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

STM32基础设计---中断串口通信

[复制链接]
STMCU小助手 发布时间:2023-1-5 21:02
首先,总结全文,设计步骤主要如下:
1,初始化GPIO
2,初始化USART1
3,初始化NVIC(嵌套向量中断控制器)
4,编写中断服务函数
5,编写主函数

详细步骤如下:

1,初始化GPIO
  1. void IO_Init()
  2. {
  3.         GPIO_InitTypeDef Uart_A;
  4.         GPIO_InitTypeDef led;
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
  6.        
  7.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);
  8.        
  9.         led.GPIO_Pin = GPIO_Pin_13;//博主开发板上的LED灯接的GPIOC的13引脚
  10.         led.GPIO_Mode = GPIO_Mode_Out_PP;
  11.         led.GPIO_Speed = GPIO_Speed_50MHz;
  12.         GPIO_Init(GPIOC,&led);
  13.        
  14.         Uart_A.GPIO_Pin = GPIO_Pin_9;
  15.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
  16.         Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;
  17.         GPIO_Init(GPIOA,&Uart_A);
  18.        
  19.         Uart_A.GPIO_Pin = GPIO_Pin_10;
  20.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
  21.         Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  22.         GPIO_Init(GPIOA,&Uart_A);
  23.        
  24. }
复制代码

以上代码不在详细介绍,前参看STM32基础设计(1)---点亮LED灯、SEM32基础设计(2)---查询串口通信


2,初始化USART1
  1. void Usart1_Init()
  2. {
  3.         USART_InitTypeDef Uart;
  4.        
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
  6.         Uart.USART_BaudRate = 115200;
  7.         Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  8.         Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  9.         Uart.USART_Parity = USART_Parity_No;
  10.         Uart.USART_StopBits = USART_StopBits_1;
  11.         Uart.USART_WordLength = USART_WordLength_8b;
  12.         USART_Init(USART1,&Uart);
  13.        
  14.         USART_Cmd(USART1,ENABLE);
  15.         USART_ClearFlag(USART1,USART_FLAG_TC);
  16. }
复制代码


以上代码不在详细介绍,具体请参看STM32基础设计(2)---查询串口通信


3,初始化NVIC
首先,让我们来了解库函数中的NVIC结构体:
  1. typedef struct
  2. {//指明那个中断通道
  3.   uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
  4.                                                    This parameter can be a value of @ref IRQn_Type
  5.                                                    (For the complete STM32 Devices IRQ Channels list, please
  6.                                                     refer to stm32f10x.h file) */
  7. //抢占优先级
  8.   uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
  9.                                                    specified in NVIC_IRQChannel. This parameter can be a value
  10.                                                    between 0 and 15 as described in the table @ref NVIC_Priority_Table */
  11. //子优先级
  12.   uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
  13.                                                    in NVIC_IRQChannel. This parameter can be a value
  14.                                                    between 0 and 15 as described in the table @ref NVIC_Priority_Table */
  15. //中断通道使能
  16.   FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
  17.                                                    will be enabled or disabled.
  18.                                                    This parameter can be set either to ENABLE or DISABLE */   
  19. } NVIC_InitTypeDef;
复制代码

了解了这个结构体后,就可以在初始化函数中定义这个变量了

  1. NVIC_InitTypeDef nvic;
复制代码

另外在NVIC初始化中还设置优先级分组(哪怕只有一个中断也要分组,这是规定)。具体使用这个库函数:

  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
  2. {
  3.   /* Check the parameters */
  4.   assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  5.   
  6.   /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
  7.   SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
  8. }
复制代码

接下来,设置结构体中变量的值:
  1. nvic.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
  2. nvic.NVIC_IRQChannelSubPriority = 0;//子优先级
  3. nvic.NVIC_IRQChannel = USART1_IRQn;//中断通道
  4. nvic.NVIC_IRQChannelCmd = ENABLE;//通道使能
  5. NVIC_Init(&nvic);//NVIC寄存器初始化
复制代码

