您的位置 首页 厂商

STM8输入捕获

最近在用STM8的过程中需要用到一个频率检测的功能,还好STM8S207的定时器中自带有输入捕获功能,之前还想着用定时器计数方式来实现的,但既…

最近在用STM8的过程中需求用到一个频率检测的功用,还好STM8S207的守时器中自带有输入捕获功用,之前还想着用守时器计数方法来完结的,但已然人家供给了该功用,那就试试吧,咱们硬件晒干接的是PC1引脚就只看了Timer1,其他的守时器应该也是相似的,看了材料之后发现STM8的输入捕获其实与STC12C5A60S2中的PCA捕获形式很相似,可是看材料没有后者明晰易懂。。。

在捕获形式中,基本上只用到了读进程,在STM8中有一个影子寄存器,但对于咱们来说是看不到的,咱们仅操作预装载寄存器即可。并且需求留意的是无论是计数器仍是捕获/比较寄存器都是先读/写高8位,后读/写低8位数据。

在文档中给出了一个输入捕获形式的流程

按着这个流程来就能够完结咱们的输入捕获

文档中首要说到将TIM1_CCMR1寄存器的CC1S位写01,将端口装备为输入,但在TIM1_CCMR1的寄存器中有阐明CC1S位的更改需在通道封闭时(TIM1_CCER1寄存器的CC1E=0)才可写入,

因而在装备中先将TIM1_CCER1寄存器的CC1E位写0,然后将TIM1_CCMR1的CC1S位写01,

TIM1_CCER1 &= (unsigned char)~0x01;//清零TIM1_CCER1中的CC1E位,之后才可装备TIM1_CCMR1TIM1_CCMR1 = 0x01;//装备TIM1_CCMR1中的CC1S位为1,CC1通道装备为输入,IC1映射到TI1FP1上//无滤波器、无预分频器(捕获输入口上检测到的每一个边缘都触发一次捕获)

TIM1_CCMR1寄存器有两种功用,别离对应捕获形式和比较形式,只需求捕获形式即可

滤波器是用来防止频率动摇的直接写0即可,无滤波器,分频器咱们也写00不必分频器,当然也能够运用分频器,进步准确率。

接着是设置触发方法,咱们挑选上升沿触发

TIM1_CCER1 &= (unsigned char)~0x02;//上升沿或许高电平触发

最终使能捕获功用,设置TIM1_CCER1寄存器的CC1E位=1,咱们咱们选用中止方法因而也将TIM1_IER寄存器的CC1IE方位1,答应中止请求。

完好的初始化代码如下

void signal_capture_Init(void){TIM1_CNTRH = 0x00;//清零计数器高8位TIM1_CNTRL = 0x00;//清零计数器低8位TIM1_PSCRH = 0x00;//计数器时钟分频高8位TIM1_PSCRL = 0x10;//计数器时钟分频低8位16分频TIM1_CCER1 &= (unsigned char)~0x01;//清零TIM1_CCER1中的CC1E位,之后才可装备TIM1_CCMR1TIM1_CCMR1 = 0x01;//装备TIM1_CCMR1中的CC1S位为1,CC1通道装备为输入,IC1映射到TI1FP1上//无滤波器、无预分频器(捕获输入口上检测到的每一个边缘都触发一次捕获)TIM1_CCER1 &= (unsigned char)~0x02;//上升沿或许高电平触发TIM1_IER |= 0x02;//CC1IE=1,使能捕获/比较1中止TIM1_CCER1 |= 0x01;//捕获使能TIM1_CR1 |= 0x01;//使能守时/计数器}

当产生一个输入捕获时,计数器的值被传送到TIM1_CCR1寄存器中,计时器的时钟源在程序中咱们设置为16分频

分频往后计数器的频率为1MHz,这儿选用分频主要是防止计数器溢出,这样一起也降低了精度,一起设置计数器的初值为0,计数器默许计数方法是向上计数,计到最大值后又从0开端计数,

中止处理代码如下

@far @interrupt void signal_capture_irq (void){if(TIM1_SR1&0x02){TIM1_SR1 &= (unsigned char)~0x02;//铲除CC1IF标志if(vsync_cap_data_old == 0x00){//第一次捕获中止降临vsync_cap_data_old = TIM1_CCR1H;//先读取高8位数据vsync_cap_data_old = (unsigned int)(vsync_cap_data_old<<8) + TIM1_CCR1L;//再读取低8位数据}else{//第2次捕获中止降临vsync_cap_data_new = TIM1_CCR1H;//先读取高8位数据vsync_cap_data_new = (unsigned int)(vsync_cap_data_new<<8) + TIM1_CCR1L;//再读取低8位数据TIM1_IER &= (unsigned char)~0x02;//制止通道1捕获/比较中止TIM1_CR1 &= (unsigned char)~0x01;//中止计数器if(vsync_cap_data_new > vsync_cap_data_old)vsync_period = (vsync_cap_data_new - vsync_cap_data_old);elsevsync_period = 0xFFFF + vsync_cap_data_new - vsync_cap_data_old;vsync_cap_data_old = 0x00;isCaptureOver = 1;}}}

咱们捕获两次中止核算时间差,

if(isCaptureOver){//假如捕获完结则对数据进行处理cmd_puts("period:");cmd_hex((unsigned char)(vsync_period>>8));cmd_hex((unsigned char)vsync_period);TIM1_CNTRH = 0x00;//清零计数器高8位TIM1_CNTRL = 0x00;//清零计数器低8位TIM1_IER |= 0x02;//CC1IE=1,使能捕获/比较1中止TIM1_CR1 |= 0x01;//使能守时/计数器isCaptureOver = 0;}

这儿只从串口输出了周期,成果如下

能够看到周期在一个范围内动摇咱们取一个值0x79ED来核算,它所对应的频率f=1000000/0x79ED=32.0379Hz仍是比较挨近咱们的实践输入频率30Hz,夺冠是大了些,能够经过代码持续改善

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/265811.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部