谷动谷力

 找回密码
 立即注册
谷动谷力 门户 查看主题

STM32F103RCT6开发板M3单片机教程03--usart串口通信

发布者: sunsili | 发布时间: 2021-11-7 22:36| 查看数: 6028| 评论数: 7|帖子模式

本帖最后由 sunsili 于 2023-12-12 13:53 编辑

STM32F103RCT6开发板M3单片机教程03--usart串口通信


首先了解编译调试硬件连接,查看原理图

STM32F103RCT6开发板用Jlink供电,USB转串口板电脑USB供电,那么连接只需3线

*          TXD(PB9)     ->   USB转串口板RXD     
*           RXD(PB10) -> USB转串口T板XD      
*           GND       -> USB转串口板GND

  • 复制上节工程文件夹打开(这个方法比较方便)
  • 新建源文件usart.c,添加usart.c到BSP(Grounp),并编辑

    1. STM32F103RCT6开发板M3单片机教程03--usart串口通信


    2. 首先了解编译调试硬件连接,查看原理图


    3. 复制上节工程文件夹打开(这个方法比较方便)
    4. 新建源文件usart.c,添加usart.c到BSP(Grounp),并编辑
    5. 新建源文件SysTick.h,并编辑
    6. 编辑main.c
    7. 编译调试



    8. /**********************************************************************************
    9. * 文件名  :usart.c
    10. * 描述    :usart1 应用函数库         
    11. * 实验平台:SUN_STM32F1板
    12. * 硬件连接:TXD(PB9)  -> USB转串口板RXD     
    13. *           RXD(PB10) -> USB转串口T板XD      
    14. *           GND           -> USB转串口板GND
    15. * 库版本  :ST_v3.5
    16. * Version    Date       Auther      Reversed History
    17.   ----------------------------------------------------------------------------
    18.   V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    19.   
    20. * (C) Sunshine Silicon Corporation
    21. *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    22. *  E-Mail : fan@sunsili.com
    23. **********************************************************************************/

    24. #include "usart.h"         
    25.         
    26. vu8 Usart1_R_Buff[USART1_REC_MAXLEN];        //串口1数据接收缓冲区
    27. vu8 Usart1_R_State=0;                                        //串口1接收状态
    28. vu16 Usart1_R_Count=0;                                        //当前接收数据的字节数           

    29. /*******************************************************************************
    30. * 函数名  : USART1_Init_Config
    31. * 描述    : USART1初始化配置
    32. * 输入    : bound:波特率(常用:2400、4800、9600、19200、38400、115200等)
    33. * 输出    : 无
    34. * 返回    : 无
    35. * 说明    : 无
    36. *******************************************************************************/
    37. void USART1_Init_Config(u32 bound)
    38. {
    39.     GPIO_InitTypeDef  GPIO_InitStructure;
    40.         USART_InitTypeDef USART_InitStructure;
    41.         NVIC_InitTypeDef  NVIC_InitStructure;
    42.         
    43.         /*使能USART1和GPIOA外设时钟*/  
    44.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);        

    45.         /*复位串口1*/
    46.          USART_DeInit(USART1);  
    47.         
    48.         /*USART1_GPIO初始化设置*/
    49.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                        //USART1_TXD(PA.9)     
    50.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                //复用推挽输出
    51.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚输出最大速率为50MHz
    52.     GPIO_Init(GPIOA, &GPIO_InitStructure);                                //调用库函数中的GPIO初始化函数,初始化USART1_TXD(PA.9)  
    53.    
    54.    
    55.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                                //USART1_RXD(PA.10)
    56.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入
    57.     GPIO_Init(GPIOA, &GPIO_InitStructure);                                        //调用库函数中的GPIO初始化函数,初始化USART1_RXD(PA.10)


    58.    /*USART1 初始化设置*/
    59.         USART_InitStructure.USART_BaudRate = bound;                                                                                //设置波特率
    60.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;                                                //8位数据格式
    61.         USART_InitStructure.USART_StopBits = USART_StopBits_1;                                                        //1个停止位
    62.         USART_InitStructure.USART_Parity = USART_Parity_No;                                                                //无奇偶校验位
    63.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;        //无硬件数据流控制
    64.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                                        //工作模式设置为收发模式
    65.     USART_Init(USART1, &USART_InitStructure);                                                                                //初始化串口1

    66.    /*Usart1 NVIC配置*/
    67.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    68.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;        //抢占优先级3
    69.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //从优先级3
    70.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
    71.         NVIC_Init(&NVIC_InitStructure);                                                        //根据指定的参数初始化VIC寄存器
    72.          
    73.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                        //使能串口1接收中断

    74.     USART_Cmd(USART1, ENABLE);                                            //使能串口
    75.         USART_ClearFlag(USART1, USART_FLAG_TC);                                        //清除发送完成标志
    76. }


    77. /*******************************************************************************
    78. * 函数名  : USART_SendData
    79. * 描述    : USART1发送数据缓冲区数据
    80. * 输入    : *buff:数据缓冲区指针,len:发送数据长度
    81. * 输出    : 无
    82. * 返回    : 无
    83. * 说明    : 无
    84. *******************************************************************************/
    85. void USART1_SendData(u8* buff, u16 len)
    86. {   
    87.         u16 i;

    88.         for(i=0; i<len; i++)  
    89.         {
    90.                 while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
    91.             USART_SendData(USART1 ,buff[i]);   
    92.         }
    93. }

    94. /*******************************************************************************
    95. * 函数名  : USART1_IRQHandler
    96. * 描述    : 串口1中断服务程序
    97. * 输入    : 无
    98. * 返回    : 无
    99. * 说明    : 1)、只启动了USART1中断接收,未启动USART1中断发送。
    100. *           2)、接收到0x0d 0x0a(回车、"\r\n")代表帧数据接收完成
    101. *******************************************************************************/
    102. void USART1_IRQHandler(void)                        
    103. {
    104.         u8 Res=0;

    105.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    106.         {
    107.                 Res =USART_ReceiveData(USART1); //读取接收到的数据(USART1->DR)
    108.                
    109.                 Usart1_R_Buff[Usart1_R_Count++] = Res;
    110.                 if(Usart1_R_State == 0)//数据接收未完成
    111.                 {
    112.                         if(Res == 0x0d)//接收到0x0d,下一个字节接收到0x0a则接收完成
    113.                         {
    114.                                 Usart1_R_State =2;
    115.                         }
    116.                 }
    117.                 else if(Usart1_R_State == 2)
    118.                 {
    119.                         if(Res == 0x0a)//上一个字节接收到0x0d,这个字节接收到oxoa则接收完成
    120.                         {
    121.                                 Usart1_R_State =1;//数据接收完成
    122.                         }
    123.                         else//接收错误
    124.                         {
    125.                                 Usart1_R_State =0;
    126.                                 Usart1_R_Count =0;
    127.                         }
    128.                 }
    129.                 if(Usart1_R_Count >= USART1_REC_MAXLEN)//接收数据长度走出接收数据缓冲区
    130.                 {
    131.                         if((Usart1_R_Buff[USART1_REC_MAXLEN-2] != 0x0d) || (Usart1_R_Buff[USART1_REC_MAXLEN-1] != 0x0a))
    132.                         {
    133.                                 Usart1_R_Count =0;
    134.                                 Usart1_R_State =0;
    135.                         }
    136.                 }                  
    137.         }
    138. }         


    139. /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    140. ********************        END OF FILE usart.c        *******************/
    复制代码

  • 新建源文件usart.h,并编辑
    1. #ifndef __USART_H
    2. #define __USART_H

    3. #include "stm32f10x.h"
    4. #include <stdio.h>

    5. #define USART1_REC_MAXLEN 200        //最大接收数据长度

    6. void USART1_Init_Config(u32 bound);
    7. void USART1_SendData(u8* buff, u16 len);
    8. //int fputc(int ch, FILE *f);
    9. //void USART1_printf(USART_TypeDef* USARTx, uint8_t *Data,...);

    10. #endif



    11. /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    12. ********************        END OF FILE usart.h        *******************/
    复制代码

  • 编辑main.c
    1. /**********************************************************************************
    2. * Sun STM32 mini Demo

    3. *   Description
    4.    
    5.     Uart Demo

    6.    
    7. * Version    Date       Auther      Reversed History
    8.   ----------------------------------------------------------------------------
    9.   V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    10.   
    11. * (C) Sunshine Silicon Corporation
    12. *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    13. *  E-Mail : fan@sunsili.com

    14. **********************************************************************************/

    15. #include "stm32f10x.h"
    16. #include "usart.h"
    17. #include "SysTick.h"
    18. #include "led.h"
    19. #include <stdio.h>

    20. extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN];        //串口1数据接收缓冲区
    21. extern vu8 Usart1_R_State;                                                //串口1接收状态
    22. extern vu16 Usart1_R_Count;                                                //当前接收数据的字节数         

    23. /*******************************************************************************
    24. * 函数名  : main
    25. * 描述    : 主函数,用户程序从main函数开始运行
    26. * 输入    : 无
    27. * 输出    : 无
    28. * 返回值  : int:返回值为一个16位整形数
    29. * 说明    : 无
    30. *******************************************************************************/
    31. int main(void)
    32. {
    33.     SysTick_Init_Config();
    34.         USART1_Init_Config(115200);//USART1初始化配置
    35.     LED_GPIO_Config();
    36.     printf ("*===================================================*\n");
    37.     printf ("*  *  Name: Sun STM32 mini Demo Code.    *************\n");
    38.     printf ("*  * (C) Sunshine Silicon Corporation    *************\n");
    39.     printf ("*  *  Website: http://www.sunsili.com    *************\n");
    40.     printf ("*  *   E-Mail : fan@sunsili.com          *************\n");
    41.     printf ("*===================================================*\n");
    42.     printf ("* Sun STM32 mini uart transmit the same data to PC .*\n");
    43.         while (1)
    44.         {
    45.                 if(Usart1_R_State == 1)//一帧数据接收完成
    46.                 {
    47.                         USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count);   //USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)
    48.                         Usart1_R_State =0;
    49.                         Usart1_R_Count =0;
    50.                 }
    51.         
    52.         printf("Hello Sunshine Silicon!\r");

    53.         LED4_ON();
    54.         Delay_nMs(500);
    55.         LED4_OFF();
    56.         Delay_nMs(500);
    57.         }
    58. }



    59. /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    60. ********************        END OF FILE main.c        *******************/
    复制代码

  • 编译调试
方法不再重复,经过前两节练习,大家应该是会了.
但发现程序不跑了,单调试发现程序卡在printf不动了。为什么呢?因为MCU不像电脑只要添加stdio.h, 就能用printf。MCU要重定向c库函数printf到USART1(不一定USART1,实际用哪个定义到哪个),标准库代码内容还会被优化掉,编译时不输出。如何让它跑起来了呢。
在usart.c中添加函数
  1. ///重定向c库函数printf到USART1
  2. int fputc(int ch, FILE *f)
  3. {
  4.                 /* 发送一个字节数据到USART1 */
  5.                 USART_SendData(USART1, (uint8_t) ch);
  6.                
  7.                 /* 等待发送完毕 */
  8.                 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);               
  9.         
  10.                 return (ch);
  11. }

  12. ///重定向c库函数scanf到USART1
  13. int fgetc(FILE *f)
  14. {
  15.                 /* 等待串口1输入数据 */
  16.                 while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

  17.                 return (int)USART_ReceiveData(USART1);
  18. }
复制代码

设置编译时,加入MCU适用标准库函数



再次编译调试一切如愿。符合我们当初的设计。

工程源码(回复后可下载)
游客,如果您要查看本帖隐藏内容请回复



最新评论

微信用户 发表于 2024-1-20 13:07:40
支持一下
yangzs 发表于 2024-2-20 15:42:35
试一下                                                
rehuosheng 发表于 2024-3-12 11:13:02
谢谢分享!
零食 发表于 2024-3-28 08:41:16
感谢分享!
TiAmoXQ 发表于 2024-4-18 11:42:01
huoquyuanma
xl123 发表于 2024-4-19 09:49:46
STM32F103RCT6开发板M3单片机教程03--usart串口通信
寂然ing 发表于 2024-4-29 19:30:17
感谢分享

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-11-24 14:51 , Processed in 0.361062 second(s), 67 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

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