4,编写中断服务函数
先贴代码,在解释
  1. void USART1_IRQHandler(void)//注意,这个函数名必须这样写,否则进不了USART1中断。详见库函数中的  IRQn_Type 结构体
  2. {
  3.         char temp= '0';
  4.         if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)//判断是否接收到数据
  5.         {
  6.                 temp = USART1->DR;//如果接收到数据,就将其读出,这样才可将RXNE寄存器清除
  7.                 if(temp == 'G')//如果接收到G  则关灯
  8.                 {
  9.                         GPIOC->BRR = GPIO_Pin_13;
  10.                 }else if(temp == 'K')//开灯
  11.                 {
  12.                         GPIOC->BSRR = GPIO_Pin_13;
  13.                 }
  14.         }
  15.                 if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')//如果发送寄存器为空,即可以发送数据
  16.                 {
  17.                         USART1->DR = temp;将接收到的数据再发送回去
  18.                         while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));等待数据发送完毕
  19.                 }
  20. }
复制代码

5,编写主函数

老规矩,先贴代码再解释:
  1. int main()
  2. {
  3.         IO_Init();
  4.         Usart1_Init();
  5.         Nvic_Init();
  6.         USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//这里是打开串口的接收中断,以便在USART1收到数据时,进入中断函数。这里特别提一下,现在不用打开发送中断,只有在准备发送数据时才应打开,否则会直接进入中断函数。
  7.         GPIOC->BSRR = GPIO_Pin_13;
  8.         while(1){}
  9. }
复制代码

额。。。突然发现没什么好解释的。

中断串口通信介绍到此完毕。

本文完整代码如下:
  1. #include<stm32f10x.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. void delay(uint n)
  5. {
  6.         int i,j;
  7.         for(i=0;i<n;i++)
  8.         for(j=0;j<8500;j++);
  9. }

  10. void IO_Init()
  11. {
  12.         GPIO_InitTypeDef Uart_A;
  13.         GPIO_InitTypeDef led;
  14.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
  15.        
  16.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);
  17.        
  18.         led.GPIO_Pin = GPIO_Pin_13;
  19.         led.GPIO_Mode = GPIO_Mode_Out_PP;
  20.         led.GPIO_Speed = GPIO_Speed_50MHz;
  21.         GPIO_Init(GPIOC,&led);
  22.        
  23.         Uart_A.GPIO_Pin = GPIO_Pin_9;
  24.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
  25.         Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;
  26.         GPIO_Init(GPIOA,&Uart_A);
  27.        
  28.         Uart_A.GPIO_Pin = GPIO_Pin_10;
  29.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
  30.         Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 110
  31.         GPIO_Init(GPIOA,&Uart_A);
  32.        
  33. }
  34. void Usart1_Init()
  35. {
  36.         USART_InitTypeDef Uart;
  37.        
  38.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
  39.         Uart.USART_BaudRate = 115200;
  40.         Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  41.         Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  42.         Uart.USART_Parity = USART_Parity_No;
  43.         Uart.USART_StopBits = USART_StopBits_1;
  44.         Uart.USART_WordLength = USART_WordLength_8b;
  45.         USART_Init(USART1,&Uart);
  46.        
  47.         USART_Cmd(USART1,ENABLE);
  48.         USART_ClearFlag(USART1,USART_FLAG_TC); //page 540
  49. }
  50. void Nvic_Init()
  51. {
  52.         NVIC_InitTypeDef nvic;
  53.        
  54.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  55.        
  56.         nvic.NVIC_IRQChannelPreemptionPriority = 1;
  57.         nvic.NVIC_IRQChannelSubPriority = 0;
  58.         nvic.NVIC_IRQChannel = USART1_IRQn;
  59.         nvic.NVIC_IRQChannelCmd = ENABLE;
  60.         NVIC_Init(&nvic);
  61. }

  62. int main()
  63. {
  64.         IO_Init();
  65.         Usart1_Init();
  66.         Nvic_Init();
  67.         USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
  68.         GPIOC->BSRR = GPIO_Pin_13;
  69.         while(1){}
  70. }

  71. void USART1_IRQHandler(void)
  72. {
  73.         char temp= '0';
  74.         if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)
  75.         {
  76.                 temp = USART1->DR;
  77.                 if(temp == 'G')
  78.                 {
  79.                         GPIOC->BRR = GPIO_Pin_13;
  80.                 }else if(temp == 'K')
  81.                 {
  82.                         GPIOC->BSRR = GPIO_Pin_13;
  83.                 }
  84.         }
  85.                 if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')
  86.                 {
  87.                         USART1->DR = temp;
  88.                         while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
  89.                 }
  90. }
复制代码


————————————————
版权声明:家安


收藏 评论0 发布时间:2023-1-5 21:02

举报

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