STM32串口的中断接收并实现控制开灯

Posted 行稳方能走远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32串口的中断接收并实现控制开灯相关的知识,希望对你有一定的参考价值。

摘自:串口 stm32 实现中断接收 打开板子上的led灯
作者:点灯小哥
发布时间: 2021-03-07 11:55:35
网址:https://blog.csdn.net/weixin_46016743/article/details/114481125


注:板子上的LED灯看电路图连接的是PC13引脚,具体配置方法参见前面博文介绍,写到led.c文件里面。

在usart.c上增加配置NVIC优先级中断控制器

	NVIC_InitTypeDef Nvic_init;	 //misc.h
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //配置NVIC中断组
	
    //3.配置NVIC中断控制器  在misc.h里
	Nvic_init.NVIC_IRQChannel = EXTI1_IRQn;  //= 配置在启动文件里 中断通道  这里要选择USART1_IRQn 串口1中断通道
	Nvic_init.NVIC_IRQChannelCmd = ENABLE;      //使能  找到FunctionalState字眼 右键goto
	Nvic_init.NVIC_IRQChannelPreemptionPriority = 1;   //因为只配置了一个中断  不考虑优先级 所以只有1个
	Nvic_init.NVIC_IRQChannelSubPriority = 1;//抢占优先级与子优先级
	
	NVIC_Init(&NvicInitStructure);

usart.c

#include "stm32f10x.h"                  // Device header
#include "usart.h"
//#include "stdio.h"
 
void Usart_Init(void)
{
	//2. 配置GPIO的结构体
	GPIO_InitTypeDef GpioInitStructure; //初始化GPIO结构体命名
	USART_InitTypeDef UsartInitStructure;//初始化USART结构体命名
	//加入NVIC
	NVIC_InitTypeDef	NvicInitStructure;  //初始化USART结构体命名 

	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVIC中断组  目前一个中断随便配置就好了
 
	
	//1. 配置时钟:GPIO口的时钟,引脚复用的时钟,串口的时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
 
	
	//2.1 配置PA9 TX
	GpioInitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;//复用推挽输出
	GpioInitStructure.GPIO_Pin   = GPIO_Pin_9;
	GpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GpioInitStructure);
	
	//2.2 配置PA10 RX
	GpioInitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输入
	GpioInitStructure.GPIO_Pin   = GPIO_Pin_10;
	GPIO_Init(GPIOA,&GpioInitStructure);
	
	//3.配置串口结构体
	UsartInitStructure.USART_BaudRate =   115200;        //波特率
	UsartInitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //硬件流
	UsartInitStructure.USART_Mode = USART_Mode_Rx| USART_Mode_Tx;					//模式
	UsartInitStructure.USART_Parity = USART_Parity_No;						//校验位
	UsartInitStructure.USART_StopBits =	USART_StopBits_1;					//停止位
	UsartInitStructure.USART_WordLength =	USART_WordLength_8b;				//字节长度
	USART_Init(USART1, &UsartInitStructure);
	
	USART_ITConfig( USART1,  USART_IT_RXNE, ENABLE ); //中断标志位
 
	USART_Cmd(USART1, ENABLE);//打开串口 比配置GPIO多这一步
 

	NvicInitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
	NvicInitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NvicInitStructure.NVIC_IRQChannelSubPriority = 1;//子优先级
	NvicInitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NvicInitStructure);
 
	
}
//发送字符
void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
		USART_SendData( USARTx,  Data);
		while( USART_GetFlagStatus( USARTx,  USART_FLAG_TXE) == RESET);//USART_GetFlagStatus是判断标志位 USART_FLAG_TXE 去usart.h  FLAG找
}
//发送字符串
void USARTSendString( USART_TypeDef* USARTx, char *str)
{
		uint16_t i = 0;
		do{
			USARTSendByte(USART1,*(str+i));
			i++;
		}while(*(str+i) != '\\0');
		
		while( USART_GetFlagStatus( USARTx,  USART_FLAG_TC) == RESET);//USART_GetFlagStatus是判断标志位 USART_FLAG_TC(这是判断字符串) 去usart.h  FLAG找
 
}

//重写Printf
//int fputc(int ch, FILE *f)
//{
//		USARTSendByte( USART1,  (uint8_t)ch);
//		while( USART_GetFlagStatus( USART1,  USART_FLAG_TXE) == RESET);
//		return (ch);
//}
//int fgetc(FILE *f)
//{
//		
//		while( USART_GetFlagStatus( USART1,  USART_FLAG_RXNE) == RESET);
//		
//		return (int) USART_ReceiveData(USART1);
 
//}

main.c

#include "stm32f10x.h"                  // Device header
#include "usart.h"
#include "led.h"
#include "exti.h"
 
void delay(uint16_t time)
{
		uint16_t i = 0;
		while(time--)
		{
			i=12000;
			while(i--);
		}
}
 
int main(void)
{
 
		Usart_Init();
		LED_Init();
//		USARTSendByte(USART1,'O');
//		USARTSendByte(USART1,'K');
	
//		USARTSendString( USART1, "甘boss");
//		printf("甘boss");
//		putchar('X');
	
		GPIO_SetBits( GPIOC,  GPIO_Pin_13);//初始化C13电平为高电平 灯不亮
 
		while(1)
		{
			
			
			
		}
}
//4. 中断服务函数
void USART1_IRQHandler(void)//函数名必须是这个 固件库里面定义好了的  自动就调用了
{
		char temp;
		                                //标志位,选择接收数据寄存器
		if( USART_GetITStatus( USART1,  USART_IT_RXNE) != RESET) //发生了中断 开始接收数据
		{
			 
			temp = USART_ReceiveData( USART1);
			
			if(temp == 'O')//串口接收到的数据是什么
			{
				 GPIO_ResetBits( GPIOC,  GPIO_Pin_13);//串口助手发送过来字符'O' 开灯
				 USARTSendString(  USART1, "LED IS OK");//调用自己写的串口发送字符串函数
 
			
			}
			if(temp == 'C')
			{
				 GPIO_SetBits( GPIOC,  GPIO_Pin_13);//关灯
				 USARTSendString(  USART1, "LED IS DOWN");
 
			}
		
		}
 
 
}

以上是关于STM32串口的中断接收并实现控制开灯的主要内容,如果未能解决你的问题,请参考以下文章

STM32串口 不用中断方式 接收一个字符串...怎么解决?

stm32h750串口发送中断关掉

STM32中串口中断接收异常

STM32使用DMA接收串口数据

stm32 串口发送数组 cpu可以工作吗

stm32 开启接收中断 PC 发送两次 为啥串口只接收到一次