如果是跟随正点原子学习STM32的同学会发现,原子的代码里面很喜欢设置一个状态标志变量。
例如串口实验中的USART_RX_STA变量、定时器中的TIM5CH1_CAPTURE_STA变量,都是将一些重要数据保存在自定义的变量里面,这些变量可以看作是用户自定义的标志变量寄存器。
那么下面分析一下这些“寄存器”到底是什么意思、该如何使用。
1、下面以串口实验为例 串口实验
串口实验中定义 u16 USART_RX_STA =0
逻辑图分析:
函数本体:
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
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;//接收数据错误,重新开始接收
}
}
}
}
}
所以接收到的数据个数为 (USART_RX_STA&0x3FFF)个
2、下面以定时器实验为例 TIM输入捕获实验
u8 TIM5CH1_CAPTURE_STA
逻辑图分析:
代码本体:
u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态
u16 TIM5CH1_CAPTURE_VAL; //输入捕获值
int a=0;
void TIM5_IRQHandler(void)
{
if((TIM5CH1_CAPTURE_STA & 0x80) == 0)//未捕获成功
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update) != RESET) //再次检测是否有中断
{
if(TIM5CH1_CAPTURE_STA & 0x40)//已经捕获到高电平
{
if((TIM5CH1_CAPTURE_STA & 0x3F) == 0x3F )//到达计时最大值,不能再进行计数;所有数据附上最大值
{
TIM5CH1_CAPTURE_STA |= 0x80;//将捕获状态位(bit8)设为1,标记成功捕获
TIM5CH1_CAPTURE_VAL = 0xFFFF;
}
else
{
TIM5CH1_CAPTURE_STA++;
}
}
}
if(TIM_GetITStatus(TIM5,TIM_IT_CC1) != RESET)
{
if(TIM5CH1_CAPTURE_STA & 0x40)//从第一个高电平开始,捕获到第一个下降沿
{
TIM5CH1_CAPTURE_STA |= 0x80;//置位bit8,标记为一次捕获结束
TIM5CH1_CAPTURE_VAL = TIM_GetCapture1(TIM5);
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //????????????????????????
}
else//第一个高电平刚到
{
TIM5CH1_CAPTURE_STA = 0;
TIM5CH1_CAPTURE_VAL = 0;
TIM_SetCounter(TIM5,0); //全部清空
TIM5CH1_CAPTURE_STA |= 0x40;//标记捕获到上升沿
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//????????????????????????
}
}
}
TIM_ClearITPendingBit(TIM5,TIM_IT_Update | TIM_IT_CC1);
}
所以
计数次数 = (TIM5CH1_CAPTURE_STA&0x3F)* 65536 + TIM5CH1_CAPTURE_VAL
再根据定时器设定的定时周期,即可计算出捕获时间