姓名:赵宗明
学号:19021211230
【嵌牛导读】:FPGA 串口通信 PWM产生
【嵌牛鼻子】:利用电脑端通过串口通信控制FPGA产生1Hz-650KHz频率可调占空比可调的矩形波,并且FPGA将该信号所持续的时间通过串口发送至电脑端实现实时观察。
【嵌牛提问】:串行接口是连接FPGA和PC机的一种简单方式。这个项目向大家展示了如果使用电脑端来FPGA产生可调占空比可调的矩形波。
【嵌牛正文】:
1.1 概述
任务要求:利用电脑端通过串口通信控制FPGA产生1Hz-650KHz频率可调占空比可调的矩形波,并且FPGA将该信号所持续的时间通过串口发送至电脑端实现实时观察。
软件工具以及硬件平台:
开发软件利用了Xilinx官方提供的ISE 14.7和美国国家仪器(NI)公司研制Labview图形化编程环境。
硬件使用了Xilinx公司的Spartan6系列FPGA,型号为XC6SLX9,基于Verilog语言编程开发。
1.2 实现原理
该设计主要包括以下几个重要模块:波特率产生模块、数据包接收模块、数据包发送模块、PWM产生模块、模10计数器模块、模60计数器模块。
以下为该设计的实现框图:
1.2.1 波特率产生模块
波特率表示每秒钟传送的码元符号的个数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。本设计利用50M系统时钟通过计数的方式产生115200波特率模块连接至发送和接收模块。
当RX或TX模块发来波特率请求信号时,波特率产生模块开始计数,当计数值达到数据发送或接收所需数值时模块产生输出,TX或RX接收到信号时便执行发送或接收的操作。计数值的计算方式为:如果传输8位数据,实则包含起始位和停止位需传输10位数据,波特率为115200传输速度下,每位数据持续(1/115200)=8.68us,则一帧数据需要时间为86.8us,在50M系统时钟下计算得出传输每一位数据计数值为434,但是因为采样定理在计数值为217时可以得到稳定的数据,所以50M系统时钟下每计数217可触发波特率模块输出端口。
1.2.2 数据包接收模块
因为涉及多个数据的接收以及解析,本设计采用了帧头帧尾校验的方式来提取频率和占空比的有效数据,因为串口通信以字节(8位数据)收发,所以超过8位的数据需将数据拆分发送至接收端再将其合并为有效数据。上位机发送数据的格式为:
0XA5(帧头) + Freq_H(频率高八位) + Freq_L(频率低八位) + Duty_H(占空比高八位) +
Duty_L(占空比低八位) + 0XC5(帧尾)。
FPAG以同样的数据格式利用状态机的方式解析数据,并分别将频率数据和占空比数据高低位合并得到有效数据,并将有效数据传输至PWM产生模块。
1.2.3 数据包发送模块
同样,数据发送也涉及多个数据的传输,所以采用了数据包的方式利用帧头帧尾校验进行数据传输及解析。FPGA串口发送格式为:
0XA5(帧头)+ Data_Size数据大小 +
Data_H(时) + Data_M(分) + Data_S(秒)+ 0XC5(帧尾)。上位机接收端利用同样的格式利用状态机的方式解析数据,并将其实时显示。
数据收包发的前提是明白单个字节数据收发的方式,以下为单个字节发送的模型图:
通过该图可以看出,它是由1个起始位(必须是0)、8个数据位(用户数据)、1个奇偶校验位(本设计没有采用奇偶校验)和1个停止位。发送端发送数据时先发送一低电平,然后发送8比特数据,之后马上将信号拉高,从而完成一帧数据的传输。接收端接收到低电平开始计数,然后接收8比特信息位后如果检测到高电平即认为已接收完一帧数据,继续等待下一帧起始信号低电平的到来,如接受完8比特数据后没有检测到高电平即认为这不是一帧有效数据,将其丢弃,继续等待起始信号。收发可以同时进行,互不干扰。
1.2.4 PWM产生模块
利用串口接收的频率和占空比的有效数据计算出计数值,通过50M系统时钟进行软件分频产生50M以下的频率可调占空比可调的矩形波。计数值的计算公式如下:
cnt_max<= (50_000_000/Freq)-1;
cnt_Duty<= ((50_000_0/Freq)*Duty)-1;
式1可计算得出产生Freq频率的计数值,式2可计算出产生Freq频率下Duty%占空比的计数值,最后通过软件分频的方式产生矩形波,并输出至FPGA的IO引脚。
1.2.5 计数器模块
计数器模块是由三个模10计数器和两个模6计数器组成,因为该设计不需要24小时进位1天的必要,所以省去了模24计数器,其实现方法与模10 模6类似。示意图如下:
1.3 实现方法
预先方案:
利用电脑端现有的串口助手发送固定的字符至下位机,FPGA端利用if或case等语句进行固定频率和脉宽的匹配。其缺点是:无法产生用户想要任意值的PWM波,只能产生事先预定好的那几组固定频率和脉宽的PWM波,该系统的可利用性较弱,并且利用现有的串口助手,使该系统的用户交互变得不友好。
实现方案:
PWM脉宽调制在电子领域有着非常广泛的应用,本设计利用模块例化的方式,将各个模块实现拼接组成了一个完整的数据通信系统来实时控制PWM波的频率与脉宽。系统通过借助电脑端Labview制作的上位机发送包含所需频率和脉宽的数据包,其发送协议为:
0XA5(帧头) + Freq_H(频率高八位) + Freq_L(频率低八位) + Duty_H(占空比高八位) +
Duty_L(占空比低八位) + 0XC5(帧尾)。
FPGA端接收到数据包解析数据并提取有效的数据,作为PWM模块的输入,使之产生频率、脉宽可调制的矩形波并在FPGA的IO引脚输出。同时FPGA在接收到有效数据开启计数器开始计时,并将计时值实时以数据包的方式发送值电脑端,实现电脑端对该波形持续时间的实时观察。FPGA端发送数据协议为:
0XA5(帧头)+ Data_Size数据大小 +
Data_H(时) + Data_M(分) + Data_S(秒)+ 0XC5(帧尾)。上位机与下位机均利用了构造状态机的方式来解析数据。
以下为该方案实现的原理图:
程序流程图:
2.1 本设计实现过程
本设计的实现过程以串口波特率生成、串口发送、串口接收、PWM产生、模10计数器、上位机制作六部分讲述。
2.1.1 波特率的生成
之前已经简单介绍了波特率的计算方式,在50M系统时钟下计算得出传输每一位数据计数值为434,但是因为采样定理在计数值为217时可以得到稳定的数据,所以50M系统时钟下每计数217可触发波特率模块输出端口。在此详细讲述波特率的产生方式。定义波特率模块:输入包括时钟信号、复位信号、波特率控制信号,输出包括该波特率下发送或接收数据的标志位。
通过在50M时钟下计数的方式控制输出Flag产生,当计数值达到217时产生一次输出,传输置RX或TX模块控制数据的发送和接收:
下图为波特率仿真图,在bps_flag为1时,TX模块发送数据。
2.1.2 串口发送
发送一个字节数据:
串口发送数据包的基础是:串口正确发送一个字节的数据。串口发送一帧(一个字节)数据的格式为:起始位+8bit数据+停止位,所以发送一组数据实际传输的数据为10bit。串口发送模块:输入为时钟信号、复位信号、波特率标志位输入、所要发送8bit数据,输出为波特率启动信号、串口输出、串口发送数据的计数值。
如上图所示,每bit数据均在bps_flag(波特率标志位)为1 时将其放置发送端口,上图所发送的数据为:0000 0100,是按起始位+数据低位—>数据高位+停止位发送的。verilog实现方法如下:
发送数据包:
以上介绍了串口发送一个字节的方式。串口发送数据包本设计利用了索引的方式(通过tx_cnt计数值来索引所要发送的数据)依次发送:帧头+数据长度+6个有效数据+帧尾一共9个数据。具体实现方法如下:
2.1.3 串口接收
接收一帧数据:
串口接收模块较串口发送更为复杂,因为串口要想从数据包中得到有效数据就得确保接收正确的数据包并无误的将其解析。串口接收模块和串口发送模块调用同样的波特率产生模块,均在该波特率下所计算的计数值处进行数据的收发。同样,接收数据包的基础是稳定的接收一帧数据。串口接收模块输入包括时钟信号、复位信号、串口接收端口、波特率标志位,输出包括解析完的一帧数据、和波特率启动信号。
接收一帧数据的原理:FPGA的RX引脚是一位一位串行的得到信号,因为发送端发送一帧数据的格式为:起始位+8bit数据+停止位,所以接收端也应该以该格式去解析数据,观察下图
FPGA的RX端口在空闲的时候一直保持为高电平,当接收到一帧数据时先接收的为该帧的起始位即低电平而且每帧数据是以停止位结束的,所以每帧数据结束时RX端口继续保持为高电平。因为每一帧数据开始都会有一个从高电平到低电平的变化,所以我们捕捉该下降沿就会得到没一帧数据的开始。本设计捕捉下降沿的方式为:拼接RX电平状态,进行实时判断。具体实现如下:
捕捉到下降沿即捕捉了没一帧数据的开始,又因为每一帧数据的bit位是固定的,所以我们利用计数的方式就可以提取每一帧数据,可以获得每一帧数据,接下来就是数据包的获取和解析。
接收数据包:
接收数据包的难点在于在什么时候去提取有效数据,发送端发送的数据格式为:
0XA5(帧头) + Freq_H(频率高八位) + Freq_L(频率低八位) + Duty_H(占空比高八位) +
Duty_L(占空比低八位) + 0XC5(帧尾)。
经过多次的板级仿真,观察下图
在bps_start(接收数据时为1,接收完一帧数据时为0)下降沿时可以提取有效数据。所以提取了bps_start下降沿就可以利用bps_start的下降沿来提取有效数据。下降沿的提取实现如下:
成功提取下降沿,也就可以成功提取每一帧数据,接下来就是数据包的解析。
数据包的解析:
发送端发送的数据格式为:
0XA5(帧头) + Freq_H(频率高八位) + Freq_L(频率低八位) + Duty_H(占空比高八位) +
Duty_L(占空比低八位) + 0XC5(帧尾)。
接收端利用了状态机的方式来解析数据,状态机定义了:帧头,数据,帧尾三个状态,在帧头、帧尾状态都需要校验,校验通过才提取有效数据,确保了数据的正确性。具体实现如下:
通过以上设计会得到有效数据:用户输入的频率和脉宽数据,可以观察出频率和脉宽数据是高八位和低八位分开的,最后在使用时需要整合为10位数据。
2.1.4 PWM产生
在以上设计中已得到频率和脉宽的有效数据,通过以下公式
cnt_max<= (50_000_000/Freq)-1;
cnt_Duty<= ((50_000_0/Freq)*Duty)-1;
得到该频率和脉宽下的计数值,并传递至分频计数模块,具体实现如下:
以上设计初期将PWM输出接在了一个LED上,方便现象的观察。如下图在50HZ下占空比为10%和90%的现象:
2.1.5 计数器
计数器模块的输入包括时钟信号、复位信号、使能端、复位端、输出包括置位端和计数值。
计数器具体实现方法如下:
2.1.6 上位机的编写
本设计的上位机是基于Labview的图形化编程语言所设计的,严格采用了串口收发的标准。具体实现如下所示:
3.1实现结果
以下为该实验用户控制FPGA产生矩形波的实验结果,包括了多个频率和脉宽的实验结果:
以下为FPGA返回矩形波持续时间的实验结果: