在上一篇文章中,我们介绍了通过Uart实现数据的收发,在此基础上,我们进一步为小伙伴们分享如何在FPGA中通过UART配置ESP8266无线模块,最终实现无线通信系统的设计。

一、设计任务

通过手机或电脑网络调试助手给ESP8266模块发送数据,FPGA驱动ESP8266模块获取数据,并显示在底板的数码管上。

二、设计准备

硬件:小脚丫FPGA核心板、全功能学习板

软件:Quartus Prime/Lattice Diamond

三、设计结构

四、设计原理

我们所选用的ESP8266是ai-thinker公司推出的一款无线WIFI模块,可以通过配置,和单片机上的串口进行通信,利用WIFI传输数据。模块内部使用乐鑫推出的低功耗高集成度的WIFI芯片,ESP8266EX内置超低功耗32位RISK处理器,CPU最高时钟频率可达160Mhz,支持实时操作系统RTOS,和WIFI协议栈,可将高达80%的处理能力留给编程与开发。

五、设计驱动

1.ESP8266模块配置

我们将ESP8266配置成SoftAP模式,同时配置成服务器,采用下表中的指令对ESP8266模块进行配置。

序号

发送指令

作用

1

AT+CWMODE=2

设置模块WIFI模式为SoftAP模式

2

AT+CWSAP=”STEP_FPGA","12345678",5,4

设置模块的AP参数:SSID为STEP_FPGA,密码为12345678,通道号为5,加密方式为WPA_WPA2_PSK

3

AT+RST

重启生效

4

AT+CIPMUX=1

开启多连接

5

AT+CIPSERVER=1,8686

开启SERVER模式,端口设置为8686

我们发送的各种指令,实际发送的数据为字符对应的ASCII码,所以在FPGA程序实现的时候就是要取AT指令的ASCII码值,变量char表示AT指令数据,变量num表示AT指令中包含的字符数量(包含回车和换行),程序实现如下:

MAIN:begin

