完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
例如:使用定时器进行一分钟的定时,然后在数码管上显示时,分,秒,然后每到1分钟蜂鸣器会报警3声.
当我进行蜂鸣器的延时时,数码管的动态扫描会暂停我所延时的时间.(单片机现象数码管在蜂鸣器响的时候不显示) 所以问一下大家有什么好的解决方法,谢谢.稍后上传我的源代码. 再次感谢! |
|
相关推荐
38个回答
|
|
云汉达人
单片机程序,数码管扫描显示,及计时 可以用一个定时器中断来完成, 比如 8 个数码管 定时器用 2 ~ 2.5 mS,每次中断 刷新 一个数码管,同时可以 设置一个标志位 在主程序 中记录中断 次数作为 定时 或者 延时, 如 2.5mS 40次 就是 100mS,如果计时精度 要求高的 可以另外 用一个定时器, 学会使用定时器,很多问题很好解决的。 |
|
|
|
云汉达人
本帖最后由 LiuYang 于 2016-10-26 10:55 编辑 如果可以外接芯片,用8574之类的就可以了,不占用MCU资源; 或者MCU上小系统,线程延时就可以了。如果不想上系统就用定时器中断吧。 |
|
|
|
云汉达人
本帖最后由 SingleYork 于 2016-10-26 10:55 编辑 哎哟,蜂鸣器的延时也用定时器去实现不就好了么?不要用延时函数,延时函数是会在那死延时!你既然会用定时器实现时、分、秒计时,那这个蜂鸣器延时还能难住你? |
|
|
|
数码管扫描用定时器中断控制状态机,一次扫描显示一位,不要直接在主程序里面扫描延时显示
|
|
|
|
本帖最后由 Suwian 于 2016-10-26 11:38 编辑
SingleYork 发表于 2016-10-26 10:53谢谢你啊不过,蜂鸣器的响3声的程序不是这样写的吗 void T1_Time() interrupt 3 { TH1=(65536-50000)/10; TL1=(65536-50000)%10; num1++; if(num1==20) { num1==0; num2++; if(num2==60) { num2=0; for(i=3;i>0;i--) { fm = 0; delay(100); fm = 1; delay(100); } } } } 我说的冲突是上面那个delay延时与数码管的动态扫描冲突 |
|
|
|
Suwian 发表于 2016-10-26 11:04 uint i= 3; while(i--) { fm = 0; delay(100); fm = 1; delay(100); } i = 3 |
|
|
|
|
|
|
|
楼主现在在外面,等回去把原程序贴下,谢谢大家!
|
|
|
|
本帖最后由 Suwian 于 2016-10-26 11:35 编辑
独行客 发表于 2016-10-26 10:57那要如何把延时程序不影响主函数对数码管的扫描呢,我试过用两个定时器分别控制两个中端定0控制数码管的时分秒显示,定1控制蜂鸣器每1分钟响3声。void T1_Time() interrupt 3 { TH1=(65536-50000)/10; TL1=(65536-50000)%10; num1++; if(num1==20) { num1=0; num2++; if(num2==60) { num2=0; for(i=3;i>0;i--) { fm = 0; delay(100); fm = 1; delay(100); } } } } |
|
|
|
#include
#define uchar unsigned char #define uint unsigned int ***it dula=P2^6; ***it wela=P2^7; ***it fm = P2^3; uchar shi,ge,f_shi,f_ge,s_shi,s_ge,num,num1,num2,val; uchar CLK,MIN; uchar i=3; uchar code table[]={ 0x3F, //"0" 0x06, //"1" 0x5B, //"2" 0x4F, //"3" 0x66, //"4" 0x6D, //"5" 0x7D, //"6" 0x07, //"7" 0x7F, //"8" 0x6F //"9" }; void delay(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void display1(uchar shi,uchar ge) { P0=0xfe; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0xfd; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void display2(uchar shi,uchar ge) { P0=0xf7; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0xef; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void display3(uchar shi,uchar ge) { P0=0xbf; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0x7f; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void SFM() { if(num==20) { num=0; val++; if(val==60) { val=0; MIN++; // while(i--) // { // fm=0; // delay(100); // fm=1; // delay(100); // // } // i=3; // if(MIN==60) { MIN=0; CLK++; if(CLK==1) CLK=0; } } shi = val/10; ge = val%10; f_shi = MIN/10; f_ge = MIN%10; s_shi = CLK/10; s_ge = CLK%10; } } void main() { TMOD=0x11; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1=(65536-50000)/256; TL1=(65536-50000)%256; EA=1; ET0=1; ET1=1; TR1=1; TR0=1; while(1) { SFM(); display3(shi,ge); display2(f_shi,f_ge); display1(s_shi,s_ge); } } void T0_Time() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++; //num1++; } void T1_Time() interrupt 3 { TH1=(65536-50000)/256; TL1=(65536-50000)%256; num1++; if(num1==20) { num1=0; num2++; if(num2==60) { num2=0; while(i--) { fm=0; delay(100); fm=1; delay(100); } i=3; } } } |
|
|
|
SingleYork 发表于 2016-10-26 10:53 #include #define uchar unsigned char #define uint unsigned int ***it dula=P2^6; ***it wela=P2^7; ***it fm = P2^3; uchar shi,ge,f_shi,f_ge,s_shi,s_ge,num,num1,num2,val; uchar CLK,MIN; uchar i=3; uchar code table[]={ 0x3F, //"0" 0x06, //"1" 0x5B, //"2" 0x4F, //"3" 0x66, //"4" 0x6D, //"5" 0x7D, //"6" 0x07, //"7" 0x7F, //"8" 0x6F //"9" }; void delay(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void display1(uchar shi,uchar ge) { P0=0xfe; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0xfd; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void display2(uchar shi,uchar ge) { P0=0xf7; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0xef; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void display3(uchar shi,uchar ge) { P0=0xbf; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0x7f; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void SFM() { if(num==20) { num=0; val++; if(val==60) { val=0; MIN++; // while(i--) // { // fm=0; // delay(100); // fm=1; // delay(100); // // } // i=3; // if(MIN==60) { MIN=0; CLK++; if(CLK==1) CLK=0; } } shi = val/10; ge = val%10; f_shi = MIN/10; f_ge = MIN%10; s_shi = CLK/10; s_ge = CLK%10; } } void main() { TMOD=0x11; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1=(65536-50000)/256; TL1=(65536-50000)%256; EA=1; ET0=1; ET1=1; TR1=1; TR0=1; while(1) { SFM(); display3(shi,ge); display2(f_shi,f_ge); display1(s_shi,s_ge); } } void T0_Time() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++; //num1++; } void T1_Time() interrupt 3 { TH1=(65536-50000)/256; TL1=(65536-50000)%256; num1++; if(num1==20) { num1=0; num2++; if(num2==60) { num2=0; while(i--) { fm=0; delay(100); fm=1; delay(100); } i=3; } } } |
|
|
|
我想你应该这样实现,把蜂鸣器的响的时间做一个基数,然后一分钟等于1/基数,这样就是你中断的时间,你在定时器里设置这个时间,检测时间是不是到了,到了以后蜂鸣器响,然后判断蜂鸣器响的次数,这样没进一次中断检测一下蜂鸣器并耗不了多少时间的,
响三次需要翻转电平六次,这样变量等于六的时候蜂鸣器不响,到了一分钟变量置0就可以了!不理解的话晚上给你代码 |
|
|
|
瞎折腾 发表于 2016-10-26 12:28 你好,我还是不太理解这个意思,之前我有想过用翻转电平的方法,但是不知道要怎么实现,如果可以的话教一下我。谢谢! |
|
|
|
本帖最后由 MOP 于 2016-10-26 15:43 编辑
嗨,最簡單的方式可參考我的文章http://www.icxbk.com/community/http://www.icxbk.com/community/forum.php?mod=viewthread&tid=67282&extra= 概念是一樣的,使用到TimeDisplay這個變數翻轉時候觸發一次,即1秒,這觸發是由RTC的ISR來的,只要一個定時器就可完成不中斷時鐘和持續N秒的蜂鳴器鳴叫 所以您要改的話,一樣有關I/O的最好還是宣告成volatile,再來因為您要蜂鳴器鳴叫也是以秒為最小單位(假設),所以一樣ˋ只要一個定時器 volatile uchar num;您的Code Interrupt中遞增的是num變數 void T0_Time() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++; }所以只要保留這個Interrupt,要實現您的功能,參考我的文章以後,增加以下 uchar beeper = 0; //global uchar started=0; //global #define BEEPER(x) //要控制的GPIO Output Pin,假設0輸出低電位,1輸出高電位 #define ALARM_TIME 3 void alarm(void) { if(MIN>0 && val==0) // When booting up, the beeper didn't need to beep. { if(!started) started=1; } if(started && val==0) { if(!beeper) beeper=1; } if(beeper) { if(val說明也可參考我的文章,您只要實現BEEPER函式即可,這裡我用Macro,您可以自己定義哪個腳位跟實現輸出,另外變數名稱最好有意義跟小寫,#define才大寫,培養好的寫程式習慣很重要:) 最後加入您的While loop即可 while(1) { SFM(); display3(shi,ge); display2(f_shi,f_ge); display1(s_shi,s_ge); alarm(); } |
|
|
|
本帖最后由 Suwian 于 2016-10-26 21:22 编辑
MOP 发表于 2016-10-26 14:32谢谢您的帮忙解答,我先消化理解一下!我把你给我的那些代码加入到程序里了,但是蜂鸣器没有发出声音,我的芯片是STC89C52的,我是初学者所以对于一些概念性的东西可能理解的不是很透彻, |
|
|
|
|
|
|
|
本帖最后由 Suwian 于 2016-10-26 21:28 编辑
MOP 发表于 2016-10-26 21:21这样修改后蜂鸣器没有声音是为什么? #include #define uchar unsigned char #define uint unsigned int #define BEEPER(x) //要控制的GPIO Output Pin,假設0輸出低電位,1輸出高電位 #define ALARM_TIME 3 ***it dula=P2^6; ***it wela=P2^7; ***it fm = P2^3; uchar beeper = 0; //global uchar started=0; //global volatile uchar shi,ge,f_shi,f_ge,s_shi,s_ge,num,num1,num2,val; uchar CLK,MIN; uchar code table[]={ 0x3F, //"0" 0x06, //"1" 0x5B, //"2" 0x4F, //"3" 0x66, //"4" 0x6D, //"5" 0x7D, //"6" 0x07, //"7" 0x7F, //"8" 0x6F //"9" }; void delay(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void display1(uchar shi,uchar ge) { P0=0xfe; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0xfd; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void display2(uchar shi,uchar ge) { P0=0xf7; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0xef; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void display3(uchar shi,uchar ge) { P0=0xbf; wela=1; wela=0; P0=table[shi]; dula=1; dula=0; delay(3); P0=0x7f; wela=1; wela=0; P0=table[ge]; dula=1; dula=0; delay(3); } void SFM() { if(num==20) { num=0; val++; if(val==60) { val=0; MIN++; if(MIN==60) { MIN=0; CLK++; if(CLK==1) CLK=0; } } shi = val/10; ge = val%10; f_shi = MIN/10; f_ge = MIN%10; s_shi = CLK/10; s_ge = CLK%10; } } void alarm(void) { if(MIN>0 && val==0) // When booting up, the beeper didn't need to beep. { if(!started) started=1; } if(started && val==0) { if(!beeper) beeper=1; } if(beeper) { if(val BEEPER(1); else { BEEPER(0); beeper=0; } } } void main() { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; // TH1=(65536-50000)/256; //TL1=(65536-50000)%256; EA=1; ET0=1; // ET1=1; // TR1=1; TR0=1; while(1) { SFM(); display3(shi,ge); display2(f_shi,f_ge); display1(s_shi,s_ge); alarm(); } } void T0_Time() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++; } |
|
|
|
Suwian 发表于 2016-10-26 13:18如果是十六位重装可以定时5毫秒,一秒就是二百次,这个定时也就是你蜂鸣器要一次响5毫秒 u8 fmq; 进入一秒的时候 fmq=0; 在中断的最后加上 if (fmq<7) {fm=~fm; } else {fmq=7;//这是为了怕你定时短的话,fmq会最后自动加到255后归0. } 这样每秒就会fmq=0一次,fm的电平就会翻转,每次定时器进入中断主要fmq的值小于7,电平就会翻转一次,六次以后就不翻转了! |
|
|
|
本帖最后由 MOP 于 2016-10-26 22:13 编辑
Suwian 发表于 2016-10-26 21:27噗,我文章有提醒您要自己定義Beeper的PIN腳位設置成GPIO輸出,因為我看你的Code似乎沒看到Beeper的定義腳位,記得要設置成Push-pull Output 假設Beeper接在P30腳位 那麼 ***it P30 = P3^0; #define BEEPER(X) ((X)? P30=1:P30=0) |
|
|
|
只有小组成员才能发言,加入小组>>
1182 浏览 0 评论
1359 浏览 1 评论
2798 浏览 5 评论
3088 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
3022 浏览 6 评论
561浏览 2评论
272浏览 1评论
401浏览 1评论
300浏览 1评论
321浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-6-19 04:39 , Processed in 1.555867 second(s), Total 112, Slave 93 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191