用户工具

站点工具


nios_ii之uart串口通信实验

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
nios_ii之uart串口通信实验 [2019/12/21 11:30]
zhangzheng
nios_ii之uart串口通信实验 [2022/03/22 10:31] (当前版本)
sean
行 1: 行 1:
-[[https://www.cnblogs.com/xiaomagee/p/11195860.html]]+|  **银杏科技有限公司旗下技术文档发布平台** ​ |||| 
 +|技术支持电话|**0379-69926675-801**||| 
 +|技术支持邮件|Gingko@vip.163.com||| 
 +^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ 
 +|  V1.0  |  2020-07-03 ​ |  gingko ​ |  初次建立 ​ |  
 + 
 +===== 实验二十:NIOSII之UART串口通信实验 ===== 
 + 
 +==== 一、 实验目的与意义 ==== 
 +  - 了解UART接口模块的工作原理。 
 +  - 掌握UART接口模块的使用方法。 
 +  - 掌握QuartusII的使用方法。 
 +==== 二、 实验设备及平台 ==== 
 + 
 +  - iCore4 双核心板[[https://item.taobao.com/item.htm?​spm=a1z10.1-c-s.w4004-22598974120.15.5923532fsFrHiE&​id=551864196684|点击购买]]。 
 +  - Blaster(或相同功能)仿真器[[https:​//item.taobao.com/​item.htm?​id=554869837940|点击购买]]。 
 +  - JLINK(或相同功能)仿真器。 
 +  - Micro USB线缆。 
 +  - Quartus开发平台。 
 +  - 电脑一台。 
 +==== 三、 硬件连接 ==== 
 + 
 +{{ :​icore4:​icore4_fpga_20_0.png?​direct |}} 
 +序号与引脚对应表 
 +|序号 |对应端口名称 |对应引脚| 
 +|1 |Uart_rxd |PIN_U7| 
 +|2 |Uart_txd |PIN_Y7| 
 +|3 |gnd |--| 
 + 
 +==== 四、 实验内容 ==== 
 + 
 +=== 一、硬件部分 === 
 + 
 + 
 +1、首先打开实验十八里面建立的工程(所有路径保持不变),如图所示: 
 +{{ :​icore4:​icore4_fpga_20_1.png?​direct |图20-1}} 
 +2、下面添加UART接口模块,选择Tools->​Qsys,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_2.png?​direct |图20-2}} 
 +3、打开已有的noisII工程,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_3.png?​direct |图20-3}} 
 +{{ :​icore4:​icore4_fpga_20_4.png?​direct |图20-4}} 
 +4、进入后界面如图所示: 
 +{{ :​icore4:​icore4_fpga_20_5.png?​direct |图20-5}} 
 +5、在界面左侧选择Interface Protocols->​Serial->​Serial->​UART(RS-232 serial port),​然后添加。 
 +{{ :​icore4:​icore4_fpga_20_6.png?​direct |图20-6}} 
 +6、在此界面参数设置如图所示,然后点击Finish:​ 
 +{{ :​icore4:​icore4_fpga_20_7.png?​direct |图20-7}} 
 +7、添加成功后界面如图所示: 
 +{{ :​icore4:​icore4_fpga_20_8.png?​direct |图20-8}} 
 +8、对uart模块进行重命名为uart,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_9.png?​direct |图20-9}} 
 +9、双击uart模块下面external_connection后面的Double-click to改为uart如图所示。 
 +{{ :​icore4:​icore4_fpga_20_10.png?​direct |图20-10}} 
 +10、下面开始连接时钟线,右击uart下面的clk与clk_0连线: 
 +{{ :​icore4:​icore4_fpga_20_11.png?​direct |图20-11}} 
 +11、连接复位线,如图所示。 
 +{{ :​icore4:​icore4_fpga_20_12.png?​direct |图20-12}} 
 +12、连接信号线s1,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_13.png?​direct |图20-13}} 
 +13、连接中断信号线,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_14.png?​direct |图20-14}} 
 +14、程序代码较大,修改内存大小,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_15.png?​direct |图20-15}} 
 +{{ :​icore4:​icore4_fpga_20_16.png?​direct |图20-16}} 
 +15、点击System->​Assign Base Address重新分配基地址,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_17.png?​direct |图20-17}} 
 +16、选择菜单栏中的Generate->​Generate,​重新编译: 
 +{{ :​icore4:​icore4_fpga_20_18.png?​direct |图20-18}} 
 +17、点击Generate开始编译,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_19.png?​direct |图20-19}} 
 +18、直接点击关闭即可: 
 +{{ :​icore4:​icore4_fpga_20_20.png?​direct |图20-20}} 
 +19、关闭 Qsys 窗口,回到 Quartus 主界面,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_21.png?​direct |图20-21}} 
 +20、在此界面右击选择 Update Symbol or Block… 
 +{{ :​icore4:​icore4_fpga_20_22.png?​direct |图20-22}} 
 +21、直接点击 OK 即可。 
 +{{ :​icore4:​icore4_fpga_20_23.png?​direct |图20-23}} 
 +22、界面如图所示: 
 +{{ :​icore4:​icore4_fpga_20_24.png?​direct |图20-24}} 
 +23、右击 ledcorel 模块生成引脚,如图所示 : 
 +{{ :​icore4:​icore4_fpga_20_25.png?​direct |图20-25}} 
 +24、为串口模块端口分配引脚(建议用 tcl 文件导入的方法),如图所示 : 
 +{{ :​icore4:​icore4_fpga_20_26.png?​direct |图20-26}} 
 +25、保存并编译工程,编译成功后硬件实现部分就完成了, 下载到 FPGA 中, 下面开 始软件部分的实现。 
 + 
 +=== 二、软件部分 === 
 + 
 +1、点击菜单栏中的 Tool->​Nios II Software Build Tools for Eclipse,打开 NIOSII 软件,选 择正确的路径(与 Quartus 工程路径相同),点击 OK。 
 +{{ :​icore4:​icore4_fpga_20_27.png?​direct |图20-27}} 
 +2、选择 Generate BSP,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_28.png?​direct |图20-28}} 
 +3、右击 led 选择 Update with Modified Files,如图所示: 
 +{{ :​icore4:​icore4_fpga_20_29.png?​direct |图20-29}} 
 +4、将以下代码写到 main.c 中。 
 +<code c> 
 +/* 
 +* FILE                                : main.c 
 +* DESCRIPTION ​                        : This file is main files. 
 +* Author ​                             : XiaomaGee@Gmail.com 
 +* Copyright ​                          : 
 +
 +* History 
 +* -------------------- 
 +* Rev                                  : 0.00 
 +* Date                                 : 09/​05/​2012 
 +
 +* create. 
 +* -------------------- 
 +*/ 
 +//​-----------------Include files-------------------------//​ 
 +#include "​stdio.h"​ 
 +#include "​unistd.h"​ 
 +#include "​system.h"​ 
 +#include "​string.h"​ 
 +#include "​sys/​alt_irq.h"​ 
 + 
 +unsigned int receive_flag=0;​ 
 +unsigned int receive_count=0;​ 
 +unsigned char receive_buffer[200];​ 
 +//​----------------函数声明-----------------//​ 
 +static int uart_send_byte(unsigned char data); 
 +static void uart_send_string(unsigned int len, unsigned char *str); 
 +static int uart_init(void);​ 
 +static void uart_ISR(void *context);​ 
 +static int set_baudrate(unsigned int baudrate);​ 
 + 
 +typedef ​ struct { 
 + volatile ​ unsigned ​ long  int DATA; 
 + volatile ​ unsigned ​ long  int DIRECTION;​ 
 + volatile ​ unsigned ​ long  int INTERRUPT_MASK;​ 
 + volatile ​ unsigned ​ long  int EDGE_CAPTURE;​ 
 +}PIO_T; 
 + 
 +typedef struct 
 +
 + union{ 
 + struct{ 
 + volatile unsigned long int RECEIVE_DATA ​      :8; 
 + volatile unsigned long int NC                 :​24;​ 
 + }BITS; 
 + volatile unsigned long int WORD; 
 + }RXDATA; 
 + 
 + union{ 
 + struct{ 
 + volatile unsigned long int TRANSMIT_DATA ​     :8; 
 + volatile unsigned long int NC                 :​24;​ 
 + }BITS; 
 + volatile unsigned long int WORD; 
 + }TXDATA; 
 + 
 + union{ 
 + struct{ 
 + volatile unsigned long int PE :1; 
 + volatile unsigned long int FE :1; 
 + volatile unsigned long int BRK :1; 
 + volatile unsigned long int ROE :1; 
 + volatile unsigned long int TOE :1; 
 + volatile unsigned long int TMT :1; 
 + volatile unsigned long int TRDY :1; 
 + volatile unsigned long int RRDY :1; 
 + volatile unsigned long int E :1; 
 + volatile unsigned long int NC :1; 
 + volatile unsigned long int DCTS :1; 
 + volatile unsigned long int CTS :1; 
 + volatile unsigned long int EOP :1; 
 + volatile unsigned long int NC1 :19; 
 + }BITS; 
 + volatile unsigned long int WORD; 
 + }STATUS; 
 + 
 + union{ 
 + struct{ 
 + volatile unsigned long int IPE :1; 
 + volatile unsigned long int IFE :1; 
 + volatile unsigned long int IBRK :1; 
 + volatile unsigned long int IROE :1; 
 + volatile unsigned long int ITOE :1; 
 + volatile unsigned long int ITMT :1; 
 + volatile unsigned long int ITRDY :1; 
 + volatile unsigned long int IRRDY :1; 
 + volatile unsigned long int IE :1; 
 + volatile unsigned long int TRBK :1; 
 + volatile unsigned long int IDCTS :1; 
 + volatile unsigned long int RTS :1; 
 + volatile unsigned long int IEOP :1; 
 + volatile unsigned long int NC :19; 
 + }BITS; 
 + volatile unsigned long int WORD; 
 + }CONTROL;​ 
 + union{ 
 + struct{ 
 + volatile unsigned long int BAUD_RATE_DIVISOR :16; 
 + volatile unsigned long int NC :16; 
 + }BITS; 
 + volatile unsigned int WORD; 
 + }DIVISOR;​ 
 +}UART_ST; 
 + 
 +#define LED ((PIO_T ​ *)(LED_BASE|1<<​31)) 
 +#define UART         ​((UART_ST *)(UART_BASE|1<<​31)) 
 + 
 +//​-----------------Function------------------------------//​ 
 +int main() 
 +
 + 
 + unsigned char buffer[30] = "​Hello! I am iCore4!\n";​ 
 + uart_init();​ 
 + while (1) { 
 + /​*蓝色led灯闪烁*/​ 
 +    ​LED->​DATA = 1; 
 +    ​usleep(500000);​ 
 +    ​LED->​DATA = 0; 
 +    ​usleep(500000);​ 
 + /​*串口通信*/​ 
 + if(receive_flag){ 
 + receive_flag = 0;//clear flags 
 + memset(buffer,​0,​50);//​ clear buffer 
 + strcpy(buffer,​receive_buffer);//​copy buffer 
 + uart_send_string(sizeof(buffer),​buffer);​ 
 +
 + uart_send_string(sizeof(buffer),​buffer);​ 
 + usleep(500000);​ 
 +   } 
 +   ​return 0; 
 +
 +/* 
 + * === FUNCTION ======================================================= 
 + * Name                                : uart_send_byte 
 + * DESCRIPTION ​                        : 发送一个Byte 
 + * Author ​                             : XiaomaGee@Gmail.com 
 + * Copyright ​                          : 
 + * 
 + * History 
 + * -------------------- 
 + * Rev                                  : 0.00 
 + * Date                                 : 06/​05/​2016 
 + * 
 + * create. 
 + * -------------------- 
 + * ================================================================= 
 + */ 
 +int uart_send_byte(unsigned char data) 
 +
 + UART->​TXDATA.BITS.TRANSMIT_DATA = data; 
 + while(!UART->​STATUS.BITS.TRDY);​ 
 + 
 + return 0; 
 +
 + 
 +/* 
 + * === FUNCTION ======================================================= 
 + * Name                                : uart_send_string 
 + * DESCRIPTION ​                        : 串口发送函数 
 + * Author ​                             : XiaomaGee@Gmail.com 
 + * Copyright ​                          : 
 + * 
 + * History 
 + * -------------------- 
 + * Rev                                  : 0.00 
 + * Date                                 : 06/​05/​2016 
 + * 
 + * create. 
 + * -------------------- 
 + * ====================================================================== 
 + */ 
 +void uart_send_string(unsigned int len, unsigned char *str) 
 +
 + while(len--) 
 +
 + uart_send_byte(*str++);​ 
 +
 +
 + 
 +/* 
 + * === FUNCTION ======================================================= 
 + * Name                                : uart_init 
 + * DESCRIPTION ​                        : 串口初始化 
 + * Author ​                             : XiaomaGee@Gmail.com 
 + * Copyright ​                          : 
 + * 
 + * History 
 + * -------------------- 
 + * Rev                                  : 0.00 
 + * Date                                 : 06/​05/​2016 
 + * 
 + * create. 
 + * -------------------- 
 + * ================================================================= 
 + */ 
 +int uart_init(void) 
 +
 + //​将波特率设置为9600 
 + //​set_baudrate(9600);​ 
 + 
 + //​将控制寄存器IRRDY置1,在接收准备好后使能中断 
 + UART->​CONTROL.BITS.IRRDY=1;​ 
 + //​将状态寄存器全部清零 
 + UART->​STATUS.WORD=0;​ 
 + //​为UART注册中断 
 + alt_irq_register(UART_IRQ,​NULL,​uart_ISR);​ 
 + 
 + return 0; 
 +
 + 
 +/* 
 + * === FUNCTION ======================================================= 
 + * Name                                : uart_ISR 
 + * DESCRIPTION ​                        : 串口中断服务函数 
 + * Author ​                             : XiaomaGee@Gmail.com 
 + * Copyright ​                          : 
 + * 
 + * History 
 + * -------------------- 
 + * Rev                                  : 0.00 
 + * Date                                 : 06/​05/​2016 
 + * 
 + * create. 
 + * -------------------- 
 + */ 
 +static void uart_ISR(void *context) 
 +
 + //​等待状态寄存器RRDY置1,当RRDY为1时表示接收的数据已经传输到RXDATA中 
 + while(!(UART->​STATUS.BITS.RRDY));​ 
 + receive_buffer[receive_count++] = UART->​RXDATA.BITS.RECEIVE_DATA;​ 
 + //​接收的数据以换行符'​\n'​为结束标志,所以PC端的发送数据最后必须添加上'​\n'​ 
 + if(receive_buffer[receive_count-1]=='​\n'​){ 
 + receive_buffer[receive_count]='​\0';​ 
 + receive_count=0;​ 
 + receive_flag=1;​ 
 +
 +
 +/* 
 + * === FUNCTION ======================================================= 
 + * Name                                : set_baudrate 
 + * DESCRIPTION ​                        : 设置波特率 
 + * Author ​                             : XiaomaGee@Gmail.com 
 + * Copyright ​                          : 
 + * 
 + * History 
 + * -------------------- 
 + * Rev                                  : 0.00 
 + * Date                                 : 06/​05/​2016 
 + * 
 + * create. 
 + * -------------------- 
 + * ================================================================= 
 + */ 
 +int set_baudrate(unsigned int baudrate) 
 +
 + UART->​DIVISOR.WORD=(unsigned int)(ALT_CPU_FREQ/​baudrate+0.5);​ 
 + 
 + return 0; 
 +
 +</​code>​ 
 +5、右击 led 选择 Build Project 编译工程,如图所示:​ 
 +{{ :​icore4:​icore4_fpga_20_30.png?​direct |图20-30}} 
 +6、编译成功后会出现 led build complete,​如图所示:​ 
 +{{ :​icore4:​icore4_fpga_20_31.png?​direct |图20-31}} 
 +7、右击 led 选择 Run As…->​32 Nios II Hardware,​如图所示:​ 
 +{{ :​icore4:​icore4_fpga_20_32.png?​direct |图20-32}} 
 +8、可能出现如下窗口,在 Target Connection 中点击 Refresh Connections。 
 +{{ :​icore4:​icore4_fpga_20_33.png?​direct |图20-33}} 
 +9、点击 RUN 
 +{{ :​icore4:​icore4_fpga_20_34.png?​direct |图20-34}} 
 +10、成功后可以看到 FPGA 蓝色 LED 闪烁,串口助手上如下图所示: 
 +{{ :​icore4:​icore4_fpga_20_35.png?​direct |图20-35}} 
 +==== 五、 实验现象 ==== 
 + 
 +  * FPGA 蓝色 LED 闪烁,串口助手(Commix)上显示收到的数据(Hello! I am iCore4!)。 
nios_ii之uart串口通信实验.1576899055.txt.gz · 最后更改: 2019/12/21 11:30 由 zhangzheng