STM32 USART中断

以STM32F103系列为例:

管脚初始化:

	RX-----浮空输入
	TX------复用推挽输出

USART初始化

  USART_InitStructure.USART_BaudRate = 115200;//波特率115200
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位
  USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位
  USART_InitStructure.USART_Parity = USART_Parity_No;//无校验位
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流控
  USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//发送和接收模式
  USART_Init(USART1,&USART_InitStructure);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //使能USART中断
  /*使能USART1*/
  USART_Cmd(USART1,ENABLE);
  USART_ClearFlag(USART1, USART_FLAG_TC);     /* 清发送外城标志,Transmission Complete flag */

中断优先级初始化

  NVIC_InitTypeDef NVIC_InitStructure;
  /* Configure the NVIC Preemption Priority Bits */  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  /* Enable the USART1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//优先级
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

串口中断模版


typedef struct{
	uint8_t rcvlen;//接受数据长度
	uint8_t rcvflag;//接受到数据标志位
	uint8_t rcvbuff[USARTLEN];//接受数据缓存区
}USART1RCV;


typedef struct{
	uint8_t sendcnt;
	uint8_t sendlen;
	uint8_t sendbuff[USARTLEN];
}USART1SEND;


void USART1_IRQHandler(void)
{
//使用操作系统时使用
#if OS_CRITICAL_METHOD == 3u
  OS_CPU_SR  cpu_sr = 0u;
#endif

  /*********************使用Ucosii时使用*******************/
  //告诉uCOS-II正在进行中断处理,在发送信号量时不进行任务调度  
  OS_ENTER_CRITICAL();   //保存全局中断标志,关总中断
  OSIntNesting++;
  OS_EXIT_CRITICAL();	   //恢复全局中断标志	
 /*******************************************************/
  //接收中断
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
		USART_ClearFlag(USART1,USART_FLAG_RXNE);
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
		
		rec_data = USART_ReceiveData(USART1);//接受数据
		usart1rcv.rcvlen++;                  //接受数据长度加一
		usart1rcv.rcvflag=1;//接受到数据
		runrecive[0]=0;//不执行时间点轮训中的串口接受数据处理
		usart1rcv.rcvbuff[(usart1rcv.rcvlen-1)]=rec_data;//保存数据
	}
	
	
	/*串口发送*/
	if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
	{
		USART_ClearITPendingBit(USART1,USART_IT_TXE);//清除发送中断标志位
		USART_SendData(USART1, usart1send.sendbuff[usart1send.sendcnt++]);
		if(sendcnt == usart1send.sendlen)
		{
			/* 关闭发送空中断,开启发送完成中断 */
			USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
			USART_ITConfig(USART1, USART_IT_TC, ENABLE);
		}    
	}
		//发送完成中断,最后一字节发送
	else if(USART_GetITStatus(USART1, USART_IT_TC) != RESET)
		USART_ITConfig(USART1,USART_IT_TC,DISABLE);
	
	OSIntExit();//使用UCOS-II时使用
}

接受数据处理:
接受到数据后若50ms后没有接受到数据,则数据接受完成
使用时间点轮训法

uint8_t   runrecive[2]={0,50};
if(runrecive[0]>=runrecive[1])
{
	runrecive[0]=0;//USART中断中清零,中断时不进入
	if(usart1rcv.rcvflag==1)
	{	
		RcvData_Handle();//自写中断数据处理函数
		Usart_Data_Clean();//串口接受结构体数据清空
	}
}

发送数据处理:

usart1send.sendlen=x;//x为要发送的数据长度,自定义
usart1send.sendtcnt=0;//清空已发送次数
usart1send.sendbuff[N]=data;//发送数据缓存赋值
USART_ITConfig(USART1,USART_IT_TXE,ENABLE); //使能串口1发送 

猜你喜欢

转载自blog.csdn.net/qq_37016048/article/details/88869011