1.关于TI1FP1,TI1FP2,TI2FP1,TI2FP2这四个信号的解释
TIMx_CH1 进入的信号叫TI1
TI1去通道1的信号叫TI1FP1
TI1去通道2的信号叫TI1FP2
同样
TIMx_CH2 进入的信号叫TI2
TI2去通道1的信号叫TI2FP1
TI2去通道2的信号叫TI2FP2
也就是说STM8S的定时器输入捕获通道和输入引脚不是一一对应的,一个输入信号可以接入两个测量通道。列如中TIMx_CH1
进入的频率信号通道1或通道2都可以测量,相应的TIMx_CH2进入的信号通道1或通道2也都可以测量。
2.在芯片对应的数据手册中TIMx_CHx如果是在中括号中标注的,说明这个功能不是
IO引脚默认的复用功能,需要在选项字节里重新设置才能映射到此功能,调试输入捕获程序时很容易忽略这一点。
3.测量通道只能设置成上升沿检测或下降沿检测,所以要同时测量一个波形的高电平时间和低电平时间时,需要用到两个
通道对同一个输入进捕获测量。你如测量pwm信号的占空比。
以下为TIM1 的TIM1_CH4引脚测量红外遥控按键信号的示例,注意,定时器有复杂的输入检测触发功能但本示例没有用到
触发功能,定时器只是简单的向上计数,溢出时重新从0开始计数
#define CAP_COUNT 24 //一次接收捕获次数
uint16_t g_Record[CAP_COUNT]; //电平保持时间记录
uint8_t g_Index; //当前捕获位置
uint8_t volatile g_RecvFlag;
//系统时钟为8M
void Timer1Open(void)
{
//1us计时,CH4捕获中断
CLK->PCKENR1 |= CLK_PCKENR1_TIM1;//TIM1定时器时钟允许
TIM1->CNTRH = 0x00;//清零计数器高8位
TIM1->CNTRL = 0x00;//清零计数器低8位
TIM1->PSCRH = 0x00;//计数器时钟分频高8位
TIM1->PSCRL = 0x08;//计数器时钟分频低8位8分频
//通道3通道4连接到TIM1_CH4引脚 通道3上升沿捕获通道4下降沿捕获
TIM1->CCER2&=0;//清零TIM1_CCER2 CC4E位,之后才可配置TIM1_CCMR1
TIM1->CCMR3 =0x22;
TIM1->CCMR4 = 0x21; //不分频,波波4周期 TI4(TIM1_CHR4)到通道4 (TI4FP4) (中文参考手册有误,请参考
英文 参考手册 )
TIM1->CCER2 = TIM1_CCER2_CC4P|TIM1_CCER2_CC3E|TIM1_CCER2_CC4E;//捕获使能,cc4 下降沿 cc3上升沿
TIM1->IER = TIM1_IER_CC3IE|TIM1_IER_CC4IE;//使能捕获/比较4中断
TIM1->EGR=TIM1_EGR_CC3G|TIM1_EGR_CC4G;//触发中断
TIM1->CR1 |= TIM1_CR1_CEN;//使能定时/计数器
}
//输入捕获中断
INTERRUPT void TIM1_CAPHandler(void)
{
uint16_t t;
if(TIM1->SR1 & TIM1_SR1_CC4IF)
{
//读痕迹冰清标志
t=TIM1->CCR4H;
t<<=8;
t+=TIM1->CCR4L;
}
else if(TIM1->SR1 & TIM1_SR1_CC3IF)
{
t=TIM1->CCR3H;
t<<=8;
t+=TIM1->CCR3L;
}
else
{
TIM1->SR1=0;
return ;
}
TIM1->SR1=0;//清标志位
if(g_RecvFlag) return ;
if(g_Index >= CAP_COUNT)
{
g_RecvFlag=1;
return ;
}
g_Record[g_Index++]=t;
if(g_Index >= CAP_COUNT)
{
g_RecvFlag=1;
frm_set_event(EVENT_IR_ID);//程序框架触发接收完成一个按键操作
}
}
//初始化红外检测
void ir_start_scan(void)
{
//TIM1_CH4 PC4
GPIOC->DDR&=~(1<<4);//输入模式
GPIOC->CR1&=~(1<<4);//浮空输入
//GPIOC->CR1|=(1<<5);上拉输入
GPIOC->CR2&=~(1<<4);//中断关闭
g_Index=0;
g_RecvFlag=0;
Timer1Open();
}
//接口函数,读取接收数据
uint8_t ir_read_code(void)
{
uint8_t i,ir_code;
uint16_t prev,next;
if( g_RecvFlag == 0)
return 0;
//时间痕迹会记录在g_Record数组里,下面进分析 HS9148发送的波形得出按键值并返回
for(i=0;i<CAP_COUNT;i+=2)
{
prev=g_Record[i];
next=g_Record[i+1];
if(next>=prev)
prev=next-prev;
else
prev=next+(0xffff-prev);
ir_code<<=1;
if(prev > 800)
ir_code|=1;
}
return ir_code;
}
//接收一个按键码后调用此函数以重新接收新的按键码
void ir_recv_enable(void)
{
drv_enter_critical();//程序框架提供的关中断函数
TIM1->SR1 =0;
g_RecvFlag=0;
g_Index=0;
drv_exit_critical();//程序框架提供的开中断函数
}
|
|