STM8自带输入捕获功能学习

发布者:Bby1978最新更新时间:2020-08-05 来源: elecfans关键字:STM8  输入捕获功能  频率检测 手机看文章 扫描二维码
随时随地手机看文章

  最近在用STM8的过程中需要用到一个频率检测的功能,还好STM8S207的定时器中自带有输入捕获功能,之前还想着用定时器计数方式来实现的,但既然人家提供了该功能,那就试试吧,由于硬件里面接的是PC1引脚就只看了TImer1,其他的定时器应该也是类似的,看了资料之后发现STM8的输入捕获其实与STC12C5A60S2中的PCA捕获模式很类似,但是看资料没有后者清晰易懂。。。

  STM8自带输入捕获功能学习

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

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

  STM8自带输入捕获功能学习

  按着这个流程来就可以完成我们的输入捕获

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

  因此在配置中先将TIM1_CCER1寄存器的CC1E位写0,然后将TIM1_CCMR1的CC1S位写01,

  [cpp] view plain copyTIM1_CCER1 &= (unsigned char)~0x01;//清零TIM1_CCER1中的CC1E位,之后才可配置TIM1_CCMR1

  TIM1_CCMR1 = 0x01;//配置TIM1_CCMR1中的CC1S位为1,CC1通道配置为输入,IC1映射到TI1FP1上

  //无滤波器、无预分频器(捕获输入口上检测到的每一个边沿都触发一次捕获)

  TIM1_CCMR1寄存器有两种功能,分别对应捕获模式和比较模式,只需要捕获模式即可

  STM8自带输入捕获功能学习

  滤波器是用来避免频率波动的直接写0即可,无滤波器,分频器我们也写00不用分频器,当然也可以使用分频器,提高准确率。

  接着是设置触发方式,我们选择上升沿触发

  STM8自带输入捕获功能学习

  [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分频

  STM8自带输入捕获功能学习

  分频过后计数器的频率为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;

  }

  这里只从串口输出了周期,结果如下

  STM8自带输入捕获功能学习

  可以看到周期在一个范围内波动我们取一个值0x79ED来计算,它所对应的频率f=1000000/0x79ED=32.0379Hz还是比较接近我们的实际输入频率30Hz,误差是大了些,可以通过代码继续改进


关键字:STM8  输入捕获功能  频率检测 引用地址:STM8自带输入捕获功能学习

上一篇:STM8单片机rtc时钟代码分享
下一篇:stm8串口接收中断程序理解及应用

推荐阅读最新更新时间:2024-11-12 13:49

