搜索
bottom↓
回复: 0
打印 上一主题 下一主题

《DNK210使用指南 -SDK版 V1.0》第十三章 UART实验

[复制链接]

出0入234汤圆

跳转到指定楼层
1

1)实验平台:正点原子DNK210开发板
2)购买链接:https://detail.tmall.com/item.htm?id=782801398750
3)全套实验源码+手册+视频下载地址:http://openedv.com/thread-348335-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学DNK210快速入门视频教程:https://www.bilibili.com/video/BV1kD421G7fu
6)正点原子FPGA交流群:132780729



第十三章 UART实验


       本章将介绍Kendryte K210的UART外设。通过本章的学习,读者将学习到UART的使用。
       本章分为如下几个小节:
       13.1 UART介绍
       13.2 硬件设计
       13.3 程序设计
       13.4 运行验证

       13.1 UART介绍
       串口通信是一种设备间常用的串行通信方式,串口按位(bit)发送和接收字节。尽管比特字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。在串口通信中,常用的协议包括RS-232、RS-422和RS-485等。
       随着科技的发展,RS-232在工业上还有广泛的使用,但是在商业技术上,已经慢慢的使用USB转串口取代了RS-232串口。我们只需要在电路中添加一个USB转串口芯片,就可以实现USB通信协议和标准UART串行通信协议的转换,而我们开发板上的USB转串口芯片是CH343P这个芯片。
       下面我们来学习串口通信协议,这里主要学习串口通信的协议层。
       串口通信的数据包由发送设备的TXD接口传输到接收设备的RXD接口。在串口通信的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据,其组成如图 13.1.1所示。

图13.1.1 串口通信协议数据帧格式

       串口通信协议数据包组成可以分为波特率和数据帧格式两部分。

       1. 波特率
       本章主要讲解的是串口异步通信,异步通信是不需要时钟信号的,但是这里需要我们约定好两个设备的波特率。波特率表示每秒钟传送的码元符号的个数,所以它决定了数据帧里面每一个位的时间长度。两个要通信的设备的波特率一定要设置相同,我们常见的波特率是4800、9600、115200等。

       2. 数据帧格式
       数据帧格式需要我们提前约定好,串口通信的数据帧包括起始位、停止位、有效数据位以及校验位。
       起始位和停止位
       串口通信的一个数据帧是从起始位开始,直到停止位。数据帧中的起始位是由一个逻辑0 的数据位表示,而数据帧的停止位可以是 0.5、1、1.5或 2个逻辑1的数据位表示,只要双方约定一致即可。
       有效数据位
       数据帧的起始位之后,就接着是数据位,也称有效数据位,这就是我们真正需要的数据,有效数据位通常会被约定为5、6、7或者8个位长。有效数据位是低位(LSB)在前,高位(MSB)在后
       校验位
       校验位可以认为是一个特殊的数据位。校验位一般用来判断接收的数据位有无错误,检验方法有:奇检验、偶检验、0检验、1检验以及无检验。下面分别介绍一下:
       奇校验是指有效数据为和校验位中“1”的个数为奇数,比如一个 8 位长的有效数据为:10101001,总共有 4 个“1”,为达到奇校验效果,校验位设置为“1”,最后传输的数据是8位的有效数据加上 1 位的校验位总共 9位。
       偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数,比如数据帧:11001010,此时数据帧“1”的个数为 4 个,所以偶校验位为“0”。
       0 校验是指不管有效数据中的内容是什么,校验位总为“0”,1 校验是校验位总为“1”。
       无校验是指数据帧中不包含校验位。
       我们一般是使用无校验的情况。

       3. Kendryte K210串口介绍
       Kendryte K210硬件上有3个UART控制器和1个UARTHS控制器,它们能够灵活地与外部设备进行全双工数据交换。
       UART一共有3个,其特点如下所示:
       1. 可编程收发波特率
       2. 3个UART的发送FIFO以及接收FIFO共享1024*8bit RAM全双工异步通信
       3. 支持输出信号波特率自动检测功能
       4. 支持5、6、7、8位数据长度
       5. 支持1、1.5、2、3、4位停止位长度
       6. 支持奇偶校验位
       7. 支持RS485协议
       8. 支持IrDA协议
       9. 支持DMA高速数据通信
       10. 支持UART唤醒模式
       11. 支持软件流控和硬件流控
       UARTHS一共有1个,其特点如下所示:
       1. 通讯速率可达5Mbps
       2. 8字节接收和发送FIFO
       3. 可编程中断模式
       4. 不支持硬件流控或者其他调制解调控制信号,或异步串行数据转换器
       本章实验只用到UART外设,UARTHS这里不详细介绍,感兴趣的自行了解学习。Kendryte K210官方SDK提供了多个操作UART的函数,这些函数介绍如下:

       1,uart_init函数
       该函数主要用于初始化UART外设,如下代码所示:
  1. void uart_init(uart_device_number_t channel)
  2. {
  3.     sysctl_clock_enable(SYSCTL_CLOCK_UART1 + channel);
  4.     sysctl_reset(SYSCTL_RESET_UART1 + channel);
  5. }

  6. /* uart_init 的UART功能编号 channel的配置参数 */
  7. typedef enum _uart_device_number
  8. {
  9.     UART_DEVICE_1,
  10.     UART_DEVICE_2,
  11.     UART_DEVICE_3,
  12.     UART_DEVICE_MAX,
  13. } uart_device_number_t;
