你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F103 USART串口通信

[复制链接]
STMCU小助手 发布时间:2022-4-5 20:21
14.1 USART定义

USART(Universal Synchronous/Asynchronous Receiver/Transmitter,即通用同步/异步收发器)串行通信是单片机最常用的一种通信技术,通常用于单片机和电脑之间以及单片机和单片机之间的通信。


14.2 USART串行通信协议


14.2.1 波特率和数据格式

USART通信中的同步通信功能很少用到,大多情况下只采用异步通信,只能实现异步通信功能的接口就称之为 UART。UART 通信通常以字节为单位组成数据帧,由通信收发双方根据预先约定的波特率(传输速率)进行通信。

波特率表示每秒发送二进制数据位的速率,单位是 bps,即 位/秒,波特率越高,传输速度越快,常用的 UART 通信波特率有2400,4800,9600,115200 等等。在进行串行通信之前,通信双方需要设置波特率保持一致,否则不能正常通信。

单片机标准串口进行通信时,没有数据传输时通信线路保持高电平状态。当要发送数据时,先发送一位0,用以表示开始发送,叫做起始位。然后再按照低位在前,高位在后的顺序发送8位数据。当8位数据发送完毕时,再发送一位1表示停止位。

对于接收端而言,开始时传输线路一直保持高电平,一旦检测到低电平,便准备开始接收数据。当接收完8位数据时,便检测停止位,检测完毕后,表示一帧数据发送完毕,开始准备接受下一帧数据。为了确保数据准确性,通常会在数据位之后设置校验位。

串行通信的数据帧的格式由起始位、数据位、奇偶校验位(可选)和停止位等部分组成,如图:

