完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近在做低频数字式相位测量仪,很多人都是卡在stm32和fpga串口通信上,还有相位差的测量,下面讲讲通信的解决办法!fpga部分用了某位大神的串口通信模块进行参考(module tx_module,module tx_control_module,module tx_bps_module,module uartsent),然后自己写了stm32f1精英版的串口接收程序。
*************************************************************************************************************************************************特别注意Do_sig 和start_sig,Done_sig。Do_sig是 发送信号,每当监测到时钟上升沿时开始发送数据;start_sig是开始进行测量信号,由stm32f1引脚提供(低电平有效)无此信号fpga不进行测量;Done_sig是计数完成信号,不需要也没事。 ************************************************************************************************************************************************* 1、fpga部分 module uartsent ( input CLK_25M, //PLL CLK 25M input RSTn, //系统复位低电平有效 SYS Reset input Do_sig, //开始发送信号 input [31:0] fxCnt, //输入信号计数寄存器 input [31:0] fBaseCnt, input [31:0] DutyCnt, input [31:0] o_data, //相位差测量数据 output TX_Pin_Out // 连接STM32串口; ); wire isDone; //tx_module发出了信号 reg rEN = 1'b0; //发送使能 reg [7:0] Data[15:0]; //发送数据缓冲区 reg [5:0] i=6'd0; //Send state声明 reg [7:0] data; //发送给txmodule的数据 tx_module U0_tx ( .CLK_25M (CLK_25M ), .RSTn (RSTn ), .TX_Data (data ), .TX_En_Sig (rEN ), .TX_Done_Sig (isDone ), .TX_Pin_Out (TX_Pin_Out ) ); // 调用txmodule发送测量数据 always@(posedge CLK_25M or posedge Do_sig) //只要25M时钟或者开始发送信号上升沿时 begin if(Do_sig) //Do_sig等于1时开始执行 begin //将数据全部转移数据到临时表 Data[15] <= DutyCnt [31:24]; //转移数据到临时表 Data[14] <= DutyCnt [23:16]; //Data[15:12] 占空比数据 Data[13] <= DutyCnt [15:8 ]; Data[12] <= DutyCnt [7 :0 ]; Data[11] <= o_data [31:24]; //Data[11: 8]delay data时间间隔数据 Data[10] <= o_data [23:16]; Data[9] <= o_data [15:8 ]; Data[8] <= o_data [7 :0 ]; Data[7] <= fxCnt [31:24]; //Data[7:4] Data[6] <= fxCnt [23:16]; Data[5] <= fxCnt [15:8 ]; Data[4] <= fxCnt [7 :0 ]; Data[3] <= fBaseCnt [31:24]; //Data[7:4] Data[2] <= fBaseCnt [23:16]; Data[1] <= fBaseCnt [15:8 ]; Data[0] <= fBaseCnt [7 :0 ]; //8位2进制数 i <= 1'b1; //状态更改发送状态 ,转移完,i=1 end else begin if(rEN == 1'b0 && i>= 1'b1) //当不使能时且i=1时 即将数据全部转移数据到临时表完成后 begin case(i)//:txmodule启动信号 状态是发送状态 6'd 1 : begin data <= Data[15]; rEN <= 1'b1; i <= i +1'b1; end // 6'd 2 : begin data <= Data[14]; rEN <= 1'b1; i <= i +1'b1; end 6'd 3 : begin data <= Data[13]; rEN <= 1'b1; i <= i +1'b1; end 6'd 4 : begin data <= Data[12]; rEN <= 1'b1; i <= i +1'b1; end 6'd 5 : begin data <= Data[11]; rEN <= 1'b1; i <= i +1'b1; end 6'd 6 : begin data <= Data[10]; rEN <= 1'b1; i <= i +1'b1; end 6'd 7 : begin data <= Data[9 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd 8 : begin data <= Data[8 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd 9 : begin data <= Data[7 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd10 : begin data <= Data[6 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd11 : begin data <= Data[5 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd12 : begin data <= Data[4 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd13 : begin data <= Data[3 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd14 : begin data <= Data[2 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd15 : begin data <= Data[1 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd16 : begin data <= Data[0 ]; rEN <= 1'b1; i <= i +1'b1; end 6'd17 : begin data <= 8'hf ; rEN <= 1'b1; i <= i +1'b1; end //发送模式验证码,等于测试freq,MCU(stm32) 6'd18 : begin data <= 8'hd ; rEN <= 1'b1; i <= i +1'b1; end 6'd19 : begin data <= 8'ha ; rEN <= 1'b1; i <= i +1'b1; end 6'd20 : i <= 1'b0; //发送完i=0 endcase end if(isDone == 1'b1) begin rEN <=1'b0; //:确定txmodule启动信号只有一个clk脉冲 end end end endmodule //Found from the internet, verify OK module tx_module ( CLK_25M, RSTn, TX_Data, TX_En_Sig, TX_Done_Sig, TX_Pin_Out ); input CLK_25M; input RSTn; input [7:0]TX_Data;//来自top_uartsent input TX_En_Sig; output TX_Done_Sig; output TX_Pin_Out; /********************************/ wire BPS_CLK; tx_bps_module U1 ( .CLK_25M( CLK_25M ), .RSTn( RSTn ), .Count_Sig( TX_En_Sig ), // input - from U2 .BPS_CLK( BPS_CLK ) // output - to U2 ); /*********************************/ tx_control_module U2 ( .CLK_25M( CLK_25M ), .RSTn( RSTn ), .TX_En_Sig( TX_En_Sig ), // input - from top .TX_Data( TX_Data ), // input - from top .BPS_CLK( BPS_CLK ), // input - from U2 .TX_Done_Sig( TX_Done_Sig ), // output - to top .TX_Pin_Out( TX_Pin_Out ) // output - to top ); /***********************************/ endmodule //Found from the internet, verify OK module tx_control_module ( CLK_25M, RSTn, TX_En_Sig, //发送使能信号 TX_Data, BPS_CLK, TX_Done_Sig, TX_Pin_Out ); input CLK_25M; input RSTn; input TX_En_Sig; //发送使能信号 input [7:0]TX_Data; input BPS_CLK; //时钟 bps-每秒传送位数(bits per second);字节/秒(bytes per second) output TX_Done_Sig; //发送完成信号 output TX_Pin_Out; //发送引脚 /********************************************************/ reg [3:0]i; reg rTX; reg isDone; always @ ( posedge CLK_25M or negedge RSTn ) begin if( !RSTn ) begin i <= 4'd0; //0000 rTX <= 1'b1; //1 isDone <= 1'b0;//0 end else if( TX_En_Sig ) //发送使能信号 case ( i ) //四位二进制数 4'd0 : if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b0; end 4'd1, 4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 : if( BPS_CLK ) begin i <= i + 1'b1; rTX <= TX_Data[ i - 1 ]; end 4'd9 : if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end 4'd10 : if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end 4'd11 : if( BPS_CLK ) begin i <= i + 1'b1; isDone <= 1'b1; end 4'd12 : begin i <= 1'b0; isDone <= 1'b0; end endcase end /********************************************************/ assign TX_Pin_Out = rTX; assign TX_Done_Sig = isDone; /*********************************************************/ endmodule |
|
|
|
//(国赛fpga)
//时钟 bps-每秒传送位数(bits per second);字节/秒(bytes per second) //Found from the internet, verify OK module tx_bps_module ( CLK_25M, RSTn, Count_Sig, BPS_CLK ); input CLK_25M; input RSTn; input Count_Sig; output BPS_CLK; /*************Count_BPS = CLK / wish bps************* */ reg [11:0]Count_BPS; //12位 always @ ( posedge CLK_25M or negedge RSTn )//当25M上升沿到来或者复位 begin if( !RSTn ) Count_BPS <= 12'd0; else if( Count_BPS == 12'd2604 ) //25M/2604=9600波特率 //测试暂用 // else if( Count_BPS == 12'd80 ) //25M/2604=9600波特率 Count_BPS <= 12'd0; else if( Count_Sig) // Count_BPS <= 12'd2604 Count_BPS <= Count_BPS + 1'b1; else Count_BPS <= 12'd0; end /********************************/ assign BPS_CLK = ( Count_BPS == 12'd1302 ) ? 1'b1 : 1'b0; /*********************************/ endmodule 顶层文件 //频率测量模块 实例化 mesureFreq U1_mesure_things ( .CLK_25M (CLK_25M ), //系统时钟,默认25M .fxA (fxA ), //被测信号--- 来自顶层 .fxB (fxB ), //基准信号--- 来自顶层 .CLK_200M (CLK_200M ), //200M时钟 .Start_sig (Start_sig ), //测量开始信号 .fxCnt (fxCnt ), //被测信号计数个数 .fBaseCnt (fBaseCnt ), //基准信号计数个数 .DutyCnt (DutyCnt ), //占空比计数个数 .DelayCnt (DelayCnt ), //时间间隔计数个数 .Done_sig (Cnt_done_sig), //计数完成信号 .LED (LED ) //LED 到顶层 ); 2、STM32部分 串口接收 //串口1中断处理函数 void USART1_IRQHandler(void) { unsigned char res; if(USART1->SR&(1<<5))//接收到数据 { res=USART1->DR; if((USART_RX_STA&0x80)==0)//接收未完成 { if(USART_RX_STA&0x40)//接收到了0x0d { if(res!=0x0a) USART_RX_STA=0;//接收错误,重新开始 else { USART_RX_STA|=0x80; //接收完成了 // showhz32str(0,600,"接收完成",BLACK,GREEN); // printf("%srn",USART_RX_BUF); } } else //还没收到0X0D { if(res==0x0d) { USART_RX_BUF[USART_RX_STA]=0; USART_RX_STA|=0x40; } else { USART_RX_BUF[USART_RX_STA]=res; USART_RX_STA++; if(USART_RX_STA>63) { USART_RX_STA=0;//接收数据错误,重新开始接收 // showhz32str(0,600,"接收数据错误",BLACK,GREEN); } } } } } } 下图此代码写在main()函数里面 usart.h头文件里面包含 extern char USART_RX_BUF[64]; //接收缓冲,最大64个字节. extern unsigned char USART_RX_STA; //接收状态标记 bit7,接收完成标志 bit6,接收到0x0d bit5~0,接收到的有效字节数目 //进行串口通信接收数据 if(USART_RX_STA & 0x80) //USART_RX_STA=0x80;//接收状态标记 bit7,接收完成标志 bit6,接收到0x0d bit5~0,接收到的有效字节数目 { count=0; /****************************************************************************************************/ x=(USART_RX_BUF[8]<<24)+(USART_RX_BUF[9]<<16)+(USART_RX_BUF[10]<<8)+USART_RX_BUF[11]; y=(USART_RX_BUF[12]<<24)+(USART_RX_BUF[13]<<16)+(USART_RX_BUF[14]<<8)+USART_RX_BUF[15]; duty=(USART_RX_BUF[0]<<24)+(USART_RX_BUF[1]<<16)+(USART_RX_BUF[2]<<8)+USART_RX_BUF[3]; /*相位差计数时间*/ delay=(USART_RX_BUF[4]<<24)+(USART_RX_BUF[5]<<16)+(USART_RX_BUF[6]<<8)+USART_RX_BUF[7]; /*****************************************************************************************************/ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1874 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1658 浏览 1 评论
1143 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
759 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1720 浏览 2 评论
1963浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
789浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
611浏览 3评论
628浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
590浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-11 16:25 , Processed in 1.038921 second(s), Total 79, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号