STM32中断函数如何进入问题理解详述

最近开始学正点原子stm32开发板,在学习usart串口通信发现一个问题,就是接受数据是如何保存到USART_RX_BUF中的。正点原子的demo是接收到数据后直接传入USART1->DR中发送出来;但显然在main函数中并没有接受的数据存入USART_RX_BUF的过程。

int main(void){
	…………
	while(1)
	{
		if(USART_RX_STA&0x8000){ 
			len=USART_RX_STA&0x3FFF;//得到此次接收到的数据长度
			printf("\r\n 您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++){
				USART1->DR=USART_RX_BUF[t]; //写入DR寄存器直接发送
				while((USART1->SR&0X40)==0); //等待发送结束
			}
		…………
	}
}

于是转到usart.c文件中,该文件只有两个函数;一个是中断处理函数;这里很显然包括了接受数据写入USART_RX_BUF的过程;但是该函数在main中并没有被调用。

#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
  
void USART1_IRQHandler(void)
{
	u8 res;	
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART1->SR&(1<<5))	//接收到数据
	{	 
		res=USART1->DR; 
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}else{	//还没收到0X0D
				if(res==0x0d)USART_RX_STA|=0x4000;
				else{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1)) USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}  		 									     
	}
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif

于是继续看初始化函数;该函数对寄存器进行了一系列初始化,并且在最后面设置了中断的函数,但是传入的变量是USART1_IRQn而不是USART1_IRQHandler;很显然它们之间是相关联的,但是它们是怎么关联上的呢?

void uart_init(u32 pclk2,u32 bound)
{  	 
	……………………
#if EN_USART1_RX		  //如果使能了接收
	//使能接收中断 
	USART1->CR1|=1<<5;    //接收缓冲区非空中断使能	    	
	MY_NVIC_Init(3,3,USART1_IRQn,2); //组2,最低优先级 
#endif
}

 基于上面的问题进行了检索,发现并没有一个详细的解释,有一篇相关的来自于2017年的博文,找到的一点思路,该博文po在此处:STM32是如何进入中断服务函数xxx_IRQHandler的_中断服务函数是如何进入的_小时候挺菜的博客-CSDN博客该文提到了在启动文件startup_stm32f10x_hd.s中,有一段汇编:

DCD USART1_IRQHandler    其中DCD是一条数据定义伪指令,用于分配一片连续的字存储单元并用指定的数据初始化。

但这只能说明在编译过程为USART1_IRQHandler开辟了一片地址,但仍然没有介USART1_IRQn与USART1_IRQHandler的连接过程,于是对USART1_IRQn进行了检索,在stm32f10x.h发现了其定义:

#ifdef STM32F10X_HD 
  ……………………
  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
  ………………
#endif /* STM32F10X_HD */  

 然后仔细对比了一下,两者顺序完全相同(见下图对比)。因此猜想USART1_IRQn和USART1_IRQHandler指向同一个地址。

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值