您的位置 首页 开关

STM32F10x 学习笔记5(USART完成串口通讯 1)

STM32F10x系列单片机中都包含了USART模块,所谓USART,就是通用同步异步收发器。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业…

STM32F10x系列单片机中都包含了USART模块,所谓USART,便是通用同步异步收发器。通用同步异步收发器(USART)供给了一种灵敏的办法与运用工业规范NRZ异步串行数据格式的外部设备之间进行全双工数据交换。它支撑同步单向通讯和半双工单线通讯,也支撑LIN(部分互连网),智能卡协议和IrDA(红外数据安排)SIRENDEC规范,以及调制解调器(CTS/RTS)操作。它还答应多处理器通讯。

早年面的介绍可知USART模块功用十分的强壮。这儿我只简略讲讲如何用USART模块来完结规范EIA-232串口通讯

用过单片机的人肯定都触摸过串口,设置串口无非便是设置波特率、数据位、中止位、奇偶校验位。发送接纳也就三种根本方法,轮询、中止和DMA。STM32F10x的USART模块也不过如此。所以我要点讲讲我在调试代码时犯得各种过错,那些很简单得到的代码就不详细的讲解了。

首要说说我的硬件环境。仍是那块神舟4号开发板,用的是串口2,对应的是USART2。默许情况下USART2是连接到IO端口A的,可是我这儿需求将USART的管腿重定向到IO端口D上。详细的管腿的联系拜见下表。这个表是从STM32参阅手册上拷下来的。

初始化USART的代码很简略。USART2连接到APB1总线上了,先要翻开USART2的时钟,然后设置波特率一类的参数。

  1. USART_InitTypeDefUSART_InitStructure;
  2. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
  3. USART_InitStructure.USART_BaudRate=9600;
  4. USART_InitStructure.USART_WordLength=USART_WordLength_8b;
  5. USART_InitStructure.USART_StopBits=USART_StopBits_1;
  6. USART_InitStructure.USART_Parity=USART_Parity_No;
  7. USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  8. USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
  9. USART_Init(USART2,&USART_InitStructure);

这样设置了还不能运用。由于咱们将USART2重定向了。重定向操作需求写复用重映射和调试I/O装备寄存器(AFIO_MAPR)。GPIO_PinRemapConfig()能够完结这项使命。

  1. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);

光这样操作还不行。STM32参阅手册上有这么一段话:

对寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXT%&&&&&%RX进行读写操作前,应当首要翻开AFIO的时钟。参阅第6.3.7节APB2外设时钟使能寄存器(RCC_APB2ENR)。

所以需求先翻开AFIO的时钟。因而,USART2的重定向需求两步操作:

[cpp]view plaincopy

  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  2. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);

我原以为这样就能工作了,可是成果仍是什么都没有输出。没办法只能持续研讨。在读GPIO的相关章节时看到下图让我茅塞顿开。

USART2的输入输出都是借用PD口管腿,PD口的时钟却还没给。用到的几个IO端口也没有设置相应的输入输出状况。在读到8.1.9复用功用装备这一小节时发现了如下的表格。

依照上面给出的装备,写好程序:

  1. GPIO_InitTypeDefGPIO_InitStructure;
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
  3. /*ConfigureUSARTTxasalternatefunctionpush-pull*/
  4. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
  5. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
  6. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  7. GPIO_Init(GPIOD,&GPIO_InitStructure);
  8. /*ConfigureUSARTRxasinputfloating*/
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
  11. GPIO_Init(GPIOD,&GPIO_InitStructure);

再次测验,一切正常。

发送一个字符的函数能够这么写:

  1. voidUART_PutChar(USART_TypeDef*USARTx,uint8_tData)
  2. {
  3. while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET){};
  4. USART_SendData(USARTx,Data);
  5. }

这个函数能够窜逃优化一下,晒干的两个函数调用都能够去掉,甚至于这个函数能够用汇编来完结或许写成inline 函数。不过这儿仅仅个示例代码,没有考虑这些。

发送字符串的函数如下:

  1. voidUART_PutStr(USART_TypeDef*USARTx,uint8_t*str)
  2. {
  3. while(0!=*str)
  4. {
  5. UART_PutChar(USARTx,*str);
  6. str++;
  7. }
  8. }

上面串口初始化的代码能够放到一个函数中:

  1. voidUSART2_init(void)
  2. {
  3. GPIO_InitTypeDefGPIO_InitStructure;
  4. USART_InitTypeDefUSART_InitStructure;
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO,ENABLE);
  6. /*ConfigureUSARTTxasalternatefunctionpush-pull*/
  7. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
  8. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
  9. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  10. GPIO_Init(GPIOD,&GPIO_InitStructure);
  11. /*ConfigureUSARTRxasinputfloating*/
  12. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  13. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
  14. GPIO_Init(GPIOD,&GPIO_InitStructure);
  15. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
  16. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
  17. USART_InitStructure.USART_BaudRate=9600;
  18. USART_InitStructure.USART_WordLength=USART_WordLength_8b;
  19. USART_InitStructure.USART_StopBits=USART_StopBits_1;
  20. USART_InitStructure.USART_Parity=USART_Parity_No;
  21. USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  22. USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
  23. USART_Init(USART2,&USART_InitStructure);
  24. USART_Cmd(USART2,ENABLE);
  25. }

今日先写这么多。接纳字符的函数与发送字符的函数差不多,可是这种轮询方法功率很低,不主张运用。下次写一篇介绍如何用中止方法发送接纳串口数据,中止方法的功率会高许多。假如有时间再写一篇DMA方法发送接纳数据的文章。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/kaiguan/264245.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部