{)ATF(8AY8U]A{D8M}I(GUB.png


14.2.2 TTL通信接口和RS232通信接口

电脑和单片机之间进行串口通信,通常使用USB转UART芯片,将USB通信协议转成UART协议和单片机通信。



14.3 USART配置步骤

1.时钟使能
2.设置中断分组
3.串口复位
4.GPIO初始化(TX,RX引脚)
5.设置中断分组
6.串口初始化
7.开启中断
8.使能串口


1. 新建两个文件,usart.c 和 usart.h

[]OJ]~{CGB[$T27T%H}1@N3.png


2. 在头文件 usart.h 添加下面代码:
  1. #ifndef _USART_H
  2. #define _USART_H
  3. #include "stdio.h"
  4. #include "stm32f10x.h"

  5. #define USART_REC_LEN        200      //定义最大接收字节数 200
  6. #define EN_USART1_RX         1        //使能(1)/禁止(0)串口1接收

  7. extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
  8. extern u16 USART_RX_STA;                //接收状态标记

  9. void usart_init(u32 bound);

  10. #endif
复制代码

[4BJGRON~`JX8%H)Q8]0UUR.png


3. 把 usart.c 添加到工程中

{H%V(28~w4HYQRQF$]K8C.png

4. 在 usart.c 中添加以下代码:

  1. #include "usart.h"

  2. #pragma import(__use_no_semihosting)
  3. //标准库需要的支持函数
  4. struct __FILE
  5. {
  6.     int handle;
  7. };

  8. FILE __stdout;

  9. //定义_sys_exit()以避免使用半主机模式
  10. void _sys_exit(int x)
  11. {
  12.     x = x;
  13. }

  14. //重定义fputc函数
  15. int fputc(int ch, FILE *f)
  16. {
  17.     while((USART1->SR & 0X40) == 0); //循环发送,直到发送完毕
  18.     USART1->DR = (u8)ch;
  19.     return ch;
  20. }

  21. #if EN_USART1_RX                    //如果使能了接收
  22. //串口1中断服务程序
  23. //注意,读取USARTx->SR能避免莫名其妙的错误
  24. u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
  25. //接收状态
  26. //bit15,    接收完成标志
  27. //bit14,    接收到0x0d
  28. //bit13~0,    接收到的有效字节数目
  29. u16 USART_RX_STA = 0;                //接收状态标记

  30. void usart_init(u32 bound){

  31.     //GPIO端口设置
  32.     GPIO_InitTypeDef GPIO_InitStructure;
  33.     USART_InitTypeDef USART_InitStructure;
  34.     NVIC_InitTypeDef NVIC_InitStructure;

  35.     //使能USART1,GPIOA时钟
  36.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);
  37.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //配置中断优先级分组

  38.     //USART1_TX   GPIOA.9
  39.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;         //PA.9
  40.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  41.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出
  42.     GPIO_Init(GPIOA,&GPIO_InitStructure);             //初始化GPIOA.9

  43.     //USART1_RX      GPIOA.10初始化
  44.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;               //PA.10
  45.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空输入
  46.     GPIO_Init(GPIOA,&GPIO_InitStructure);                    //初始化GPIOA.10

  47.     //Usart1 NVIC 配置
  48.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  49.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ;  //抢占优先级3
  50.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;          //子优先级3
  51.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //IRQ通道使能
  52.     NVIC_Init(&NVIC_InitStructure);            //根据指定的参数初始化NVIC寄存器

  53.     //USART 初始化设置
  54.     USART_InitStructure.USART_BaudRate = bound;                    //串口波特率
  55.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;    //字长为8位数据格式
  56.     USART_InitStructure.USART_StopBits = USART_StopBits_1;         //一个停止位
  57.     USART_InitStructure.USART_Parity = USART_Parity_No;            //无奇偶校验位
  58.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  59.     USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;  //收发模式
  60.     USART_Init(USART1,&USART_InitStructure);        //初始化串口1

  61.     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);    //开启串口接受中断
  62.     USART_Cmd(USART1,ENABLE);                       //使能串口1
  63. }

  64. void USART1_IRQHandler(void)         //串口1中断服务程序
  65. {
  66.     u8 Res;

  67.     //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  68.     if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
  69.     {
  70.         Res = USART_ReceiveData(USART1);            //读取接收到的数据

  71.         if((USART_RX_STA & 0x8000) == 0)            //接收未完成
  72.         {
  73.             if(USART_RX_STA & 0x4000)               //接收到了0x0d
  74.             {
  75.                 if(Res != 0x0a) USART_RX_STA = 0;   //接收错误,重新开始
  76.                 else USART_RX_STA |= 0x8000;        //接收完成了
  77.             }
  78.             else //还没收到0X0D
  79.             {
  80.                 if(Res == 0x0d) USART_RX_STA |= 0x4000;
  81.                 else
  82.                 {
  83.                     USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
  84.                     USART_RX_STA++;
  85.                     if(USART_RX_STA > (USART_REC_LEN - 1))USART_RX_STA = 0; //接收数据错误,重新开始接收
  86.                 }
  87.             }
  88.         }
  89.         /*---- User Code Begin ----*/

  90.         /*---- User Code End ----*/
  91.     }
  92. }
  93. #endif
复制代码

3XKR98{IF1ODKV}1PQNCG53.png

QL}VQ#A`~~12`MZKX]38O.png

_WQ@[ZKGE3$OF}}(C{RFQBP.png

QM1]1J[_0]IYJ{Q`MHFC@LW.png

QN_DV9@TL@A{CTD)NTED2.png


5. 实现USART串口通信(以printf函数为例)

  1. #include "stm32f10x.h"
  2. #include "delay.h"
  3. #include "led.h"
  4. #include "tim.h"
  5. #include "key.h"
  6. #include "pwm.h"
  7. #include "usart.h"

  8. int main(void)
  9. {
  10.     delay_init();
  11.     usart_init(115200);

  12.     printf("USART Init Complete.\r\n");
  13.     while(1)
  14.     {
  15.         printf("Hello World !\r\n");
  16.         delay_ms(500);
  17.     }
  18. }
复制代码

~F@@88S8U0SOG6K(CBHFF]8.png


测试结果:

%ZT}C0)X@J{4TBY8M27MW{F.png


收藏 评论0 发布时间:2022-4-5 20:21

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版