《测量两个下降沿之间的时间》由会员分享,可在线阅读,更多相关《测量两个下降沿之间的时间(10页珍藏版)》请在金锄头文库上搜索。
1、我想在通过一个 I/O 口过来的高低信号,让定时器测量两个下降沿之间的时间。 下面是我的程序,不知道为什么不进入中断,请知道的朋友多多指点,谢谢。 #include #include unsigned int FstFlag=0; /是否为第一次进入 I/O 口中断 unsigned int T0CycleCnt=0; /在两次下降沿定时器 T0 溢出次数 unsigned char HeartBeatRate=0; /心率 void BoardClk (void) /时钟设置,经过验证这个函数没有问题 int i; / delay counter OSCXCN = 0x67; / start
2、 external oscillator with / 22.1184MHz crystal for (i=0; i 1ms) while (!(OSCXCN & 0x80); / Wait for crystal osc. to settle OSCICN = 0x88; / select external oscillator as SYSCLK void T0Init(void) /定时器 T0 初始化 CKCON|=0x00; /T0 使用系统始终的 12 分频 TMOD|=0x0a; /Gate 使能,T0 为自动装载的 8 位定时器 TL0|=0x00; /初值装载 0x00 TH
3、0|=0x00; /重装载后将 0x00 加载给 TL0 TCON|=0x11; /定时器 0 开,INT0 边沿触发 void Timer0(void)interrupt 1 if(FstFlag=0) /第一个下降沿 T0Init(); T0CycleCnt+=1; if(T0CycleCnt 65535) /脉搏大于 9.102 秒/次 T0CycleCnt=0; FstFlag=1; if(FstFlag!=0) /第二个下降沿 TCON=0x10; /关定时器 HeartBeatRate=(char)(12*256*T0CycleCnt/22118400+12*TL0/2211840
4、0); void PortInit(void) XBR2|=0x40; /push-pull XBR1|=0x14; /INT0 连接到端口引脚 void PrintHeartBeatRate(void) void main(void) while(1) BoardClk(); EA=1; FstFlag=0; PortInit(); T0Init(); PrintHeartBeatRate(); 对我有用0 丢个板砖0 引用 举报 管理 TOP 回复次数:4 icesnows (逝去日子) 等级: 2#1 楼 得分: 0 回复于:2006-04-19 12:46:50void main(vo
5、id) while(1) BoardClk(); EA=1; FstFlag=0; PortInit(); T0Init(); PrintHeartBeatRate(); 你的主程序设计,时钟设置怎么能不停的调用?PortInit()和 T0Init()调用也在反复执行!这样怎么可能正常工作呢? T0 在不停的初始化! void main(void) BoardClk(); PortInit(); T0Init(); EA=1; FstFlag=0; while(1) PrintHeartBeatRate(); 感觉定时中断程序也有问题,设计似乎存在些问题,没有仔细看芯片资料,不太敢断言! 个
6、人感觉,似乎应该在外部中断 0 的服务程序里初始化、启动定时器,到第二次进外部中断时说明来了第二个下降沿,此时停止定时器,读计数值,就可以计算出时间了!而定时器只需简单计数 对我有用0 丢个板砖0 引用 举报 管理 TOP 精华推荐: 讨论 WINCE5 2440 中堆和栈的分配问题 gaoxininchina 等级: #2 楼 得分: 0 回复于:2006-04-19 14:30:40谢谢您的回复,我在仔细分析了您的建议后,把程序修改成下面的样子,但还是有点问题,请指教! #include #include unsigned int FstFlag=0; /是否为第一次进入 I/O 口中断
7、unsigned int T0CycleCnt=0; /在两次下降沿定时器 T0 溢出次数 unsigned char HeartBeatRate=0; /心率 void BoardClk (void) int i; / delay counter OSCXCN = 0x67; / start external oscillator with 22.1184MHz crystal for (i=0; i 1ms) while (!(OSCXCN & 0x80); / Wait for crystal osc. to settle OSCICN = 0x88; / select external
8、 oscillator as SYSCLK void T0Init(void) CKCON|=0x00; /T0 使用系统始终的 12 分频 TMOD|=0x0a; /Gate 使能,T0 为自动装载的 8 位定时器 TL0|=0x00; /初值装载 0x00 TH0|=0x00; /重装载后将 0x00 加载给 TL0 TCON|=0x11; /定时器 0 开,INT0 边沿触发 void Timer0(void)interrupt 1 T0CycleCnt+=1; void PortInit(void) XBR2|=0x40; /push-pull XBR1|=0x14; /INT0 连接
9、到端口引脚 void PortInt(void)interrupt 0 T0Init(); if(FstFlag%2=0) if(T0CycleCnt 65535) /心跳 9.102 秒 T0CycleCnt=0; /清零 if(FstFlag%2=1) /如果不是第一次进 I/O 口中断 TCON=0x10; /定时器 T0 关 HeartBeatRate=(char)(12*256*T0CycleCnt/22118400+12*TL0/22118400); FstFlag+=1; if(FstFlag 65535) FstFlag=0; void PrintHeartBeatRate(v
10、oid) void main(void) BoardClk(); PortInit(); EA=1; EX0=1; ET0=1; FstFlag=0; while(1) PrintHeartBeatRate(); 对我有用0 丢个板砖0 引用 举报 管理 TOP 精华推荐: 请教 ZLG7290 双边沿触发的奇怪问题 icesnows (逝去日子) 等级: 2#3 楼 得分: 0 回复于:2006-04-19 20:01:55什么问题? 说几点意见,在这种方法下,定时器完全按照普通的来用,也就是说由 TR0 和 GATE 来控制就 OK 了!外部中断服务程序也不用那么复杂,我认为应该是这样的,
11、你看看 在 T0 初始化程序里,不需要使能 TR0 void PortInt(void)interrupt 0 if (!FstFlag) /FstFlag=0,进中断表示第一个下降沿 FstFlag=1; T0Init(); TR0=1; /使能 T0 else /FstFlag=1,进中断表示第二个下降沿 FstFlag=0; TR0=0; /关定时器 HeartBeatRate=(char)(12*256*T0CycleCnt/22118400+12*TL0/22118400); 当然这样的测试,只能得出部分两个下降沿间的时间,例如下降沿编号 1 2 3 4 5 6 7,那这个程序能测试
12、出的时间是 1 和 2、3 和 4、5 和 6 之间的时间!如果你要测出每两个下降沿,实际上改起来更简单 void PortInt(void)interrupt 0 TR0=0; if (FstFlag) /FstFlag!=0,表示不是第一次来下降沿,可以计算时间 HeartBeatRate=(char)(12*256*T0CycleCnt/22118400+12*TL0/22118400); else /FstFlag=0,进中断表示第一个下降沿 FstFlag=1; T0Init(); TR0=1; /使能 T0 另外那个表示时间的数 HeartBeatRate,你强行转换成 CHAR 类型好象不太对,你要是想转换成 ASCII 码,应该分别取十位和个位,然后分别加上 0x30,你想想吧 对我有用0 丢个板砖0 引用 举报 管理 TOP 精华推荐:如何调试驱动异常?#4 楼 得分: 0 回复于:2006-04-28 11:33:54HeartBeatRate=(char)(12*256*T0CycleCnt/22118400+12*TL0/22118400); 是什么意思?这个数为什么要这样算? FlySkyFree (飞) 等级: