FPGA——ESP8266发送0、1实验

这篇具有很好参考价值的文章主要介绍了FPGA——ESP8266发送0、1实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、实验内容。

定义两个串口,分别接收两个按键输入0、1,或接收PC发送的AT指令,两个输入,通过按键切换输入到esp8266,从而完成WiFi连接、TCP服务器连接、以及数据0、1发送。

二、系统架构。

FPGA——ESP8266发送0、1实验

三、RTL视图

FPGA——ESP8266发送0、1实验

四、项目代码。

uart_tx.v串口发送模块

// uart_tx.v
`include "param.v"
module uart_tx(
	input wire 			clk	,
	input wire 			rst_n	,
	input wire 			tx_req,//发送请求
	input wire [7:0] 	tx_din,//并行数据输入
	
	output reg        tx_dout,//串行数据输出
	output wire       dout_vld//并转串完成标志
	

);
reg [12:0] cnt_bps		;//波特率计数寄存器	
wire       add_cnt_bps	;//波特率计数开始
wire       end_cnt_bps  ;//波特率计数结束

reg [3:0]  cnt_bit      ;//比特计数寄存器
wire       add_cnt_bit  ;//比特计数开始
wire       end_cnt_bit  ;//比特计数结束

reg        tx_flag      ;//发送标志

reg [9:0]  tx_data      ;

//波特率计数器设计
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_bps <= 13'd0;
	end 
	else if(add_cnt_bps)begin
		if(end_cnt_bps)begin
			cnt_bps <= 13'd0;
		end 
		else begin
			cnt_bps <= cnt_bps + 1'd1;
		end 
	end 
	else begin
		cnt_bps <= cnt_bps;
	end 
end 

assign add_cnt_bps = tx_flag;
assign end_cnt_bps = add_cnt_bps && cnt_bps == (`SYS_FRQ/`BAUD_MAX) - 1'd1;

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_bit <= 4'd0;
	end 
	else if(add_cnt_bit)begin
		if(end_cnt_bit)begin
			cnt_bit <= 4'd0;
		end 
		else begin
			cnt_bit <= cnt_bit + 1'd1;
		end 
	end 
	else begin
		cnt_bit <= cnt_bit;
	end 
end 

assign add_cnt_bit = end_cnt_bps;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 9;

//发送标志tx_flag
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		tx_flag <= 1'b0;
	end 
	else if(tx_req)begin
		tx_flag <= 1'b1;
	end 
	else if(end_cnt_bit)begin
		tx_flag <= 1'b0;
	end 
	else begin
		tx_flag <= tx_flag;
	end 
end 


//数据缓存,tx_data
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		tx_data <= 10'b0;
	end 
	else if(tx_req)begin
		tx_data <= {1'b1, tx_din, 1'b0};
	end
	else begin
		tx_data <= tx_data;
	end 
end 

//tx_dout数据串行输出
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		tx_dout <= 1'b1;
	end 
	else if(tx_flag && cnt_bps == 1)begin
		tx_dout <= tx_data[cnt_bit];
	end 
	else begin
		tx_dout <= tx_dout;
	end 
end 

//dout_vld约束
assign dout_vld = ~tx_flag;

endmodule 

uart_rx.v串口接收模块

`include "param.v"
module uart_rx(
	input wire 			clk		,
	input wire 			rst_n		,
	input wire 			rx_din	,//串行数据输入
	
	output wire [7:0] rx_dout	,//并行数据输出
	output reg 		   dout_vld//串转并完成标志
);

reg [12:0] cnt_bps		;//波特率计数寄存器
wire       add_cnt_bps	;//波特率计数开始
wire       end_cnt_bps	;//波特率计数结束

reg [3:0]  cnt_bit      ;//比特计数寄存器
wire       add_cnt_bit  ;//比特计数开始
wire       end_cnt_bit  ;//比特计数结束

reg 			rx_din_r0;//同步
reg 			rx_din_r1;//打拍
wire     	nedge		;//下降沿

reg      	rx_flag;//接受标志

reg [9:0] 	rx_data;//寄存数据包


//波特率计数器设计
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_bps <= 13'd0;
	end 
	else if(add_cnt_bps)begin
		if(end_cnt_bps)begin
			cnt_bps <= 13'd0;
		end 
		else begin
			cnt_bps <= cnt_bps + 1'd1;
		end 
	end 
	else begin
		cnt_bps <= cnt_bps;
	end 
end 

assign add_cnt_bps = rx_flag;
assign end_cnt_bps = add_cnt_bps && cnt_bps == (`SYS_FRQ / `BAUD_MAX) - 1'd1;

//比特计数器设计
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_bit <= 4'd0;
	end 
	else if(add_cnt_bit)begin
		if(end_cnt_bit)begin
			cnt_bit <= 4'd0;
		end
		else begin
			cnt_bit <= cnt_bit + 1'd1;
		end 
	end 
	else begin
		cnt_bit <= cnt_bit;
	end 
end 

assign add_cnt_bit = end_cnt_bps;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 4'd10 - 1'd1;

//起始位位置检测
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		rx_din_r0 <= 1'b1;
		rx_din_r1 <= 1'b1;
	end 
	else begin
		rx_din_r0 <= rx_din;
		rx_din_r1 <= rx_din_r0;
	end 
end 

assign nedge = ~rx_din_r0 && rx_din_r1;

//接受标志rx_flag约束
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		rx_flag <= 1'b0;
	end 
	else if(nedge)begin
		rx_flag <= 1'b1;
	end 
	else if(end_cnt_bit)begin
		rx_flag <= 1'b0;
	end
	else begin
		rx_flag <= rx_flag;
	end 

end 

//缓存接受到的数据
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		rx_data <= 10'b0;
	end 
	else if(rx_flag && cnt_bps == (`SYS_FRQ/`BAUD_MAX) >> 1)begin
		rx_data[cnt_bit] = rx_din_r0;
	end 
	else begin
		rx_data <= rx_data;
	end 

end 

assign rx_dout = rx_data[8:1];

//串转并完成标志dout_vld约束
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		dout_vld <= 1'b0;
	end 
	else if(end_cnt_bit)begin
		dout_vld <= 1'b1;
	end 
	else begin
		dout_vld <= 1'b0;
	end 
end 

endmodule 

param.v波特率常量定义

`define SYS_FRQ 50_000_000
`define BAUD_115200

`ifdef BAUD_9600
	`define BAUD_MAX 9600
`elsif BAUD_19200
	`define BAUD_MAX 19200
`elsif BAUD_38400
	`define BAUD_MAX 38400
`elsif BAUD_57600
	`define BAUD_MAX 57600
`elsif BAUD_115200
	`define BAUD_MAX 115200
`else
	`define BAUD_MAX 9600
`endif
	

key_debounce.v按键消抖模块

module key_debounce(
    input clk,
    input rst_n,
    input key,

    output reg temp
);

parameter DELAY = 20'd1000_000;


reg [19:0] delay_cnt;
reg key_reg;//保存上一时刻的键值
reg flag,key_value;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        delay_cnt <= 20'd0;
        key_reg   <= 1'b1;
    end
    else begin
        key_reg <= key;
        if(key_reg != key)begin
            delay_cnt <= DELAY;
        end
        else begin
            if(delay_cnt > 20'd0)begin
                delay_cnt <= delay_cnt - 1'd1;
            end
            else begin
                delay_cnt <= 20'd0;
            end
        end
    end
end

always @(posedge clk or negedge rst_n) begin
   if(!rst_n)begin
    flag <= 1'b0;
    key_value <= 1'b1;
   end
   else if(delay_cnt == 1'd1)begin
    flag      <= 1'b1;
    key_value <= key;
   end
   else begin
    flag <= 1'b0;
    key_value <= key_value;
   end
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)begin
		temp <= 1'b0;
	end
	else begin
		if(flag&&~key_value)begin
			temp <= 1'b1;
		end
		else
			temp <= 1'b0;
	end
end	
endmodule 

date_send.v数据发送模块

`include "param.v"
module date_send(
	input wire 			clk	,
	input wire 			rst_n	,
	input wire	[1:0]	key,
	output reg          tx_dout//串行数据输出
);
reg 		tx_req;//发送请求
reg [7:0] 	tx_din;//并行数据输入
reg [12:0] cnt_bps		;//波特率计数寄存器	
wire       add_cnt_bps	;//波特率计数开始
wire       end_cnt_bps  ;//波特率计数结束

reg [3:0]  cnt_bit      ;//比特计数寄存器
wire       add_cnt_bit  ;//比特计数开始
wire       end_cnt_bit  ;//比特计数结束

reg        tx_flag      ;//发送标志

reg [9:0]  tx_data      ;

always @(posedge clk or negedge rst_n)begin 
	if(!rst_n)begin
		tx_req <= 0;
		tx_din <= 0;
	end 
	else if(key[0]&&!key[1])begin 
		tx_req <= 1;
		tx_din <= 8'd48;
	end 
	else if(key[1]&&!key[0])begin 
		tx_req <= 1;
		tx_din <= 8'd49;
	end 
	else begin 
		tx_req <= 0;
	end 
end

//波特率计数器设计
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_bps <= 13'd0;
	end 
	else if(add_cnt_bps)begin
		if(end_cnt_bps)begin
			cnt_bps <= 13'd0;
		end 
		else begin
			cnt_bps <= cnt_bps + 1'd1;
		end 
	end 
	else begin
		cnt_bps <= cnt_bps;
	end 
end 

assign add_cnt_bps = tx_flag;
assign end_cnt_bps = add_cnt_bps && cnt_bps == (`SYS_FRQ/`BAUD_MAX) - 1'd1;

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_bit <= 4'd0;
	end 
	else if(add_cnt_bit)begin
		if(end_cnt_bit)begin
			cnt_bit <= 4'd0;
		end 
		else begin
			cnt_bit <= cnt_bit + 1'd1;
		end 
	end 
	else begin
		cnt_bit <= cnt_bit;
	end 
end 

assign add_cnt_bit = end_cnt_bps;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 9;

//发送标志tx_flag
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		tx_flag <= 1'b0;
	end 
	else if(tx_req)begin
		tx_flag <= 1'b1;
	end 
	else if(end_cnt_bit)begin
		tx_flag <= 1'b0;
	end 
	else begin
		tx_flag <= tx_flag;
	end 
end 


//数据缓存,tx_data
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		tx_data <= 10'b0;
	end 
	else if(tx_req)begin
		tx_data <= {1'b1, tx_din, 1'b0};
	end
	else begin
		tx_data <= tx_data;
	end 
end 

//tx_dout数据串行输出
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		tx_dout <= 1'b1;
	end 
	else if(tx_flag && cnt_bps == 1)begin
		tx_dout <= tx_data[cnt_bit];
	end 
	else begin
		tx_dout <= tx_dout;
	end 
end 

//dout_vld约束
assign dout_vld = ~tx_flag;

endmodule 

uart.v顶层模块

module uart(
	input wire 	clk	,
	input wire 	rst_n	,
	input	[2:0]	key	,
	input wire 	rx_esp,
	output wire tx_esp,     //串行输出
	input wire 	rx_pc,
	output wire tx_pc     //串行输出	
	);

wire [7:0] rx_byte		;
wire       rx_byte_vld	;
wire [7:0] rx_byte1		;
wire       rx_byte_vld1	;
wire [2:0] temp			;
wire	   tx_AT	 	;
wire	   tx_data	 	;

reg		en;
assign tx_esp=en==1?tx_AT:tx_data;

always @(posedge clk or negedge rst_n)begin 
	if(!rst_n)begin
		en <= 0;
	end 
	else if(temp[0])begin 
		en <= ~en;
	end 
	else begin 
		en <= en;
	end 
end
key_debounce(
.clk(clk),
.rst_n(rst_n),
.key(key[0]),

.temp(temp[0])
);


key_debounce(
.clk(clk),
.rst_n(rst_n),
.key(key[1]),

.temp(temp[1])
);


key_debounce(
.clk(clk),
.rst_n(rst_n),
.key(key[2]),

.temp(temp[2])
);

uart_rx u_uart_rx(
.clk		(clk),
.rst_n	(rst_n),
.rx_din	(rx_pc),//串行数据输入
	
.rx_dout	(rx_byte),//并行数据输出
.dout_vld(rx_byte_vld)//串转并完成标志
);


uart_rx u_uart_rx1(
.clk		(clk),
.rst_n	(rst_n),
.rx_din	(rx_esp),//串行数据输入
	
.rx_dout	(rx_byte1),//并行数据输出
.dout_vld(rx_byte_vld1)//串转并完成标志
);


uart_tx u_uart_tx(
.clk	(clk),
.rst_n	(rst_n),
.tx_req(rx_byte_vld),//发送请求
.tx_din(rx_byte),//并行数据输入
	
.tx_dout(tx_AT)//串行数据输出
//.dout_vld()//并转串完成标志
	

);

date_send u_date_send(
.clk	(clk),
.rst_n	(rst_n),
.key	(temp[2:1]),	
.tx_dout(tx_data)//串行数据输出	

);

uart_tx u_uart_tx1(
.clk	(clk),
.rst_n	(rst_n),
.tx_req(rx_byte_vld1),//发送请求
.tx_din(rx_byte1),//并行数据输入
	
.tx_dout(tx_pc)//串行数据输出
//.dout_vld()//并转串完成标志
	

);
endmodule 

五、具体操作及运行结果。

1.按照管教分配连接ESP8266.
2.连接WiFi
按下key1,将串口tx端切换到PC,此时可接收来自串口调试助手的数据。
在串口调试助手中选择开发板端口,并打开串口。
FPGA——ESP8266发送0、1实验
输入 AT+RST 重启ESP8266模块。
输入 AT+CWMODE=1 将模块设置为Station模式。(可能会因编码原因返回乱码)
输入 AT+CWJAP=“SSID”,“PWD” 该命令为连接路由器发出的WiFi信号,SSID为此WiFi的用户名,PWD为此PWD的密码。如果返回乱码,可在路由器后台,或电脑热点设置中查看是否连接成功。
FPGA——ESP8266发送0、1实验
在热点设置中查看到,esp8266连接成功。
FPGA——ESP8266发送0、1实验
3.创建TCP服务器
打开Socket tool,并创建端口为6666的TCP服务器。
FPGA——ESP8266发送0、1实验
打开串口调试助手,输入并发送指令:
AT+CIPSTART=“TCP”,“172.16.103.242”,6666(此处可根据自己实际情况修改ip及端口)
FPGA——ESP8266发送0、1实验
4.发送数据
输入 AT+CIPMODE=1 打开透传模式。
输入 AT+CIPSEND 设置发送数据长度。(AT+CIPSEND=14(等于符号后的数字代表发送数据的长度,此处我们暂不设置数字长度))
按下key1切换输入为按键输入。
按下key2、key3分别发送0、1至TCP服务器。
FPGA——ESP8266发送0、1实验

六、总结。

本实验主要就是理解串口各个端口的作用,以及串口发送单个字符。文章来源地址https://www.toymoban.com/news/detail-463972.html

到了这里,关于FPGA——ESP8266发送0、1实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 13-ESP8266连接MQTT服务器发送数据

    Author:teacherXue MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号

    2024年02月03日
    浏览(47)
  • ASR PRO与 ESP8266 CP2102进行串口通信

    ESP8266 ASR PRO RX PB5 TX PB6 GND(可选) GND(可选) 3.3V(可选) 3V3(可选) 如果 ASR PRO 频繁重启那就是电压不足需要对ESP8266进行单独供电,这边建议是对每块开发板都单独供电 下面是我的接线和供电方法 引脚 类型 PB_5 输出 PB_6 输出 波特率设置成为 9600 TX 为 PB_5 RX 为 PB_6 AT命令发送 软件名

    2023年04月08日
    浏览(67)
  • 关于ESP8266串口输出中文时出现乱码的解决方案

    本人之前并没有c语言的项目编程经验,第一次使用ESP8266以及Eclipse编程环境,因此犯了诸多新手会犯的错误,但在网上查找相关问题时发现许多初级错误并不能完整的找到解决办法,因此希望将个人踩过的坑分享出来,如果有初学者遇到类似问题可以得到较快解决方案。 日前

    2024年02月03日
    浏览(40)
  • 实验四:ESP8266WIFI通讯实验

    本实验开发板基于:GD32F103 我们首先需要看一下原理图 根据原理图可以看到,ESP8266是通过PA2 PA3这个串口进行通讯,PA13是控制它的复位, 从芯片手册中可以看到PA2PA3是串口1,PA2是串口1的发送,PA3是串口1的接收。 本项目使用ESP8266型号为ESP-01S 自带排针WIFI模块 功能特点:基

    2024年02月03日
    浏览(26)
  • microPython 吃透 esp8266 NodeMCU v3 ch340串口收发

    》》》》》》》》》》 这块板子的淘宝链接》 》》》》》》》》》》 1. usb口是ch340转UART0,双向收发 2. UART0 位于引脚 1 (TX) 和 3 (RX) 上。UART0是双向的,默认情况下用于REPL.,但是这块板子的RX 好像有问题使用引脚无法接收数据,因此使用引脚的UART0仅是TX。 3. 引脚 15 (

    2023年04月19日
    浏览(29)
  • 使用ESP8266-01s连接阿里云并发送数据

    一.硬件选型 esp8266-01s一个以及相应固件烧录器一个(小白的话在这里推荐直接在安信可的淘宝官网买已经含有mqtt固件的模组,我之前买了一个不知道什么问题固件完全烧录不进去),烧录器用来直接将esp8266直接插到电脑的USB接口上进行串口通信。 二.阿里云平台配置 1.注册

    2023年04月20日
    浏览(26)
  • 使用ArduinoMqttClient库连接阿里云,并实现发送接收数据(ESP8266)

    阿里云物联网平台的接入方式有很多种,从阿里云提供的开发文档可以看到,支持的接入协议有MQTT、HTTPS、CoAP、JT/808、GB/32960协议等等,并支持多种类型的设备接入。 对于阿里云物联网平台的接入,网上有许许多多的教程,有亲测有效的,表示感谢;也些教程留了有一些bu

    2024年02月02日
    浏览(24)
  • 十、stm32-ESP8266(串口透传、MCU透传、控制LED亮灭)

    见博客:stm32f103c8t6新建固件库模板(可自取) 固件库模板 MDK5开发环境 stm32参考手册 UART串口协议 stm32中断概念 ESP8266模块资料 利用固件库模板点灯工程(下面第三行,手动狗头) CH340 USB→TTL模块 ESP8266模块 手机软件 实验程序已经发布到百度网盘,本文末有链接可以自取

    2023年04月19日
    浏览(34)
  • NodeMCU ESP8266 基于Arduino IDE的串口使用详解(图文并茂)

    UART ( Universal Asynchronous Receiver/Transmitter ),串口通讯在嵌入式开发中至关重要,我们可以通过串口打印程序里的数据,也可以通过串口将数据发送到PC上并进行可视化的图形显示。 注意:相关的串口通讯的知识可以参考这篇文章 UART串口协议快速扫盲(图文并茂+超详细) Node

    2024年02月04日
    浏览(43)
  • 基于ESP8266+网络调试助手点灯实验

    ESP8266 是一种低成本、高性能的 Wi-Fi 模块,内置了 TCP/IP 协议栈,它可以作为单独的无线网络控制器,或者与其他微控制器进行串口通信。它具有以下特点: 1、采用CH340芯片,是一款高性价比开发板; 2、设计,使USB接口更加牢固; 3、文档资料齐全,任何人可免费获取,仅供传

    2024年02月15日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包