11169|3

5979

帖子

8

TA的资源

版主

楼主
 

Spartan-6 FPGA 嵌入式套件试用(五)----- 串口接收 [复制链接]

接着上一篇,这篇主要来学习一下串口的接收,设计的思路为:

1.       PC端用串口助手发送数据;

2.       Xilinx fpga同过串口接收数据;

3.       同过接收到的数据来控制板子上的LED的状态,数据和LED的对应关系如下:

 

 

对应的Bit1 时,LED亮;为0时,LED灭。

 

串口异步接收部分的框图如下:

 

具体实现如下:

// RS-232 RX module

module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle);

input clk, RxD;

output RxD_data_ready; 

output [7:0] RxD_data;

 

parameter ClkFrequency = 27000000;    // Spartan-6板子上的27MHz时钟

parameter Baud = 115200;             //波特率设置115200

 

 

output RxD_endofpacket;  //一个时钟宽度,如果没有其他数据需要接收,RxD_idle等于1

output RxD_idle;         //没有新数据接收的指示

 

 

//产生波特率

parameter Baud8 = Baud*8;

parameter Baud8GeneratorAccWidth = 16;

wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7);

reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;

 

always @(posedge clk)

     Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc;

 

wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth];

 

//同步RxD信号

reg [1:0] RxD_sync_inv;

always @(posedge clk)

             if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD};

 

reg [1:0] RxD_cnt_inv;

reg RxD_bit_inv;

 

//对开始信号Start进行检测

always @(posedge clk)

if(Baud8Tick)

begin

if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1;

else

if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1;

 

if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0;

else

if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1;

end

 

reg [3:0] state;

reg [3:0] bit_spacing;

 

wire next_bit = (bit_spacing==4'd10);

 

always @(posedge clk)

if(state==0)

bit_spacing <= 4'b0000;

else

if(Baud8Tick)

bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000};

 

//一旦检测到"开始位",使用如下的状态机可以检测出接收到每一位数据

always @(posedge clk)

if(Baud8Tick)

case(state)

4'b0000: if(RxD_bit_inv) state <= 4'b1000;  // start bit found?

4'b1000: if(next_bit) state <= 4'b1001;  // bit 0

4'b1001: if(next_bit) state <= 4'b1010;  // bit 1

4'b1010: if(next_bit) state <= 4'b1011;  // bit 2

4'b1011: if(next_bit) state <= 4'b1100;  // bit 3

4'b1100: if(next_bit) state <= 4'b1101;  // bit 4

4'b1101: if(next_bit) state <= 4'b1110;  // bit 5

4'b1110: if(next_bit) state <= 4'b1111;  // bit 6

4'b1111: if(next_bit) state <= 4'b0001;  // bit 7

4'b0001: if(next_bit) state <= 4'b0000;  // stop bit

default: state <= 4'b0000;

endcase

 

//使用一个移位寄存器来存储接收到的数据

reg [7:0] RxD_data;

always @(posedge clk)

if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]};

 

reg RxD_data_ready, RxD_data_error;

always @(posedge clk)

begin

RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv); 

RxD_data_error <= (Baud8Tick && next_bit && state==4'b0001 &&  RxD_bit_inv);

end

 

reg [4:0] gap_count;

always @(posedge clk)

      if (state!=0) gap_count<=5'h00;

           else if (Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01;

 

assign RxD_idle = gap_count[4];

 

reg RxD_endofpacket;

 

always @(posedge clk)

        RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F);

 

endmodule

 

测试代码如下:

 

wire RxD_data_ready;

wire [7:0]RxD_data;

wire RxD_endofpacket;

wire RxD_idle;

 

reg [7:0]RxD_data_tmp;

 

//保存接收到的串口数据

always @(posedge clk)

begin

if(RxD_data_ready)

           RxD_data_tmp <= RxD_data;

else

           RxD_data_tmp <= RxD_data_tmp;

end

 

//把串口接收到的数据和LED绑定,通过串口数据控制LED的状态

assign led0 = RxD_data_tmp[0];   // bit0

assign led1 = RxD_data_tmp[1];   //bit1

assign led2 = RxD_data_tmp[2];   //bit2

assign led3 = RxD_data_tmp[3];   //bit3          

 

//例化串口接收模块

async_receiver async_receiver_inst(

                                                                   .clk(clk),

                                                                   .RxD(uart_tx),

                                                                   .RxD_data_ready (RxD_data_ready),

                                                                   .RxD_data (RxD_data),

                                                                   .RxD_endofpacket (RxD_endofpacket),

                                                                   .RxD_idle(RxD_idle));

 

   

测试结果:

有空拍几张效果图上来,哈哈

此帖出自FPGA/CPLD论坛

最新回复

谢谢分享了  详情 回复 发表于 2014-5-20 13:19
点赞 关注(1)
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 

回复
举报

978

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
沙发,顶空灵哥
此帖出自FPGA/CPLD论坛
 
 

回复

2万

帖子

71

TA的资源

管理员

板凳
 

嘿嘿 辛苦了呢

 

文字 字体 颜色 很搭

此帖出自FPGA/CPLD论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 
谢谢分享了
此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表