用STM32F107单片机的外部中断对脉冲信号计数,脉冲信号频率略高,计数就变少,为啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用STM32F107单片机的外部中断对脉冲信号计数,脉冲信号频率略高,计数就变少,为啥?相关的知识,希望对你有一定的参考价值。
这个脉冲信号为20HZ的时候,还能准确计数,但是200HZ的时候,计数变少了。STM32不可能连这么点频率的脉冲都处理不了吧,求指教
嘿嘿 俺来帮你解答用 外部中断对脉冲信号计数造成丢失脉冲的原因:
1 脉冲信号频率过高 超过外部中断对脉冲信号的处理速度
2 系统其它中断会造成影响 会延迟外部中断对脉冲信号的处理时间
3 外部中断对脉冲信号的处理程序如果比较长 执行时间也长 也会影响外部中断对脉冲信号的处理速度
建议:
1 将对脉冲信号计数的外部中断的优先级设成高级中断
2 外部中断对脉冲信号的处理程序要尽量想办法缩短
3 当然建议最好使用计数器 每当计满 才中断1次 就不会丢失脉冲了
STM32F107单片机内部可是有4个定时计数器啊
呵呵 满意就给加分吧追问
整个程序中就这一个外部中断,并无其他中断了。要说频率高,其实也不过200hz就出现了计数丢失现象,这个对于stm32来说说不过去啊。中断函数里面就对计数值counter++了,其他什么也没干。望解答
追答呵呵 为什么不用计数器啊?
按理不会的 频率不算高 硬件上脉冲传感器没问题吧
要求用这个,而且碰到问题总不能回避吧
追答那很好 你是如何判断 计数时 少了多少个脉冲的?
有准确的数值吗?
这个脉冲信号由光耦的相关电路产生。我把某滚轮转一圈,固定产生20个脉冲。如果转的不快,这20个脉冲都能被计数。如果转快了,计数就丢失了。。。加Q聊吧370276468
追答脉冲信号由光耦的相关电路产生 是你设计的吗? 有可能是硬件问题
参考技术A 公司用了这个片子做的红外遥控控制,检测红外都没啥问题。你这个情况是不是计数器已经跑溢出了。你看到的是不确定的计数。
200HZ用中断处理应该没啥问题。
你中断出了计数还有别的东西吗? 参考技术B 这个没试过,但是用外部中断计数,未免太耗单片机资源,一直中断。。不太好。。可以试试定时器。
stc89c2单片机测频
今天做了一下51单片机的测频法(给定一定的门限时间,来测频率个数),我的大体思路是用两个中断来控制,通过定时器0,来给定一个1s的门限时间,把待测信号输入到外部中断INT0(P3^2),然后通过外部中断进入的个数来确定信号的频率,即记的个数就是待测信号的脉冲。现在我把我的程序贴出来给大家参考一下
/*================================
程序名称 :测频
编者 :xxniuren
日期 :2012 11
程序目的 :用两个时钟来定时,第一个时钟是
外部中断INT0 第二个时钟是产生一个一秒的门信号
===============================*/
#include <reg52.h>
#include <lcd.h>
#define uchar unsigned char
#define uint unsigned int
uchar num,flag1,flag2;
long int count1,count2;
uint zhao,s_wan,wan,qian,bai,shi,ge;
uchar code table[] = "Pinlv";
//****************显示pinlv****************
void display()
write_com(0x80);
for(num = 0; num < 5; num++)
write_date(table[num]);
delay_1602(5);
//****************显示数字****************
void display_date(long int date)
zhao = date / 1000000;
s_wan = (date % 1000000) / 100000;
wan = (date % 100000) / 10000;
qian = (date % 10000) / 1000;
bai = (date % 1000) / 100;
shi = (date % 100) / 10;
ge = date % 10;
write_com(0xc0 + 3) ;
write_date(zhao + '0');
delay_1602(5);
write_date(s_wan + '0');
delay_1602(5);
write_date(wan + '0');
delay_1602(5);
write_date(qian + '0');
delay_1602(5);
write_date(bai + '0');
delay_1602(5);
write_date(shi + '0');
delay_1602(5);
write_date(ge + '0');
delay_1602(5);
write_date('H');
delay_1602(5);
write_date('z');
delay_1602(5);
/************
初始化外部中断
************/
void INT0_init(void)
EA = 1; // 打开全局中断
EX0 = 1; //打开外部中断0
IT0 = 1; //外部中断0触发 下降沿触发
/************
初始化定时器
************/
void timer0_init(void)
TMOD = 0x01;
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
void main()
init_lcd();
display();
timer0_init();//先开门限时间中断
INT0_init(); //后开外部触发中断
while(1)
display_date(count2);
void T0_time() interrupt 1
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
num++;
if(num == 20)
num = 0;
flag1 = 1;
void INTRPT0()interrupt 0
count1++;
if(flag1 == 1)
count2 = count1;
flag1 = 0;
count1 = 0;
这个程序相对来说容易实现,但是测频相对来说不是太准,我测的时候100hz,显示的是92hz,20khz测出来是18360hz,所以不是很准,我后来想增加测量的周期数来提高程序的精度,但是效果不是很明显。所以还是有待改善
下面把我的1602的程序也贴出来,大家可以直接拿着试一下(注意下管脚)。如果有什么好的提高频率精度的方法 希望大家指点一下,然后相互进步。。。
/*==============================================
程序名称:lcd
编者:xxniuren
日期:2012 8
程序目的:生成一个lcd的头文件 方便调用。其中程序调用方法是
初始化--定义光标坐标--使用
===============================================*/
#include <reg52.h>
#include <lcd.h>
void delay_1602(uint xms)
uint i,j;
for (i = xms; i > 0; i--)
for(j = 110; j > 0; j--) ;
void write_com(uchar com)
lcdrs= 0; //先把写命令和数据设定为写命令按钮 0位命令 1为数据 0为写 1为读
lcd_data = com; //给P0一个数据
delay_1602(5); //延时5ms
lcden = 1; //给使能一个高电平
delay_1602(5); //延时5ms
lcden = 0; //给一个低脉冲 从而把数据传上去
void write_date(uchar date)
lcdrs = 1;//写入数据选择
lcd_data = date;
delay_1602(5);
lcden = 1;//打开使能端
delay_1602(5);
lcden = 0;//给一个脉冲从而输入数据
void init_lcd()
lcden = 0;
lcdrw = 0;
write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口
write_com(0x0c);//设置开显示 不显示光标
// write_com(0x06);//写一个数据后地址指针加一
write_com(0x01);//显示清零,数据指针清零
//lcd 1602 .h
#ifndef __lcd_H__
#define __lcd_H__
#define uchar unsigned char
#define uint unsigned int
#define lcd_data P0
sbit lcden = P1^2; //使能
sbit lcdrs = P1^0; //数据命令选择引脚
sbit lcdrw = P1^1; //读写选择引脚
void delay_1602(uint xms);
void write_com(uchar com);
void write_date(uchar date);
void init_lcd();
#endif
以上是关于用STM32F107单片机的外部中断对脉冲信号计数,脉冲信号频率略高,计数就变少,为啥?的主要内容,如果未能解决你的问题,请参考以下文章
STM32f407定时器用为编码器接口模式采集脉冲,但单片机供电后,复用引脚直接有电压输出
单片机外部中断有两种信号方式,即电平方式和脉冲方式.啥叫电平方式啥叫脉冲方式