STM8 外设时钟门控
关闭未使用外设的时钟可使STM8降低功耗。外设的时钟门控(PCG)模式使用户可在运行模式下随时打开或关闭fMASTER与下列外设的连接: ADC I2C AWU(寄存器时钟,而非计数器时钟) SPI TIM UART CAN(寄存器时钟,而非CAN时钟) STM8系统复位后,所有外设时钟均处于开的状态。用户可通过清除CLK_PCKENR1或CLK_PCKENR2中的PCKEN位来关闭相应的外设时钟。但是在关闭外设的时钟前,用户必须设置相应的位禁用该外设。 为了使能一个外设,用户必须先设置寄存器CLK_PCKENR中对应的PCKEN位,然后设置外设控制寄存器中的外设使能位。 AWU计数器是由独立于fMASTER的内
[单片机]
STM8使用----STVD(COSMIC)定义变量指定其类型和位定义
STM8使用----STVD(COSMIC)定义变量指定其类型和位定义 http://www.51hei.com/bbs/dpj-31009-1.html (出处: 单片机论坛) stm8 stvd下 near等于51的xdata tiny等于51的idata 如何分配变量到指定的地址 举例: unsigned char temp_A@0x00; //定义无符号变量temp_A,强制其地址为0x00 unsigned char temp_B@0x100; //定义无符号变量temp_B,强制其地址为0x100 @tiny unsigned char temp_C; //定义无符号变量temp_C,由编译器自动在
[单片机]
<font color='red'>STM8</font>使用----STVD(COSMIC)定义变量指定其类型和位定义
STM8 STM8S208MB寄存器
引脚类型 寄存器 STM8S208MB寄存器采用LQFP80封装,此处的80就表示都会 有80个引脚,其中68个引脚是GPIO。按 GPIO 端口功能分类,依次是 PA 组GPIO端口有6个(PA1-PA6) PB 组GPIO端口有8个(PB0-PB7) PC 组GPIO端口有8个(PC0-PC7) PD 组GPIO端口有8个(PD0-PD7) PE 组GPIO端口有8个(PE0-PE7) PF 组GPIO端口有6个(PF0,PF3-PF7) PG 组GPIO端口有8个(PG0-PG7) PH 组GPIO端口有8个(PH0-PH7) PI 组GPIO端口有8个(PI0-PI7) STM8S208MB 每一个端口寄存器位驱
[单片机]
<font color='red'>STM8</font> STM8S208MB寄存器
基于STM8主控的物美价廉的毫欧表设计
主控采用STM8单片机,测量使用开尔文接法,测量精度与系统使用电阻精度精度有很大关系,使用高精度电阻可以大大提高测量精度,下载程序后即可使用。
[单片机]
基于<font color='red'>STM8</font>主控的物美价廉的毫欧表设计
使用STM8驱动温湿度传感器DHT11的代码实现
最近希望恢复性学习一下 STM8 的相关知识,于是我选择了从头开始写温湿度传感器 DHT11 驱动代码的方式。其中遇到一些问题,也有一些收获,希望会帮助到遇到类似问题的朋友,也希望不足之处得到大家的指导。 首先介绍一下 DHT11 的必要知识 一 复位时序 以及 数据时序 下面是数据时序 此外,根据数据手册得知,一次通信需要的时间是 3 毫秒左右,这很重要,在后面的 BUG 分析环节会说到 二 贴上关键代码以及分析 // 复位 DHT11 voidDHT11_RST() { TIM4_CR1=0x00;// 关闭定时器 TIM4_CNTR=0;// 保证下次的第一个数据位的准确 DATA_
[单片机]
使用<font color='red'>STM8</font>驱动温湿度传感器DHT11的代码实现
新版IAR调试查看寄存器问题 STM8代码大小优化问题
今天写两个后台问的较多的问题,如标题所示: 1.新版IAR调试查看寄存器问题; 2.STM8代码大小优化问题; 1新版IAR调试查看寄存器问题 从去年上半年开始,IAR将各开发环境逐渐进行了大升级,首先是将EWARM从V7升级到了V8。然后,陆续将EW430、EWAVR等进行了升级。 什么是新版IAR?图标是黑色那种,如EWARM V8.2、 EWSTM8 V3.1。如下图: 老版本IAR,扳手工具图标。如下图: 许多小伙伴安装了新版的IAR,不管是EWARM、EW430还是EWSTM8,都出现了一个问题:调试时,“不能”查看外设寄存器了。 如下面动画,查看了各主菜单,以及View视图各个子菜单,都没有
[单片机]
新版IAR调试查看寄存器问题 <font color='red'>STM8</font>代码大小优化问题
STM8 SPI 例程 通信出错
这个STM8的SPI通信也够奇葩的,跟STM32有大区别。光判断发送空和接收空的标志还不行,还必须判断忙标志位,而且读数的时候要等忙标志完毕才能读,废话少说上代码: 这是一段发2字节收2字节的代码,注意如果第二个字节接收才有效的话,也需要发送第二个字节才能提供时钟进行接收: GPIO_WriteLow(GPIOA, GPIO_PIN_3); while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET){} SPI_SendData(0x80 | 0x75); while(SPI_GetFlagStatus(SPI_FLAG_BSY) == SET){}
[单片机]
STM8读取AD值偶尔跳变出错的问题
在调试STM8S103K3T6的AD功能时,发现当温度快速变化时(吹风机模拟),读取到的AD值会偶尔出现跳变,出现的位置相对固定;AD时钟设为2Mhz,每100ms采集一次,单次单路采集,通道无切换,用示波器看供电电压和AD口电压都没有毛刺等跳变,可以排除外部器件的问题;后来查看手册发现问题,DRH/DRL数据的左对齐和右对齐方式,对应不同的读取顺序 我使用的右对齐,把程序改成先读DRL,再读DRH,问题解决
[单片机]
<font color='red'>STM8</font>读取AD值偶尔跳变出错的问题
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved