历史上的今天
今天是:2024年11月20日(星期三)
2018年11月20日 | 带你学习STM8自带输入捕获功能
2018-11-20 来源:eefocus
最近在用STM8的过程中需要用到一个频率检测的功能,还好STM8S207的定时器中自带有输入捕获功能,之前还想着用定时器计数方式来实现的,但既然人家提供了该功能,那就试试吧,由于硬件里面接的是PC1引脚就只看了Timer1,其他的定时器应该也是类似的,看了资料之后发现STM8的输入捕获其实与STC12C5A60S2中的PCA捕获模式很类似,但是看资料没有后者清晰易懂。。。

在捕获模式中,基本上只用到了读进程,在STM8中有一个影子寄存器,但对于我们来说是看不到的,我们仅操作预装载寄存器即可。而且需要注意的是无论是计数器还是捕获/比较寄存器都是先读/写高8位,后读/写低8位数据。
在文档中给出了一个输入捕获模式的流程

[cpp] view plain copyTIM1_CCER1 &= (unsigned char)~0x02;//上升沿或者高电平触发
最后使能捕获功能,设置TIM1_CCER1寄存器的CC1E位=1,由于我们采用中断方式因此也将TIM1_IER寄存器的CC1IE位置1,允许中断请求。
完整的初始化代码如下
[cpp] view plain copyvoid 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_CCMR1
TIM1_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开始计数,
中断处理代码如下
[cpp] view plain copy@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
{
//第二次捕获中断来临
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);
else
vsync_period = 0xFFFF + vsync_cap_data_new - vsync_cap_data_old;
vsync_cap_data_old = 0x00;
isCaptureOver = 1;
}
}
}
我们捕获两次中断计算时间差,
[cpp] view plain copyif(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,误差是大了些,可以通过代码继续改进
上一篇:单片机C语言几种内存泄露总结
下一篇:单片机SPI总线时序详解
史海拾趣
|
1、我们常用的PCB介质是FR4材料的,相对空气的介电常数是4.2-4.7。这个介电常数是会随温度变化的,在0-70度的温度范围内,其最大变化范围可以达到20%。介电常数的变化会导致线路延时10%的变化,温度越高,延时越大。介电常数还会随信号频率变化,频 ...… 查看全部问答> |
|
让家电智能人声化设计不再为难——WTV语音芯片帮你提升产品性能 本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 关键词:语音芯片,语音IC,WTV芯片,家电控制 语音芯片,采用数码电子技术将纯的无任何机械的半导体集成电路(IC)去完成语音信号的存储和还原,这样一类经过存储而还原播放的语言、声 ...… 查看全部问答> |
|
关于xilinx FPGA 中嵌入的PowerPC 405 cores 的使用问题请教 我手里的开发板是xilinx公司的v2pro芯片的xupv2p开发板。 芯片是嵌入了PowerPC405 cores ; 开发板上有一个DEBUG 16针接口。 我想问一下,如何使用这个接口呢?如何调试,仿真嵌入的PowerPC 呢? 如果需要下载程序到这个里面需要什么样的下载线 ...… 查看全部问答> |
|
任职条件: 大学嵌入式、计算机、电子专业本科学历。研究生、有工作经验者、有嵌入式相关证书者优先。 英语四级以上,六级以上者优先。 精通嵌入式C语言,熟练掌握嵌入式系统架构、原理。 热爱本职工作,具有较强的团队合作精神。 诚实、 ...… 查看全部问答> |
|
2410 文档 2410自带eCC功能: ECC generator block executes the followings: 1. When MCU writes data to NAND, the ECC generator block generates ECC code. 2. When MCU reads data from NAND, the ECC generator block generates ECC code ...… 查看全部问答> |
|
linux内核完全剖析 基于0.12内核 赵炯 的 200901的 txt doc pdf 的下载版本地址 谁有就给个链接吧 谢谢了哈 嘿嘿… 查看全部问答> |
|
本帖最后由 辛昕 于 2014-12-4 00:04 编辑 这算是前面 那个 Contiki系列的续编。不过,相对来说,我觉得它比较独立。 一直以来,用GCC编程是我的习惯,只不过,那也仅限于PC上的程序。而一 ...… 查看全部问答> |




