首先,总结全文,设计步骤主要如下:
1,初始化GPIO
2,初始化USART1
3,初始化NVIC(嵌套向量中断控制器)
4,编写中断服务函数
5,编写主函数
详细步骤如下:
1,初始化GPIO
- void IO_Init()
- {
- GPIO_InitTypeDef Uart_A;
- GPIO_InitTypeDef led;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
-
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);
-
- led.GPIO_Pin = GPIO_Pin_13;//博主开发板上的LED灯接的GPIOC的13引脚
- led.GPIO_Mode = GPIO_Mode_Out_PP;
- led.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC,&led);
-
- Uart_A.GPIO_Pin = GPIO_Pin_9;
- Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
- Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA,&Uart_A);
-
- Uart_A.GPIO_Pin = GPIO_Pin_10;
- Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
- Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA,&Uart_A);
-
- }
复制代码
以上代码不在详细介绍,前参看STM32基础设计(1)---点亮LED灯、SEM32基础设计(2)---查询串口通信
2,初始化USART1
- void Usart1_Init()
- {
- USART_InitTypeDef Uart;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
- Uart.USART_BaudRate = 115200;
- Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- Uart.USART_Parity = USART_Parity_No;
- Uart.USART_StopBits = USART_StopBits_1;
- Uart.USART_WordLength = USART_WordLength_8b;
- USART_Init(USART1,&Uart);
-
- USART_Cmd(USART1,ENABLE);
- USART_ClearFlag(USART1,USART_FLAG_TC);
- }
复制代码
以上代码不在详细介绍,具体请参看STM32基础设计(2)---查询串口通信
3,初始化NVIC
首先,让我们来了解库函数中的NVIC结构体:
- typedef struct
- {//指明那个中断通道
- uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
- This parameter can be a value of @ref IRQn_Type
- (For the complete STM32 Devices IRQ Channels list, please
- refer to stm32f10x.h file) */
- //抢占优先级
- uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
- specified in NVIC_IRQChannel. This parameter can be a value
- between 0 and 15 as described in the table @ref NVIC_Priority_Table */
- //子优先级
- uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
- in NVIC_IRQChannel. This parameter can be a value
- between 0 and 15 as described in the table @ref NVIC_Priority_Table */
- //中断通道使能
- FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
- will be enabled or disabled.
- This parameter can be set either to ENABLE or DISABLE */
- } NVIC_InitTypeDef;
复制代码
了解了这个结构体后,就可以在初始化函数中定义这个变量了
另外在NVIC初始化中还设置优先级分组(哪怕只有一个中断也要分组,这是规定)。具体使用这个库函数:
- void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
- {
- /* Check the parameters */
- assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
-
- /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
- SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
- }
复制代码
接下来,设置结构体中变量的值:
- nvic.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
- nvic.NVIC_IRQChannelSubPriority = 0;//子优先级
- nvic.NVIC_IRQChannel = USART1_IRQn;//中断通道
- nvic.NVIC_IRQChannelCmd = ENABLE;//通道使能
- NVIC_Init(&nvic);//NVIC寄存器初始化
复制代码
4,编写中断服务函数
先贴代码,在解释
- void USART1_IRQHandler(void)//注意,这个函数名必须这样写,否则进不了USART1中断。详见库函数中的 IRQn_Type 结构体
- {
- char temp= '0';
- if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)//判断是否接收到数据
- {
- temp = USART1->DR;//如果接收到数据,就将其读出,这样才可将RXNE寄存器清除
- if(temp == 'G')//如果接收到G 则关灯
- {
- GPIOC->BRR = GPIO_Pin_13;
- }else if(temp == 'K')//开灯
- {
- GPIOC->BSRR = GPIO_Pin_13;
- }
- }
- if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')//如果发送寄存器为空,即可以发送数据
- {
- USART1->DR = temp;将接收到的数据再发送回去
- while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));等待数据发送完毕
- }
- }
复制代码
5,编写主函数
老规矩,先贴代码再解释:
- int main()
- {
- IO_Init();
- Usart1_Init();
- Nvic_Init();
- USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//这里是打开串口的接收中断,以便在USART1收到数据时,进入中断函数。这里特别提一下,现在不用打开发送中断,只有在准备发送数据时才应打开,否则会直接进入中断函数。
- GPIOC->BSRR = GPIO_Pin_13;
- while(1){}
- }
复制代码
额。。。突然发现没什么好解释的。
中断串口通信介绍到此完毕。
本文完整代码如下:
- #include<stm32f10x.h>
- #define uint unsigned int
- #define uchar unsigned char
- void delay(uint n)
- {
- int i,j;
- for(i=0;i<n;i++)
- for(j=0;j<8500;j++);
- }
-
- void IO_Init()
- {
- GPIO_InitTypeDef Uart_A;
- GPIO_InitTypeDef led;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
-
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);
-
- led.GPIO_Pin = GPIO_Pin_13;
- led.GPIO_Mode = GPIO_Mode_Out_PP;
- led.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC,&led);
-
- Uart_A.GPIO_Pin = GPIO_Pin_9;
- Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
- Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA,&Uart_A);
-
- Uart_A.GPIO_Pin = GPIO_Pin_10;
- Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
- Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 110
- GPIO_Init(GPIOA,&Uart_A);
-
- }
- void Usart1_Init()
- {
- USART_InitTypeDef Uart;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
- Uart.USART_BaudRate = 115200;
- Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- Uart.USART_Parity = USART_Parity_No;
- Uart.USART_StopBits = USART_StopBits_1;
- Uart.USART_WordLength = USART_WordLength_8b;
- USART_Init(USART1,&Uart);
-
- USART_Cmd(USART1,ENABLE);
- USART_ClearFlag(USART1,USART_FLAG_TC); //page 540
- }
- void Nvic_Init()
- {
- NVIC_InitTypeDef nvic;
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
-
- nvic.NVIC_IRQChannelPreemptionPriority = 1;
- nvic.NVIC_IRQChannelSubPriority = 0;
- nvic.NVIC_IRQChannel = USART1_IRQn;
- nvic.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&nvic);
- }
-
- int main()
- {
- IO_Init();
- Usart1_Init();
- Nvic_Init();
- USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
- GPIOC->BSRR = GPIO_Pin_13;
- while(1){}
- }
-
- void USART1_IRQHandler(void)
- {
- char temp= '0';
- if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)
- {
- temp = USART1->DR;
- if(temp == 'G')
- {
- GPIOC->BRR = GPIO_Pin_13;
- }else if(temp == 'K')
- {
- GPIOC->BSRR = GPIO_Pin_13;
- }
- }
- if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')
- {
- USART1->DR = temp;
- while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
- }
- }
复制代码
————————————————
版权声明:家安
|