复制代码
       函数共有一个参数,用于选择UART的编号进行初始化,可以看到函数先使能外设时钟,然后重新复位。

       2,uart_config函数
       该函数用于UART的功能,该函数原型及参数描述如下所示:
  1. void uart_config(uart_device_number_t channel, uint32_t baud_rate, uart_bitwidth_t data_width, uart_stopbit_t stopbit, uart_parity_t parity);

  2. /* 数据位宽度配置参数 */
  3. typedef enum _uart_bitwidth
  4. {
  5.     UART_BITWIDTH_5BIT = 5,
  6.     UART_BITWIDTH_6BIT,
  7.     UART_BITWIDTH_7BIT,
  8.     UART_BITWIDTH_8BIT,
  9. } uart_bitwidth_t;

  10. /* 停止位配置参数 */
  11. typedef enum _uart_stopbit
  12. {
  13.     UART_STOP_1,
  14.     UART_STOP_1_5,
  15.     UART_STOP_2
  16. } uart_stopbit_t;

  17. /*奇偶校验位配置参数 */
  18. typedef enum _uart_parity
  19. {
  20.     UART_PARITY_NONE,
  21.     UART_PARITY_ODD,
  22.     UART_PARITY_EVEN
  23. } uart_parity_t;
复制代码
       函数用于设置对应串口号的波特率、数据宽度、停止位宽度、奇偶校验位,第一个参数用于选择串口号,第二个参数设置串口的波特率,后面三个参数用于设置数据格式,分别设置数据位宽度、停止位宽度和奇偶校验位。

       3,uart_send_data函数
       该函数用来发送数据,函数代码如下所示:
  1. int uart_send_data(uart_device_number_t channel, const char *buffer, size_t buf_len)
  2. {
  3.     g_write_count = 0;
  4.     while(g_write_count < buf_len)
  5.     {
  6.         uart_channel_putc(*buffer++, channel);
  7.         g_write_count++;
  8.     }
  9.     return g_write_count;
  10. }
复制代码
       可以看到,函数共有三个参数,第一个参数用于设置发送数据的串口号,第二个参数是要发送的数据,第三个参数是设置发送数据的长度,函数会返回写入成功的字节数。

       4,uart_receive_data函数
       该函数用来发送数据,函数代码如下所示:
  1. int uart_receive_data(uart_device_number_t channel, char *buffer, size_t buf_len)
  2. {
  3.     size_t i = 0;
  4.     for(i = 0; i < buf_len; i++)
  5.     {
  6.         if(uart[channel]->LSR & 1)
  7.             buffer = (char)(uart[channel]->RBR & 0xff);
  8.         else
  9.             break;
  10.     }
  11.     return i;
  12. }
复制代码
       函数共有三个参数,第一个参数用于设置接收数据的串口号,第二个参数是用于设置接收数据存放的内存地址,第三个参数是设置接收数据的长度,该函数接收一段数据后会返回收到数据的字节数,我们可以根据返回值确定字符串的大小,从而方便我们处理数据。


       13.2 硬件设计

       13.2.1 例程功能
       1. Kendryte K210通过USB串口和上位机对话,Kendryte K210在收到上位机发过来的字符串后,会返回给上位机。同时每隔一定时间,通过USB串口输出一段信息到电脑。

       13.2.2 硬件资源

       1.USB接口
              UARTHS_TX – IO5
              UARTHS_RX – IO4

       13.2.3 原理图
       本章实验内容,主要讲解UART外设的使用,无需关注原理图。

       13.3 程序设计

       13.3.1 UART驱动代码介绍
       UART源码包括两个文件:uart.c和uart.h(正点原子团队编写),我们先介绍uart.h文件的内容。
  1. /*****************************HARDWARE-PIN*********************************/
  2. /* 硬件IO口,与原理图对应 */
  3. #define PIN_UART_USB_RX       (4)
  4. #define PIN_UART_USB_TX       (5)

  5. /*****************************SOFTWARE-GPIO********************************/
  6. /* 软件GPIO口,与程序对应 */
  7. #define UART_USB_NUM           UART_DEVICE_3

  8. /*****************************FUNC-GPIO************************************/
  9. /* GPIO口的功能,绑定到硬件IO口 */
  10. #define FUNC_UART_USB_RX       (FUNC_UART1_RX + UART_USB_NUM * 2)
  11. #define FUNC_UART_USB_TX       (FUNC_UART1_TX + UART_USB_NUM * 2)