if(cnt_main >=4'd5) cnt_main <=4'd5;    //write mode

else cnt_main <= cnt_main +1'b1;

case(cnt_main)

4'd0:begin num<=8'd13; char<={"AT+CWMODE=2",16'h0d0a};state<=TXMD;end

4'd1:begin num<=8'd37; char<={"AT+CWSAP=",8'h22,"STEP_FPGA",8'h22,",",8'h22,"12345678",8'h22,",5,4",16'h0d0a};state <= TXMD;end

4'd2:begin num<=8'd08; char <={"AT+RST",16'h0d0a};state <= TXMD;end

4'd3:begin num<=8'd13; char<={"AT+CIPMUX=1",16'h0d0a};state<=TXMD;end

4'd4:begin num <=8'd21; char <={"AT+CIPSERVER=1,8686",16'h0d0a};state <= TXMD;end

4'd5:begin state <= REMD;end

default: state <= IDLE;

endcase

end

使用AT指令集控制ESP8266模块是UART接口,这里需要例化串口部分的UART模块进行数据传输,如下:

/uart_tx  module//

Baud #

(

.BPS_PARA               (BPS_PARA       )

)

Baud_tx

(

.clk                    (clk            ),  //系统时钟 12MHz

.rst_n                  (rst_n          ),  //系统复位,低有效

.bps_en                 (bps_en_tx      ),  //接收时钟使能

.bps_clk                (bps_clk_tx     )    //接收时钟输出

);

Uart_Tx  Uart_Tx_uut

(

.clk                    (clk            ),  //系统时钟 12MHz

.rst_n                  (rst_n          ),  //系统复位,低有效

.bps_en                 (bps_en_tx      ),  //发送时钟使能

.bps_clk                (bps_clk_tx     ),  //发送时钟输入

.tx_data_valid          (tx_data_valid  ),  //发送数据有效脉冲

.tx_data_in             (tx_data_in     ),  //要发送的数据

.uart_tx                (wifi_tx        )   //UART发送输出

);

Baud模块和Uart_Tx模块配合完成UART发送数据的功能,前级电路通过tx_data_valid和tx_data_in[7:0]端口将数据传递给Uart_Tx模块,然后Uart_Tx模块将数据按照UART总线时序发送出去。

我们使用之前设计的UART发送模块将需要传递的数据通过UART总线发送出去,每次传输8位数据;每当MAIN状态跳转到TXMD状态后,TXMD状态完成对Uart_Tx模块tx_data_valid和tx_data_in[7:0]端口的配置。

TXMD:begin

case(cnt_txmd)

3'd0:   if(bps_en_tx) cnt_txmd <= cnt_txmd;

else cnt_txmd <= cnt_txmd +1'b1;

3'd1:   begin num <= num -1'b1; cnt_txmd <= cnt_txmd +1'b1;end

3'd2:   begin tx_data_valid <=1'b1; tx_data_in <= char[(num*8)+:8]; cnt_txmd <= cnt_txmd +1'b1;end

3'd3:   begin

tx_data_valid <=1'b0;

if(num>=1'b1) cnt_txmd <=3'd0;

else cnt_txmd <= cnt_txmd +1'b1;

end

3'd4:   begin state <= DELAY; cnt_txmd <=1'b0;end

default: state <= IDLE;

endcase

end

到这里对ESP8266的配置已经完成了,假设用手机或电脑连接该网络:STEP_FPGA,同时打开网络调试助手作为TCP Client连接TCP服务器:192.168.4.1,端口号:8686,那么就可以给ESP8266发数据了,ESP8266模块接收到WIFI数据,然后以UART总线时序发送给FPGA,FPGA需要UART总线的接收模块接收数据,所以设计中还需要对UART接收功能模块的例化,程序实现如下:

uart_rx  module/

Baud #

(

.BPS_PARA               (BPS_PARA       )

) Baud_rx

(

.clk                    (clk            ),  //系统时钟 12MHz

.rst_n                  (rst_n          ),  //系统复位,低有效

.bps_en                 (bps_en_rx      ),  //接收时钟使能

.bps_clk                (bps_clk_rx     )    //接收时钟输出

);

Uart_Rx  Uart_Rx_uut

(

.clk                    (clk            ),  //系统时钟 12MHz

.rst_n                  (rst_n          ),  //系统复位,低有效

.bps_en                 (bps_en_rx      ),  //接收时钟使能

.bps_clk                (bps_clk_rx     ),  //接收时钟输入

.uart_rx                (wifi_rx        ),  //UART接收输入

.rx_data_valid          (rx_data_valid  ),  //接收数据有效脉冲

.rx_data_out            (rx_data_out    )    //接收到的数据

);

Baud模块和Uart_Rx模块配合完成UART接收数据的功能,Uart_Rx模块按照UART总线时序接收数据,将接收到的数据通过rx_data_valid和rx_data_out[7:0]端口输出给后级电路。

当我们连接服务器,使用网络调试助手发送数据<123>,ESP8266模块接收WIFI信号,并通过UART返回数据,如上图所示,想要将123显示在数码管上,需要对UART接收的数据进行解析,包括两个方面,

  • 接收到的数据中部分不能显示,需要排除,只显示数据<123>

  • 数据以ASCII码形式接收,需要解析成字符数据

UART数据中被舍弃的数据,我们可以简单的使用加号和冒号<:>来控制显示的部分,例如显示冒号以后且加号以前的数据,程序实现如下

//解析UART通信,控制只显示有效数据部分

always@(posedge clk or negedge rst_n)begin

if(!rst_n) display_en <=1'b0;

else if((state == REMD)&&(rx_data_valid))

case(rx_data_out)

":": display_en <=1'b1;

"+": display_en <=1'b0;

default: display_en <= display_en;

endcase

else display_en <= display_en;

end

ASCII码数据译码成对应的字符数据,程序实现如下:

//对接收的ASCII码值解码,只对应0~9的数字

always@(posedge clk or negedge rst_n)begin

if(!rst_n) seg_data_r <=4'ha;

else if((state == REMD)&&(rx_data_valid))

case(rx_data_out)

"0": seg_data_r <=4'd0;

"1": seg_data_r <=4'd1;

"2": seg_data_r <=4'd2;

"3": seg_data_r <=4'd3;

"4": seg_data_r <=4'd4;

"5": seg_data_r <=4'd5;

"6": seg_data_r <=4'd6;

"7": seg_data_r <=4'd7;

"8": seg_data_r <=4'd8;

"9": seg_data_r <=4'd9;

default: seg_data_r <= seg_data_r;

endcase

else seg_data_r <= seg_data_r;

end

最后将显示部分的字符数据放到移位寄存器中缓存,程序实现如下:

reg             [35:0]   seg_data;

//移位寄存器,UART接收数据的buffer

always@(posedge clk or negedge rst_n)begin

if(!rst_n)begin

seg_data <=36'haaaa_aaaa_a;     // 本实验a对应数码管字库为不显示

end else if(!display_en_r2)begin    //

seg_data <=36'haaaa_aaaa_a;

end else if(rx_data_valid_r1)begin

seg_data <={seg_data[31:0],seg_data_r};

end else seg_data <= seg_data;

end

例化扫描式数码管驱动模块,将移位寄存器缓存的数据显示在数码管上,程序实现如下:

Segment_scan  Segment_scan_uut

(

.clk                    (clk                ),       //系统时钟 12MHz

.rst_n                  (rst_n              ),       //系统复位低有效

.dat_1                  (seg_data[31:28]     ),      //SEG1 显示的数据输入

.dat_2                  (seg_data[27:24]     ),      //SEG2 显示的数据输入

.dat_3                  (seg_data[23:20]     ),      //SEG3 显示的数据输入

.dat_4                  (seg_data[19:16]     ),      //SEG4 显示的数据输入

.dat_5                  (seg_data[15:12]     ),      //SEG5 显示的数据输入

.dat_6                  (seg_data[11:8]     ),      //SEG6 显示的数据输入

.dat_7                  (seg_data[7:4]     ),      //SEG7 显示的数据输入

.dat_8                  (seg_data[3:0]     ),      //SEG8 显示的数据输入

.dat_en                 (8'b1111_1111        ),      //数码管数据位显示使能

.dot_en                 (8'b0000_0000        ),      //数码管小数点位显示使能

.seg_rck                (seg_rck            ),       //74HC595的RCK管脚

.seg_sck                (seg_sck            ),       //74HC595的SCK管脚

.seg_din                (seg_din            )        //74HC595的SER管脚

);

以上是通过小脚丫FPGA核心板所实现的ESP8266实例,想要了解详细资料FPGA实现过程,欢迎点击文章下方的蓝色“”~


赶快扫码关注我吧?~~小编会定期分享基于FPGA的设计贴及行业信息,千万不要错过哦!

at指令 fpga_FPGA毕设系列 | 无线通信相关推荐

  1. 博图sodt定时器的用法_西门子plc定时器指令 西门子S7-1200系列PLC定时器指令

    定时器指令是在PLC程序设计中非常常见的一种指令,S7-1200系列PLC的定时器的指令格式及使用方式都不同于S7-200系列PLC. S7-1200系列PLC的采用的是IEC标准的定时器指令,用户程 ...

  2. Matlab毕设系列--说明

    1 说明 自Matlab图像处理.路径规划.预测模型.优化求解.语音处理等专栏建立及更新以后,同学们选题的困惑与空身乏力的无奈,博主深感不安啊,为了能够不断地为大家解决毕设问题,以下将推出毕设专栏,欢 ...

  3. 毕设系列二之垃圾分类小程序

    垃圾分类小程序 1. 结构 微信小程序 图像识别模型 API 2. 微信小程序设计 对于小程序的界面设计,我设计的比较简单.如图: 当然.界面完全可以依照自己的想法进行设计.对ui设计我考虑的不多.主 ...

  4. 大数据毕设系列项目说明 【源码+论文】

    文章目录 1 项目下载步骤 2 项目包含内容 3 样例展示 4 代码样例 1 项目下载步骤 Hi,大家好,这里是学长开发的大数据可视化项目系列,大家可以用于自己的课设或毕设,可以灵活耦合任意数据,为自 ...

  5. Github常用搜索指令(毕设资料搜索必备)

    1.language:限制语言 2.in:根据某个关键词来进行检索 关键词 name 项目名称 description 项目描述 readme 项目帮助文档 语法:需要检索的内容 in:name或de ...

  6. [毕设系列] 一、张正友相机标定

    张正友相机标定 预备知识 0.1 刚体.仿射.线性.旋转变换 0.2 什么是标定? 0.3 为什么要进行标定? 0.4 什么是畸变? 一.张正友标定法 1.1 简介 1.2 流程 1.3 畸变公式 二 ...

  7. 毕设系列教程-基于Blinker和小爱同学的智能家居设计与现实-系统介绍

    前言 本系列教程只是针对刚入门的小白,大佬不喜勿喷,为了帮助一些小白毕业生顺利毕业,帮助电子爱好者制作自己的智能家居DIY,尽量减少对专业知识的描述,如果有毕业设计要求的同学当然也可以提供毕业论文的参 ...

  8. 毕设系列之Libx264实时视频流(YUV 420P转H264视频编码篇)

    #PS:要转载请注明出处,本人版权所有 #PS:这个只是 < 我自己 >理解,如果和你的 #原则相冲突,请谅解,勿喷 开发环境:Ubuntu 16.04 LTS 本文的技术实现部分参考雷博 ...

  9. 毕设系列之 --- 算法教学 : 决策树算法

    决策树理解案例 我们在买苹果的时候可以通过苹果的颜色.硬度来判断它的好坏,再决定是否买这个苹果.那么我们也许可以基于之前买苹果的经验做出这样一个分析: 某人不太会挑苹果,所以纯粹是随机写的几条数据,假 ...

最新文章

  1. 为什么ConcurrentHashMap的读操作不需要加锁?
  2. java基本类_Java基本类型
  3. micropython oled中文_micropython esp8266+ssd1306(OLED) 显示中文(示例)
  4. undefined reference to '__gxx_personality_v0'
  5. 左值、右值、左值引用、右值引用
  6. 前端学习(1980)vue之电商管理系统电商系统之实现文本框和按钮的切换
  7. superset0.34源码级别汉化
  8. vue :style 设置背景图片 backgroundImage
  9. Tomcate服务器的基本知识概括总结及安装目录概括
  10. 清除Linux和window等系统的DNS缓存的命令
  11. 在Ubuntu上面使用华为EC3372
  12. 二叉树查找后继节点(即中序遍历情况下的这个节点的下一个) Python实现
  13. 968. 监控二叉树(每日一难phase2--day17)
  14. 百万调音师—AU效果器基本应用
  15. 常用Intent合集 Android
  16. 描写计算机教室的词语,关于描写教室的词语
  17. 胡凡算法之——快速幂
  18. 阿里云买的域名备案成功了 后续怎么建站 ?
  19. oracle 倒库详细步骤,超详细的倒车入库步骤
  20. unable to start ssh-agent service, error :1058 问题的解决方法

热门文章

  1. python Pil byteio转换
  2. ubuntu 鼠标变成黑色的叉并且图标消失
  3. pytorch 索引
  4. tensorflow学习笔记(三十二):conv2d_transpose (解卷积)
  5. numpy基本用法多维数组
  6. JTable表头也就是标题行给隐藏
  7. 王者荣耀服务器维护1月9号,王者荣耀1月9日维护到几点 王者荣耀1月9日几点能上游戏?...
  8. 计算机网络中st是什么,计算机组成中ST 是指什么
  9. 电脑有回声_游戏东西丨兽人游戏Echo回声电脑手机汉化版
  10. BigDecimal 比较大小需要注意的事项