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

【经验分享】STM32串口中断实例二

[复制链接]
STMCU小助手 发布时间:2022-2-6 22:00
  1. int main(void)
  2. {
  3.     uint8_t a=0;//LED高低电压控制

  4.     /* System Clocks Configuration */
  5.     RCC_Configuration();                                              //系统时钟设置
  6.     /*嵌套向量中断控制器
  7.         说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */
  8.     NVIC_Configuration();                                              //中断源配置
  9.     /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。
  10.     在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B, 因此要对这个端口的时钟
  11.     进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/
  12.     GPIO_Configuration();                                              //端口初始化
  13.     USART_Config(USART1);                                              //串口1初始化

  14.     while (1)
  15.     {
  16.         if(rec_f == 1)
  17.         {   
  18.             //判断是否收到一帧有效数据                                             
  19.             rec_f = 0;

  20.             for(i=0; i<sizeof(TxBuffer1); i++) //发送字符串
  21.             {
  22.                 USART_SendChar(USART1,TxBuffer1[i]);
  23.                 Delay(0x0000ff0);
  24.             }
  25.             /*for(i=0;i<TxCounter1;i++)//发送字符串
  26.             {
  27.                 USART_SendChar(USART1,RxBuffer1[i]);
  28.             } */
  29.             if(a==0)
  30.             {
  31.                 GPIO_SetBits(GPIOD, GPIO_Pin_2);    //LED1  明暗闪烁
  32.                 a=1;
  33.             }
  34.             else
  35.             {
  36.                 GPIO_ResetBits(GPIOD, GPIO_Pin_2);
  37.                 a=0;
  38.             }
  39.         }
  40.     }
  41. }
复制代码
main函数如上。
相关变量
  1. uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";
  2. uint8_t RxBuffer1[], rec_f, tx_flag, i;

  3. __IO uint8_t TxCounter1 = 0x00;
  4. __IO uint8_t RxCounter1 = 0x00;

  5. uint32_t Rec_Len;
复制代码

串口中断函数配置如下所示:
  1. //--------------------------------------------------------------------------------------
  2. void USART_SendChar(USART_TypeDef* USARTx,uint8_t data)
  3. {
  4.     USART_SendData(USARTx,data);
  5.     while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
  6. }
  7. //--------------------------------------------------------------------------------------
  8. void USART_Config(USART_TypeDef* USARTx)
  9. {
  10.     USART_InitStructure.USART_BaudRate = 19200;                        //速率19200bps
  11.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;        //数据位8位
  12.     USART_InitStructure.USART_StopBits = USART_StopBits_1;            //停止位1位
  13.     USART_InitStructure.USART_Parity = USART_Parity_No;                //无校验位
  14.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //无硬件流控
  15.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                    //收发模式

  16.     /* Configure USARTx */
  17.     USART_Init(USARTx, &USART_InitStructure);                            //配置串口参数函数


  18.     /* Enable USARTx Receive and Transmit interrupts */
  19.     USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);          //使能接收中断
  20.     USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);            //使能发送缓冲空中断

  21.     /* Enable the USARTx */
  22.     USART_Cmd(USARTx, ENABLE);
  23. }
  24. //--------------------------------------------------------------------------------------
  25. void Delay(__IO uint32_t nCount)
  26. {
  27.     for(; nCount!=0; nCount--);
  28. }
  29. /*--------------------------------------------------------------------------------------
  30. 系统时钟配置为72MHZ+外设时钟配置*/
  31. void RCC_Configuration(void)
  32. {
  33.     SystemInit();
  34.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOA, ENABLE);
  35. }
  36. //--------------------------------------------------------------------------------------
  37. void GPIO_Configuration(void)
  38. {
  39.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                     //LED1控制--PD2
  40.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;             //推挽输出
  41.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  42.     GPIO_Init(GPIOD, &GPIO_InitStructure);

  43.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                      //USART1 TX
  44.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;             //复用推挽输出
  45.     GPIO_Init(GPIOA, &GPIO_InitStructure);                     //A端口

  46.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                  //USART1 RX
  47.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //复用开漏输入
  48.     GPIO_Init(GPIOA, &GPIO_InitStructure);                      //A端口
  49. }
  50. //--------------------------------------------------------------------------------------
  51. void NVIC_Configuration(void)
  52. {
  53.     /*  结构声明*/
  54.     NVIC_InitTypeDef NVIC_InitStructure;

  55.     /* Configure the NVIC Preemption Priority Bits */
  56.     /* Configure one bit for preemption priority */
  57.     /* 优先级组 说明了抢占优先级所用的位数,和子优先级所用的位数   在这里是1, 7 */
  58.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  59.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                     //设置串口1中断
  60.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;             //抢占优先级 0
  61.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //子优先级为0
  62.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  63.     NVIC_Init(&NVIC_InitStructure);
  64. }
复制代码

在中断服务函数中编写usart函数。
  1. //串口1 中断服务程序
  2. void USART1_IRQHandler(void)      
  3. {
  4.     unsigned int i;
  5.    
  6.     //判断读寄存器是否非空
  7.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)      
  8.     {
  9.         //将读寄存器的数据缓存到接收缓冲区里
  10.         RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);   

  11.         //判断结束标志是否是0x0d 0x0a
  12.         if(RxBuffer1[RxCounter1-2] == 0x0d && RxBuffer1[RxCounter1-1] == 0x0a)     
  13.         {
  14.             for(i=0; i< RxCounter1; i++)
  15.                 TxBuffer1[i] = RxBuffer1[i];          //将接收缓冲器的数据转到发送缓冲区,准备转发
  16.             
  17.             //接收成功标志
  18.             rec_f = 1;            
  19.             
  20.             //发送缓冲区结束符
  21.             TxBuffer1[RxCounter1] = 0;                                             
  22.             TxCounter1 = RxCounter1;
  23.             RxCounter1 = 0;
  24.         }
  25.     }

  26.     //这段是为了避免STM32 USART 第一个字节发不出去的BUG
  27.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                  
  28.     {
  29.         //禁止发缓冲器空中断,
  30.         USART_ITConfig(USART1, USART_IT_TXE, DISABLE);                        
  31.     }

  32. }
复制代码


运行结果如下,在发送去不填写任何字符,直接发送,显示RT Interrupt Example: This is USART1 DEMO,说明前三个字符已经被占用替换了。

216878-20181003142931280-1140176473.png

收藏 评论0 发布时间:2022-2-6 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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