搜索
bottom↓
回复: 3

串口分支 程序 如何 整合到一起?

[复制链接]

出0入0汤圆

发表于 2013-5-25 10:19:53 | 显示全部楼层 |阅读模式
功能需求
PC发送数据包格式如下:
bootcode len cmd para checksum

比如发送
40 03 02 01 BB
该命令包的命令码就是:02 ,参数:01
当FPGA 收到命名包,并解析命令包,
当命令码为:02时 , 且参数为:01;调用 音乐播放模块,并播放音乐..

再发送: 40 03 02 02 BA 是
当FPGA 收到命名包,并解析命令包,
当命令码为:02时 , 且参数为:02;停止播放音乐..

请问如何在这个基础上修改呢? 谢谢
  1. module my_uart_top(clk,rst_n,rs232_rx,rs232_tx);

  2. input clk; // 主时钟
  3. input rst_n;  //低电平复位信号
  4. input rs232_rx;   // RS232接收数据信号
  5. output rs232_tx;  //  RS232发送数据信号

  6. wire bps_start1,bps_start2;   //接收到数据后,波特率时钟启动信号置位
  7. wire clk_bps1,clk_bps2;     // clk_bps的高电平为接收或者发送数据位的中间采样点
  8. wire[7:0] rx_data;   //接收数据寄存器,保存直至下一个数据来到
  9. wire rx_int;  //接收数据中断信号,接收到数据期间始终为高电平
  10. //----------------------------------------------------
  11. speed_select      speed_rx( .clk(clk), //波特率选择模块,接收和发送模块复用,不支持全双工通信
  12.                                         .rst_n(rst_n),
  13.                                         .bps_start(bps_start1),
  14.                                         .clk_bps(clk_bps1)
  15.                                         );

  16. my_uart_rx        my_uart_rx(       .clk(clk), //接收数据模块
  17.                                         .rst_n(rst_n),
  18.                                         .rs232_rx(rs232_rx),
  19.                                         .clk_bps(clk_bps1),
  20.                                         .bps_start(bps_start1),
  21.                                         .rx_data(rx_data),
  22.                                         .rx_int(rx_int)
  23.                                         );
  24.             
  25. speed_select      speed_tx( .clk(clk), //波特率选择模块,接收和发送模块复用,不支持全双工通信
  26.                                         .rst_n(rst_n),
  27.                                         .bps_start(bps_start2),
  28.                                         .clk_bps(clk_bps2)
  29.                                         );
  30. my_uart_tx        my_uart_tx(       .clk(clk), //发送数据模块
  31.                                         .rst_n(rst_n),
  32.                                         .clk_bps(clk_bps2),
  33.                                         .rx_data(rx_data),
  34.                                         .rx_int(rx_int),
  35.                                         .rs232_tx(rs232_tx),
  36.                                         .bps_start(bps_start2)
  37.                                         );

  38. endmodule
  39. module my_uart_rx(clk,rst_n,rs232_rx,clk_bps,bps_start,rx_data,rx_int);

  40. input clk; // 主时钟
  41. input rst_n;  //低电平复位信号
  42. input rs232_rx;   // RS232接收数据信号!!
  43. input clk_bps;    // clk_bps的高电平为接收或者发送数据位的中间采样点
  44. output bps_start; //接收到数据后,波特率时钟启动信号置位
  45. output[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到
  46. output rx_int;    //接收数据中断信号,接收到数据期间始终为高电平

  47. //----------------------------------------------------------------
  48. reg rs232_rx0,rs232_rx1,rs232_rx2; //接收数据寄存器,滤波用
  49. wire neg_rs232_rx;   //表示数据线接收到下降沿

  50. always [url=home.php?mod=space&uid=72445]@[/url] (posedge clk or negedge rst_n) begin
  51.      if(!rst_n) begin
  52.             rs232_rx0 <= 1'b1;
  53.             rs232_rx1 <= 1'b1;
  54.             rs232_rx2 <= 1'b1;
  55.         end
  56.      else begin
  57.             rs232_rx0 <= rs232_rx;
  58.             rs232_rx1 <= rs232_rx0;
  59.             rs232_rx2 <= rs232_rx1;
  60.         end
  61. end

  62. assign neg_rs232_rx = rs232_rx2 & ~rs232_rx1; //接收到下降沿后neg_rs232_rx置高一个时钟周期  ??

  63. //----------------------------------------------------------------
  64. reg bps_start_r;
  65. reg[3:0]   num;   //移位次数
  66. reg rx_int;   //接收数据中断信号,接收到数据期间始终为高电平

  67. always @ (posedge clk or negedge rst_n) begin
  68.      if(!rst_n) begin
  69.             bps_start_r <= 1'b0;
  70.             rx_int <= 1'b0;
  71.         end
  72.      else if(neg_rs232_rx) begin
  73.             bps_start_r <= 1'b1; //启动接收数据
  74.            rx_int <= 1'b1;   //接收数据中断信号使能
  75.             end
  76.      else if(num==4'd10) begin                      //??
  77.             bps_start_r <= 1'b0; //数据接收完毕
  78.             rx_int <= 1'b0;      //接收数据中断信号关闭
  79.         end
  80. end
  81. assign bps_start = bps_start_r;

  82. //----------------------------------------------------------------
  83. reg[7:0] rx_data_r;  //接收数据寄存器,保存直至下一个数据来到
  84. //----------------------------------------------------------------

  85. reg[7:0]   rx_temp_data; //当前接收数据寄存器
  86. reg rx_data_shift;   //数据移位标志

  87. always @ (posedge clk or negedge rst_n) begin
  88.      if(!rst_n) begin
  89.             rx_data_shift <= 1'b0;
  90.             rx_temp_data <= 8'd0;
  91.             num <= 4'd0;
  92.             rx_data_r <= 8'd0;
  93.         end
  94.      else if(rx_int) begin    //接收数据处理
  95.         if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit数据,一个结束位      
  96.               rx_data_shift <= 1'b1;
  97.                num <= num+1'b1;
  98.                if(num<=4'd8) rx_temp_data[7] <= rs232_rx;    //锁存9bit(1bit起始位,8bit数据)   ??如何配置rs232_rx
  99.             end
  100.         else if(rx_data_shift) begin    //数据移位处理   
  101.               rx_data_shift <= 1'b0;
  102.                if(num<=4'd8) rx_temp_data <= rx_temp_data >> 1'b1;  //移位8次,第1bit起始位移除,剩下8bit正好是接收数据
  103.                else if(num==4'd10) begin
  104.                       num <= 4'd0;  //接收到STOP位后结束,num清零
  105.                       rx_data_r <= rx_temp_data;  //把数据锁存到数据寄存器rx_data中
  106.                    end
  107.             end
  108.         end
  109. end

  110. assign rx_data = rx_data_r;
  111. endmodule

  112. module my_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start);

  113. input clk;    // 主时钟
  114. input rst_n;  //低电平复位信号
  115. input clk_bps;       // clk_bps的高电平为接收或者发送数据位的中间采样点
  116. input[7:0] rx_data;  //接收数据寄存器
  117. input rx_int;     //接收数据中断信号,接收到数据期间始终为高电平,在次利用它的下降沿来启动发送数据
  118. output rs232_tx;  // RS232发送数据信号
  119. output bps_start; //接收或者要发送数据,波特率时钟启动信号置位
  120. //---------------------------------------------------------
  121. reg rx_int0,rx_int1,rx_int2;    //rx_int信号寄存器,捕捉下降沿滤波用
  122. wire neg_rx_int;  // rx_int下降沿标志位

  123. always @ (posedge clk or negedge rst_n) begin
  124.      if(!rst_n) begin
  125.             rx_int0 <= 1'b0;
  126.             rx_int1 <= 1'b0;
  127.             rx_int2 <= 1'b0;
  128.         end
  129.      else begin
  130.             rx_int0 <= rx_int;
  131.             rx_int1 <= rx_int0;
  132.             rx_int2 <= rx_int1;
  133.         end
  134. end

  135. assign neg_rx_int =  ~rx_int1 & rx_int2;  //捕捉到下降沿后,neg_rx_int拉地保持一个主时钟周期??

  136. //---------------------------------------------------------
  137. reg[7:0] tx_data; //待发送数据的寄存器
  138. //---------------------------------------------------------
  139. reg bps_start_r;
  140. reg tx_en; //发送数据使能信号,高有效
  141. reg[3:0] num;

  142. always @ (posedge clk or negedge rst_n) begin
  143.      if(!rst_n) begin
  144.             bps_start_r <= 1'b0;
  145.             tx_en <= 1'b0;
  146.             tx_data <= 8'd0;
  147.         end
  148.      else if(neg_rx_int) begin   //接收数据完毕,准备把接收到的数据发回去
  149.             bps_start_r <= 1'b1;
  150.             tx_data <= rx_data;  //把接收到的数据存入发送数据寄存器
  151.             tx_en <= 1'b1;       //进入发送数据状态中
  152.         end
  153.      else if(num==4'd10) begin   //数据发送完成,复位
  154.             bps_start_r <= 1'b0;
  155.             tx_en <= 1'b0;
  156.         end
  157. end

  158. assign bps_start = bps_start_r;

  159. //---------------------------------------------------------
  160. reg rs232_tx_r;

  161. always @ (posedge clk or negedge rst_n) begin
  162.      if(!rst_n) begin
  163.             num <= 4'd0;
  164.             rs232_tx_r <= 1'b1;
  165.         end
  166.      else if(tx_en) begin
  167.             if(clk_bps)   begin
  168.                    num <= num+1'b1;
  169.                    case (num)
  170.                       4'd0:  rs232_tx_r <= 1'b0; //发送起始位
  171.                       4'd1:  rs232_tx_r <= tx_data[0];   //发送bit0
  172.                       4'd2:  rs232_tx_r <= tx_data[1];   //发送bit1
  173.                       4'd3: rs232_tx_r <= tx_data[2]; //发送bit2
  174.                       4'd4: rs232_tx_r <= tx_data[3]; //发送bit3
  175.                       4'd5: rs232_tx_r <= tx_data[4]; //发送bit4
  176.                       4'd6: rs232_tx_r <= tx_data[5]; //发送bit5
  177.                       4'd7:  rs232_tx_r <= tx_data[6];   //发送bit6
  178.                       4'd8: rs232_tx_r <= tx_data[7]; //发送bit7
  179.                       4'd9: rs232_tx_r <= 1'b1;   //发送结束位
  180.                        default: rs232_tx_r <= 1'b1;
  181.                       endcase
  182.                end
  183.             else if(num==4'd10) num <= 4'd0;   //复位
  184.         end
  185. end

  186. assign rs232_tx = rs232_tx_r;  //如何配置rs232_tx???

  187. endmodule
  188. module speed_select(clk,rst_n,bps_start,clk_bps);

  189. input clk; // 主时钟
  190. input rst_n;  //低电平复位信号
  191. input bps_start;  //接收到数据后,波特率时钟启动信号置位
  192. output clk_bps;   // clk_bps的高电平为接收或者发送数据位的中间采样点
  193. parameter   bps9600    = 5208,//5207,    //波特率为9600bps 这里使用FPGA主频计算11.06962Mhz,5207是50MHz主频计算值
  194.                bps19200   = 2603,    //波特率为19200bps
  195.                bps38400   = 1301,    //波特率为38400bps
  196.                bps57600   = 867, //波特率为57600bps
  197.                bps115200  = 433; //波特率为115200bps

  198. parameter   bps9600_2   = 2604,//2603,
  199.                bps19200_2  = 1301,
  200.                bps38400_2  = 650,
  201.                bps57600_2  = 433,
  202.                bps115200_2 = 216;  

  203. reg[31:0] bps_para;  //分频计数最大值,以前是13位数据,但是总是有报警,所以我就给改成了32为数据,没有了多余的报警
  204. reg[31:0] bps_para_2;    //分频计数的一半
  205. /*`define   bps_para     5207   //因为这个uart_ctrl在always中会产生报警,所以使用伪指令的宏定义
  206. `define   bps_para_2   2603*/   //这个宏定义的参数在使用的时候必须给参数前加一个`例如:`bps_para_2
  207. reg[12:0] cnt;           //分频计数
  208. reg clk_bps_r;           //波特率时钟寄存器

  209. //----------------------------------------------------------
  210. reg[2:0] uart_ctrl;  // uart波特率选择寄存器,怎样配置uart_ctr??
  211. //----------------------------------------------------------

  212. always @ (posedge clk or negedge rst_n) begin
  213.      if(!rst_n) begin
  214.            uart_ctrl <= 3'd0;   //默认波特率为9600bps
  215.         end
  216.      else begin
  217.             case (uart_ctrl)  //波特率设置
  218.                3'd0:  begin
  219.                       bps_para <= bps9600;
  220.                       bps_para_2 <= bps9600_2;
  221.                       end
  222.                3'd1:  begin
  223.                       bps_para <= bps19200;
  224.                       bps_para_2 <= bps19200_2;
  225.                       end
  226.                3'd2:  begin
  227.                       bps_para <= bps38400;
  228.                       bps_para_2 <= bps38400_2;
  229.                       end
  230.                3'd3:  begin
  231.                       bps_para <= bps57600;
  232.                       bps_para_2 <= bps57600_2;
  233.                       end
  234.                3'd4:  begin
  235.                       bps_para <= bps115200;
  236.                       bps_para_2 <= bps115200_2;
  237.                       end
  238.                default: ;
  239.                endcase
  240.         end
  241. end

  242. always @ (posedge clk or negedge rst_n)
  243.      if(!rst_n) cnt <= 13'd0;
  244.      else if(cnt<bps_para && bps_start) cnt <= cnt+1'b1;  //波特率时钟计数启动
  245.      else cnt <= 13'd0;

  246. always @ (posedge clk or negedge rst_n)
  247.      if(!rst_n) clk_bps_r <= 1'b0;
  248.      else if(cnt==bps_para_2 && bps_start) clk_bps_r <= 1'b1;    // clk_bps_r高电平为接收或者发送数据位的!中间!采样点
  249.     else clk_bps_r <= 1'b0;

  250. assign clk_bps = clk_bps_r;

  251. endmodule
复制代码
播放音乐的模块如下所示:
  1. module top(sp,   
  2.         
  3.         led,
  4.           clk,
  5.         rst_n);

  6. output                sp;

  7. output  [2:0]   led;
  8. input                clk;
  9. input                rst_n; // synthesis attribute clock_buffer of rst_n is ibufg;

  10. reg     [23:0]   clk_cnt;
  11.   always [url=home.php?mod=space&uid=72445]@[/url] ( posedge clk or negedge rst_n)
  12.     if (!rst_n )
  13.         clk_cnt <= 24'd0;
  14.     else
  15.         clk_cnt <= clk_cnt + 1'b1;

  16.   wire  clk_6mhz = (clk_cnt[2]||(clk_cnt[1]&&clk_cnt[0]));                        //(clk_cnt[2]&&clk_cnt[1]);
  17.   wire  clk_4hz  = (clk_cnt[22]&&clk_cnt[23]);
  18.       
  19. wire    [3:0]   high,med,low;      




  20.   assign    led[0] = |{high,med,low};
  21.   assign    led[1] = |{high,med};
  22.   assign    led[2] = |high;
  23. song song_inst
  24.     (
  25.     .clk_6mhz   (clk_6mhz),
  26.     .clk_4hz    (clk_4hz),
  27.     .sp         ( sp    ),
  28.     .high       ( high  ),
  29.     .med        ( med   ),
  30.     .low        ( low   )
  31.     );



  32. endmodule
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-5-25 10:55:34 | 显示全部楼层
lz,分模块设计就行.一块一块的功能划分好.

出0入0汤圆

发表于 2013-5-25 13:02:36 | 显示全部楼层
一、这个串口程序没有将接受到每个字节的标志位拉出,你要找到关键地方,将这个标志位拉出来
二、你要的功能关键是要实现对数据的按协议解码,因为这都是单向传输,还是比较简单的

出0入0汤圆

 楼主| 发表于 2013-5-30 05:57:08 | 显示全部楼层
搜搜,没找到差不多的结构的例子参考

都是自收自发的多...
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表