[其他ST产品] STM32串口通信 (缓冲区 发送不出数据&接收不到数据)

[复制链接]
 楼主| 范德萨发额 发表于 2021-12-30 23:44 | 显示全部楼层 |阅读模式
流程
(简单的发送数据)

GPIO时钟使能
串口时钟使能
串口的GPIO配置
写初始化串口函数,配置串口USART_Init(USART1,&USART_InitStruct);
开启(使能)串口USART_Cmd(USART1, ENABLE);

附上代码

  1. void NVIC_Config_USART()
  2. {
  3.         NVIC_InitTypeDef   NVIC_InitStruct;
  4.        
  5.         NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
  6.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  7.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  8.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  9.         NVIC_Init(&        NVIC_InitStruct);
  10.        
  11.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  12. }
  13. void Init_UART()
  14. {
  15.      GPIO_InitTypeDef     GPIOInitstruct;
  16.            USART_InitTypeDef   USART_InitStruct;
  17.        
  18.           
  19.           RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,ENABLE);  //开启串口对应的GPIO时钟
  20.           RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1,ENABLE);//开启串口1的时钟  :Tx-A9   RX-A10,开
  21.           
  22.            GPIOInitstruct.GPIO_Mode = GPIO_Mode_AF_PP;   //设置串口GPIO模式(有两个)
  23.            GPIOInitstruct.GPIO_Pin = GPIO_Pin_9;
  24.            GPIOInitstruct.GPIO_Speed = GPIO_Speed_50MHz;      //Tx GPIO配置
  25.            GPIO_Init(GPIOA,&GPIOInitstruct);                       //设置TX为推免输出模式
  26.        
  27.                  GPIOInitstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  28.            GPIOInitstruct.GPIO_Pin = GPIO_Pin_10;
  29.            GPIOInitstruct.GPIO_Speed = GPIO_Speed_50MHz;
  30.            GPIO_Init(GPIOA,&GPIOInitstruct);       //设置RX GPIO配置
  31.        
  32.                 USART_InitStruct.USART_BaudRate = 115200;
  33.                 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  34.                 USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  35.                 USART_InitStruct.USART_Parity = USART_Parity_No;
  36.                 USART_InitStruct.USART_StopBits = USART_StopBits_1;
  37.                 USART_InitStruct.USART_WordLength = USART_WordLength_8b;   
  38.           USART_Init(USART1,&USART_InitStruct);   //配置好串口
  39.                
  40.                  NVIC_Config_USART();   //配置NVIC
  41.                  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  // 使能接收中断
  42.                  
  43.                
  44.                  USART_Cmd(USART1, ENABLE);   //开启串口
  45.                    //串口接受,会引发中断


  46. }

  47. void UART_SendByte(USART_TypeDef * USARTx, uint8_t dat)
  48. {
  49.         USART_SendData(USART1, dat);
  50.         while((USART_GetFlagStatus(USART1,USART_FLAG_TC))== RESET);
  51.           //发送缓冲区为空,状态置1,  写入一个数据,状态置0,灯数据发送借书,这个状态寄存器就变成1
  52.                                                           //实现了串口发送一个字节
  53. }

  54. void UART_SendString(USART_TypeDef * USARTx, char* string)
  55. {
  56.         char * str = string;//指向string
  57.         while(*str)   //只要str不为0,表示字符串还没有结束
  58.         {
  59.                 UART_SendByte(USARTx, *str);
  60.                 str++;
  61.         }

  62. }


  63. void LED_Init(void)
  64. {
  65. GPIO_InitTypeDef GPIO_InitStructure;
  66. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
  67. RCC_APB2Periph_GPIOE, ENABLE); //使能 PB,PE 端口时钟
  68. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 推挽输出
  69. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  70. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  71. GPIO_Init(GPIOB, &GPIO_InitStructure);
  72. GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
  73. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 推挽输出
  74. GPIO_Init(GPIOE, &GPIO_InitStructure);
  75. GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高

  76. }



 楼主| 范德萨发额 发表于 2021-12-30 23:45 | 显示全部楼层
中断函数:

  1. void USART1_IRQHandler(void)
  2. {
  3.          uint16_t temp;
  4.                 delay_init();
  5.         if(USART_GetITStatus(USART1,USART_IT_RXNE))
  6.         {
  7.                 GPIO_ResetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高
  8.                 temp = USART_ReceiveData(USART1);
  9.                 USART_SendData(USART1,temp);
  10.                 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == SET);
  11.                
  12.                
  13.         }
  14. }
 楼主| 范德萨发额 发表于 2021-12-30 23:47 | 显示全部楼层
注意事项

3052261cdd48040f55.png

巧妙运用 USART_GetFlagStatus函数来确定发送/接受数据是否完成,避免因为程序执行太快而导致数据丢失。
 楼主| 范德萨发额 发表于 2021-12-30 23:49 | 显示全部楼层
以下是详细代码:
@brief Checks whether the specified USART flag is set or not. *
@param USARTx: Select the USART or the UART peripheral. * This
parameter can be one of the following values: * USART1, USART2,
USART3, UART4 or UART5. * @param USART_FLAG: specifies the flag to
check. * This parameter can be one of the following values:
 楼主| 范德萨发额 发表于 2021-12-30 23:50 | 显示全部楼层
@ARG USART_FLAG_CTS:  CTS Change flag (not available for UART4 and UART5)
1
@ARG USART_FLAG_LBD:  LIN Break detection flag
1
@arg USART_FLAG_TXE:  Transmit data register empty flag
1
@arg USART_FLAG_TC:   Transmission Complete flag
1
@arg USART_FLAG_RXNE: Receive data register not empty flag
1
@arg USART_FLAG_IDLE: Idle Line detection flag
1
@arg USART_FLAG_ORE:  OverRun Error flag
1
@arg USART_FLAG_NE:   Noise Error flag
1
@arg USART_FLAG_FE:   Framing Error flag
1
@arg USART_FLAG_PE:   Parity Error flag
@retval The new state of USART_FLAG (SET or RESET).
/
FlagStatus USART_GetFlagStatus(USART_TypeDef USARTx, uint16_t USART_FLAG)


 楼主| 范德萨发额 发表于 2021-12-30 23:51 | 显示全部楼层
一点心得:
今天这个串口中断真的写了很久,最开始只有程序中的发送代码,但是都不能使我设置的GPIO的灯亮,原因是因为我的GPIO使能时钟函数写错了)(PS:细节决定成败)
第二步进阶: 发送的数据让串口返回 : 用到了NVIC中断函数
NVIC函数的步骤:
1.NVIC 初始化 NVIC_Init()
2.中断优先级 NVIC_PriorityGroupConfig
3. 使能(开启)接收中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
————————————————
版权声明:本文为CSDN博主「Tjyuking」的原创**,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45720531/article/details/110097800
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

1011

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部