复制代码
       这里是是硬件管脚和UART的串口号绑定,我们这里使用的是UART3。
  1. /**
  2. * @brief   初始化USART
  3. * @param   baudrate:波特率
  4. * @retval  无
  5. */
  6. void usart_init(uint32_t baudrate)
  7. {
  8.     fpioa_set_function(PIN_UART_USB_RX, FUNC_UART_USB_RX);
  9.     fpioa_set_function(PIN_UART_USB_TX, FUNC_UART_USB_TX);
  10.     /* 初始化串口号,设置波特率,8位数据格式,1个停止位,无奇偶校验位 */
  11.     uart_init(UART_USB_NUM);
  12.     uart_configure(UART_USB_NUM, baudrate, UART_BITWIDTH_8BIT, UART_STOP_1, UART_PARITY_NONE);
  13. }
复制代码
       这个函数用于初始化我们UART,函数带有一个参数,用于设置波特率,串口号可以通过uart.h文件的宏定义修改,可以看到,我们先绑定硬件管脚的功能,然后初始化UART,再配置UART即可。

       13.3.2 main.c代码
       main.c中的代码如下所示:
  1. char recvbut[200];

  2. int main(void)
  3. {
  4.     uint16_t times = 0;
  5.     uint8_t recvbut_len = 0;
  6.     char *hello = {"正点原子K210 开发板\r\n"};

  7.     usart_init(115200); /* 初始化UART */

  8.     /* 开机发送正点原子K210 开发板 */
  9.     uart_send_data(UART_USB_NUM, hello, strlen(hello));

  10.     while (1)
  11.     {

  12.         /* 等待串口信息,并通过串口发送出去 */
  13.         recvbut_len = uart_receive_data(UART_USB_NUM, recvbut, 200);
  14.         if (recvbut_len != 0)
  15.         {
  16.             uart_send_data(UART_USB_NUM, recvbut, recvbut_len);
  17.         }
  18.         else
  19.         {
  20.             if ((times % 30000) == 0)
  21.             {
  22.                 uart_send_data(UART_USB_NUM, hello, strlen(hello));
  23.                 times = 0;
  24.             }
  25.             times++;
  26.             usleep(100);  
  27.         }
  28.     }
  29. }
复制代码
       我们主要看到循环中的内容,先用定义的变量recvbut_len获取接收数据的长度,并将数据存放于recvbut,如果数据长度不为0(有数据),则通过串口发送收到的数据recvbut,否则,延时100us。系统每隔3秒打印输出一段信息。

       13.4 运行验证
       将DNK210开发板连接到电脑主机,通过VSCode将固件烧录到开发板中,我们打开“串口终端”,可以看到串口中断不断的打印数据,如下图所示:

图13.4.1 “串行终端”窗口打印输出

       也可以通过串口调试助手来收发数据,我们用XCOM V2.7,该软件在光盘有提供,且无需安装,直接可以运行,但是需要你的电脑安装有.NET Framework 4.0(WIN自带了)或以上版本的环境才可以,该软件的详细介绍请看:http://www.openedv.com/posts/list/22994.htm 这个帖子。
       接着我们打开XCOM V2.7,设置串口为开发板的USB转串口(CH343虚拟串口,得根据你自己的电脑选择,我的电脑是COM50,另外,请注意:波特率是115200)。XCOM的左下角提供发送新行这个选项,只要勾选了这个选项,每次发送数据后,XCOM都会自动多发一个回车换行(0X0D+0X0A)。设置好了发送新行,我们再在发送区输入你想要发送的文字,然后单击发送,可以看到输出信息,如图下图所示:

图13.4.2 串口助手

       可以看到,我们发送的消息被发送回来了。大家可以试试,如果数据出现乱码,可能是串口助手编码方式不同导致的,这时我们需要重新设置XCOM的串口助手的编码方式,选择UTF-8编码,如下图所示:

图13.4.3 修改串口助手编码方式

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

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-10-16 18:08

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

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