共3条
1/1 1 跳转至页
问
各位大侠:
我是新手,请多关照!我想用下面的程序测量ICP引脚上的周期,可是好象总存在问题,请高手帮我看看问题出在什么地方?谢谢,比较急!
#include<iom8v.h>
#include<math.h>
#include <macros.h>
#define osccal 0xae//内部RC校正常数
#pragma data:code
const unsigned char table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
#pragma data:data
unsigned char ledbuff[]={0,0,0,0};
unsigned int oldcount;
unsigned int newcount;
unsigned char counter;
/* 微秒级延时程序 */
void delay_us(int time)
{
do
{
time--;
}
while (time>1);
}
//动态扫描显示,使用B口传递显示数据
void display(void)
{
unsigned char i;
DDRB|=0xfe;
PORTB|=0xfe;
DDRD|=0xf0;
PORTD|=0xf0;
for(i=0;i<4;i++)
{
PORTB=ledbuff[i];
PORTD&=~(1<<(i+4));
delay_us(400);
PORTD|=0xf0;
}
}
//将COUNT 十六进制数据转换为LED 七段码
void hextobcd(unsigned int count)
{
unsigned char i;
for(i=0;i<4;i++)
{
ledbuff[i]=table[count%10];
count=count/10;
}
}
//初始化
void sys_init(void)
{
DDRB|=0xfe; //PB0不能作为输出,否则会引发中断
PORTB|=0xfe; //端口初始化
DDRD|=0xf0;
PORTD|=0xf0; //片选,低有效
TIMSK=0x20; //使能T1捕捉中断
TCCR1A=0x00;
TCCR1B=0xC2; //CK/8,捕捉周期的单位为1us
ICR1=0;
TCNT1=0;
counter=0;
}
//捕捉中断处理程序
#pragma interrupt_handler ICP_timer1:iv_TIMER1_CAPT
void ICP_timer1(void)
{
unsigned int temp;
counter++;
if(counter==2)
{
newcount=ICR1-temp;
counter=0;
ICR1=0;
temp=0;
}
//TCCR1B=0xC2;
temp=ICR1;
TCNT1=0;
}
//测量ICP引脚上的信号的周期
void main()
{ void sys_init(void);
OSCCAL=osccal; //校正振荡频率
sys_init();
SEI(); //使能全局中断
while(1)
{
if ((newcount&0xfff8)!=(oldcount&0xfff8))
{
oldcount=newcount;
}
hextobcd(oldcount);
display();
}
}
//周期我用示波器测过,很稳定的,可是测量显示值总在跳,是设置的问题吗?还是别的地方出了问题?
答 1: 使用外部振荡试试,内部rc有误差
我是新手,请多关照!我想用下面的程序测量ICP引脚上的周期,可是好象总存在问题,请高手帮我看看问题出在什么地方?谢谢,比较急!
#include<iom8v.h>
#include<math.h>
#include <macros.h>
#define osccal 0xae//内部RC校正常数
#pragma data:code
const unsigned char table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
#pragma data:data
unsigned char ledbuff[]={0,0,0,0};
unsigned int oldcount;
unsigned int newcount;
unsigned char counter;
/* 微秒级延时程序 */
void delay_us(int time)
{
do
{
time--;
}
while (time>1);
}
//动态扫描显示,使用B口传递显示数据
void display(void)
{
unsigned char i;
DDRB|=0xfe;
PORTB|=0xfe;
DDRD|=0xf0;
PORTD|=0xf0;
for(i=0;i<4;i++)
{
PORTB=ledbuff[i];
PORTD&=~(1<<(i+4));
delay_us(400);
PORTD|=0xf0;
}
}
//将COUNT 十六进制数据转换为LED 七段码
void hextobcd(unsigned int count)
{
unsigned char i;
for(i=0;i<4;i++)
{
ledbuff[i]=table[count%10];
count=count/10;
}
}
//初始化
void sys_init(void)
{
DDRB|=0xfe; //PB0不能作为输出,否则会引发中断
PORTB|=0xfe; //端口初始化
DDRD|=0xf0;
PORTD|=0xf0; //片选,低有效
TIMSK=0x20; //使能T1捕捉中断
TCCR1A=0x00;
TCCR1B=0xC2; //CK/8,捕捉周期的单位为1us
ICR1=0;
TCNT1=0;
counter=0;
}
//捕捉中断处理程序
#pragma interrupt_handler ICP_timer1:iv_TIMER1_CAPT
void ICP_timer1(void)
{
unsigned int temp;
counter++;
if(counter==2)
{
newcount=ICR1-temp;
counter=0;
ICR1=0;
temp=0;
}
//TCCR1B=0xC2;
temp=ICR1;
TCNT1=0;
}
//测量ICP引脚上的信号的周期
void main()
{ void sys_init(void);
OSCCAL=osccal; //校正振荡频率
sys_init();
SEI(); //使能全局中断
while(1)
{
if ((newcount&0xfff8)!=(oldcount&0xfff8))
{
oldcount=newcount;
}
hextobcd(oldcount);
display();
}
}
//周期我用示波器测过,很稳定的,可是测量显示值总在跳,是设置的问题吗?还是别的地方出了问题?
答 1: 使用外部振荡试试,内部rc有误差
共3条
1/1 1 跳转至页
回复
| 有奖活动 | |
|---|---|
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
| 送您一块开发板,2025年“我要开发板活动”又开始了! | |
我要赚赏金打赏帖 |
|
|---|---|
| Chaos-nano操作系统在手持式VOC检测设备上的应用被打赏¥37元 | |
| 【分享开发笔记,赚取电动螺丝刀】关于在导入第三方库lib时,wchart类型冲突的原因及解决方案被打赏¥30元 | |
| 在FireBeetle2ESP32-C5上实现温湿度检测和显示被打赏¥20元 | |
| 在FireBeetle2ESP32-C5上实现光照强度检测及显示被打赏¥21元 | |
| 以FireBeetle2ESP32-C5实现数据识读播报被打赏¥19元 | |
| 【STM32F103ZET6】14:实测STM32F1的串口输出任务的挂起与恢复功能被打赏¥27元 | |
| Chaos-nano在压力容器监控系统中的项目应用被打赏¥23元 | |
| 基于FireBeetle2ESP32-C5的WS2812B彩色灯带控制被打赏¥21元 | |
| SWM221CBT7显示开发板驱动TFT显示屏被打赏¥19元 | |
| SWM221CBT7显示开发板驱动OLED屏显示被打赏¥19元 | |
我要赚赏金
