如何解决无缘蜂鸣器频率 被数码管刷新干扰
功能:数码管时钟,整点报时。按键调整时间。
实现步骤:
1、动态刷新数码管,将DS1302寄存器中的值赋给刷新函数用来显示当前时间。
2、定时器0以10ms计时刷新数码管。
3、每小时的0分、0秒-2秒 无缘蜂鸣器响。(闹铃2秒钟)
4、通过按键调整DS1302的初始值,来更改当前时间(或闹钟时间)
遇到问题:
刷新数码管的定时器中断会影响无缘蜂鸣器的声音频率。
调试过程:
一:定时器0刷新数码管,主函数中判断时间,如果时间到就闹钟。
结果:蜂鸣器频率被数码管和按键扫描打乱。
二:另外加了一个定时器1,在main()函数中只做按键扫描,和判断当前时间是否等于闹钟时间。如果是定时器1打开。(TR1 = 1;) 否则关闭定时器1;并将定时器1的优先级高于定时器0 。
结果:发现声音频率还是会被10ms的刷新打断。
请高手点拨!
没看到你有设置中断优先级的啊。
- /*******************************************************************************
- * 实 验 名 : DS1302时钟显示试验
- * 实验说明 : 数码管显示时钟信息
- * 连接方式 : 见连接图
- * 注 意 :
- *******************************************************************************/
- #include<reg51.h>
- #include"ds1302.h"
- //#include"smg.h"
- //--定义使用的IO--//
- sbit Beep = P3^7 ;
- #define KEY P1 //8位按键
- #define DUAN_SMG P0 //数码管段选
- sbit LSA=P2^2; //数码管位选
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- //--定义全局变量--//
- unsigned char keyTime; //保存按键时间长短
- //unsigned char beepNum; //滴次数
- unsigned int beep1m; //一分钟内不在滴
- unsigned char DisplayData[8]; //用来存放要显示的8位数的值
- unsigned char SMG_CODE[17]={ //数码管显示十进制数值
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- //--声明使用到的函数--//
- void DigDisplay(); //刷新数码管
- void Delay10ms(unsigned int c); //延时函数
- void delay(unsigned int i);
- void Timer0Cofig(void); //初始化定时器0
- void Timer1Cofig(void); //初始化定时器1
- void KEY_Scan(); //扫描按键
- unsigned char IncBcdLow(unsigned char bcd);
- unsigned char IncBcdHigh(unsigned char bcd); //加时间
- unsigned char DecBcdLow(unsigned char bcd); //减时间
- unsigned char keyTimeOK(); //按键时长
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- EA=1;//打开总中断
- TMOD = 0x11; //定时器0选择工作方式1
- // //Ds1302Init(); //---初始化DS1302.写入初始值--- 注释后,断电重启不被初始化
- Timer0Cofig();
- Timer1Cofig();
- while(1)
- {
- KEY_Scan();
- if (TIME[1]==0x10&&TIME[0]<0x05)
- {
- TR1 = 1; //启动定时器0
- }else{
- TR1 = 0; //启动定时器0
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : KEY_Scan
- * 函数功能 : 扫描按键
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void KEY_Scan()
- {
- if (KEY!=0xFF)
- {
- // delay(50);
- if (KEY!=0xFF)
- {
- switch (KEY)
- {
- case(0xFE) : //返回按键K1的数据
- keyTimeOK();
-
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[0] = IncBcdLow(TIME[0]);
- Ds1302Init();
- }
- TIME[0] = IncBcdLow(TIME[0]);
- Ds1302Init();
- break;
- case(0xFD) : //返回按键K2的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[1] = IncBcdLow(TIME[1]);
- Ds1302Init();
- }
- TIME[1] = IncBcdLow(TIME[1]);
- Ds1302Init();
- break;
- case(0xFB) : //返回按键K3的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[2] = IncBcdLow(TIME[2]);
- Ds1302Init();
- }
- TIME[2] = IncBcdLow(TIME[2]);
- Ds1302Init();
- break;
- case(0xF7) : //返回按键K4的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[3] = IncBcdLow(TIME[3]);
- Ds1302Init();
- }
- TIME[3] = IncBcdLow(TIME[3]);
- Ds1302Init();
- break;
- case(0xEF) : //返回按键K5的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[0] = DecBcdLow(TIME[0]);
- Ds1302Init();
- }
- TIME[0] = DecBcdLow(TIME[0]);
- Ds1302Init();
- break;
- case(0xDF) : //返回按键K6的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[1] = DecBcdLow(TIME[1]);
- Ds1302Init();
- }
- TIME[1] = DecBcdLow(TIME[1]);
- Ds1302Init();
- break;
- case(0xBF) : //返回按键K7的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[2] = DecBcdLow(TIME[2]);
- Ds1302Init();
- }
- TIME[2] = DecBcdLow(TIME[2]);
- Ds1302Init();
- break;
- case(0x7F) : //返回按键K8的数据
- keyTimeOK();
- while (keyTime>=20&& KEY != 0xFF) //按键时间到达就快速+时间
- {
- Delay10ms(1);
- TIME[3] = DecBcdLow(TIME[3]);
- Ds1302Init();
- }
- TIME[3] = DecBcdLow(TIME[3]);
- Ds1302Init();
- break;
- default:
- break;
- }
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : Timer0Cofig
- * 函数功能 : 配置定时器
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0Cofig(void)
- {
- TH0 = 0xd8; //设置初始值,定时10MS
- TL0 = 0xf0;
- // EA = 1; //打开总中断
- ET0 = 1; //打开定时器0中断
- TR0 = 1; //启动定时器0
- }
- /*******************************************************************************
- * 函 数 名 : Timer0
- * 函数功能 : 定时器0中断函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0() interrupt 1
- {
- TH0 = 0xd8; //设置初始值,定时10MS(55536)
- TL0 = 0xf0;
- Ds1302ReadTime(); //---读取时钟信息---
- DisplayData[0] = SMG_CODE[TIME[2]/16]; //时
- DisplayData[1] = SMG_CODE[TIME[2]&0x0f];
- DisplayData[2] = 0x40;
- DisplayData[3] = SMG_CODE[TIME[1]/16]; //分
- DisplayData[4] = SMG_CODE[TIME[1]&0x0f];
- DisplayData[5] = 0x40;
- DisplayData[6] = SMG_CODE[TIME[0]/16]; //秒
- DisplayData[7] = SMG_CODE[TIME[0]&0x0f];
- DigDisplay(); // 使用数码管显示
- }
- /*******************************************************************************
- * 函 数 名 : Timer1Cofig
- * 函数功能 : 配置定时器
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer1Cofig(void)
- {
- TH1 =(65536-200)/256; //设置初始值,定时200uS(55536)
- TL1 =(65536-200)%256;
- ET1 = 1; //打开定时器0中断
- TR1 = 0; //初始化不开启定时器0
- }
- /*******************************************************************************
- * 函 数 名 : Timer1
- * 函数功能 : 定时器1中断函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer1() interrupt 3
- {
- TH1 = (65536-200)/256; //设置初始值,定时200uS(55536)
- TL1 =(65536-200)%256;
- // beep1m++;
- // if(beep1m==6000) beep1m=0;
- Beep=~Beep;
- }
- /*******************************************************************************
- * 函 数 名 : Delay10ms
- * 函数功能 : 延时函数,延时10ms
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Delay10ms(unsigned int c) //误差 0us
- {
- unsigned char a, b;
- //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
- for (;c>0;c--)
- {
- for (b=38;b>0;b--)
- {
- for (a=130;a>0;a--);
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : DigDisplay
- * 函数功能 : 使用数码管显示
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void DigDisplay()
- {
- unsigned char i;
- unsigned int j;
- for(i=0;i<8;i++)
- {
- switch(i) //位选,选择点亮的数码管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- DUAN_SMG=DisplayData[i];//发送段码
- j=50; //扫描间隔时间设定
- while(j--);
- DUAN_SMG=0x00;//消隐
- }
- }
- /*******************************************************************************
- * 函 数 名 : IncBcdLow
- * 函数功能 : 60内,以BCD码格式从低位递增
- * 输 入 : bcd(这里用于输入时间(或日期))
- * 输 出 : bcd
- *******************************************************************************/
- // /* 递增一个BCD码的高位 */
- //unsigned char IncBcdHigh(unsigned char bcd)
- //{
- // if ((bcd&0xF0) < 0x90)
- // bcd += 0x10;
- // else
- // bcd &= 0x0F;
- //
- // return bcd;
- //}
- /* 60内递增一个BCD码的低位 */
- unsigned char IncBcdLow(unsigned char bcd)
- {
- if ((bcd&0x0F) < 0x09) //加个位
- bcd += 0x01;
- else{
- bcd &= 0xF0; //加十位
- if ((bcd&0xF0) < 0x50)
- bcd += 0x10;
- else
- bcd &= 0x00;
- }
- return bcd;
- }
- ///* 递减一个BCD码的高位 */
- //unsigned char DecBcdHigh(unsigned char bcd)
- //{
- // if ((bcd&0xF0) > 0x00)
- // bcd -= 0x10;
- // else
- // bcd |= 0x90;
- //
- // return bcd;
- //}
- /* 60内递减一个BCD码的低位 */
- unsigned char DecBcdLow(unsigned char bcd)
- {
- if ((bcd&0x0F) > 0x00) //减个位
- bcd -= 0x01;
- else{
- bcd |= 0x09;
- if ((bcd&0xF0) > 0x00) //减十位
- bcd -= 0x10;
- else
- bcd |= 0x50;
- }
- return bcd;
- }
- /*******************************************************************************
- * 函 数 名 : keyTimeOK
- * 函数功能 : 按键时间长度达到200ms
- * 输 入 : 无
- * 输 出 : 1(真)
- *******************************************************************************/
- unsigned char keyTimeOK()
- {
- keyTime = 0;
- while (keyTime<20&&KEY != 0xFF) //检测按键按下时长
- {
- Delay10ms(1);
- keyTime++;
- }
-
- }
- /*******************************************************************************
- * 函 数 名 : delay
- * 函数功能 : 延时函数,延时1ms
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void delay(unsigned int i)
- {
- char j;
- for(i; i > 0; i--)
- for(j = 200; j > 0; j--);
- }
- #include<reg51.h>
- #include"ds1302.h"
- //#include"smg.h"
- //--定义使用的IO--//
- sbit Beep = P3^7 ;
- #define KEY P1 //8位按键
- #define DUAN_SMG P0 //数码管段选
- sbit LSA=P2^2; //数码管位选
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- //--定义全局变量--//
- unsigned char keyTime; //保存按键时间长短
- unsigned char DisplayData[8]; //用来存放要显示的8位数的值
- unsigned char SMG_CODE[17]={ //数码管显示十进制数值
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- //--声明使用到的函数--//
- void DigDisplay(); //刷新数码管
- void Delay10ms(unsigned int c); //延时函数
- void delay(unsigned int i);
- void Timer0Cofig(void); //初始化定时器0
- void Timer1Cofig(void); //初始化定时器1
- void KEY_Scan(); //扫描按键
- unsigned char IncBcdLow(unsigned char bcd);
- unsigned char IncBcdHigh(unsigned char bcd); //加时间
- unsigned char DecBcdLow(unsigned char bcd); //减时间
- unsigned char keyTimeOK(); //按键时长
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- EA=1;//打开总中断
- TMOD = 0x11; //定时器0选择工作方式1
- // //Ds1302Init(); //---初始化DS1302.写入初始值--- 注释后,断电重启不被初始化
- Timer0Cofig();
- Timer1Cofig();
- while(1)
- {
- KEY_Scan();
- if (TIME[1]==0x10&&TIME[0]<0x05)
- {
- TR1 = 1; //启动定时器0
- }else{
- TR1 = 0; //启动定时器0
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : Timer0Cofig
- * 函数功能 : 配置定时器
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0Cofig(void)
- {
- TH0 = 0xd8; //设置初始值,定时10MS
- TL0 = 0xf0;
- ET0 = 1; //打开定时器0中断
- TR0 = 1; //启动定时器0
- }
- /*******************************************************************************
- * 函 数 名 : Timer0
- * 函数功能 : 定时器0中断函数
- *******************************************************************************/
- void Timer0() interrupt 1
- {
- TH0 = 0xd8; //设置初始值,定时10MS(55536)
- TL0 = 0xf0;
- Ds1302ReadTime(); //---读取时钟信息---
- DisplayData[0] = SMG_CODE[TIME[2]/16]; //时
- DisplayData[1] = SMG_CODE[TIME[2]&0x0f];
- DisplayData[2] = 0x40;
- DisplayData[3] = SMG_CODE[TIME[1]/16]; //分
- DisplayData[4] = SMG_CODE[TIME[1]&0x0f];
- DisplayData[5] = 0x40;
- DisplayData[6] = SMG_CODE[TIME[0]/16]; //秒
- DisplayData[7] = SMG_CODE[TIME[0]&0x0f];
- DigDisplay(); // 使用数码管显示
- }
- /*******************************************************************************
- * 函 数 名 : Timer1Cofig
- * 函数功能 : 配置定时器
- *******************************************************************************/
- void Timer1Cofig(void)
- {
- TH1 =(65536-200)/256; //设置初始值,定时200uS(55536)
- TL1 =(65536-200)%256;
- ET1 = 1; //打开定时器0中断
- TR1 = 0; //初始化不开启定时器0
- }
- /*******************************************************************************
- * 函 数 名 : Timer1
- * 函数功能 : 定时器1中断函数
- *******************************************************************************/
- void Timer1() interrupt 3
- {
- TH1 = (65536-200)/256; //设置初始值,定时200uS(55536)
- TL1 =(65536-200)%256;
- Beep=~Beep;
- }
- #include<reg51.h>
- #include"ds1302.h"
- //#include"smg.h"
- //--定义使用的IO--//
- sbit Beep = P3^7 ;
- #define KEY P1 //8位按键
- #define DUAN_SMG P0 //数码管段选
- sbit LSA=P2^2; //数码管位选
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- //--定义全局变量--//
- unsigned char keyTime; //保存按键时间长短
- unsigned char DisplayData[8]; //用来存放要显示的8位数的值
- unsigned char SMG_CODE[17]={ //数码管显示十进制数值
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- //--声明使用到的函数--//
- void DigDisplay(); //刷新数码管
- void Delay10ms(unsigned int c); //延时函数
- void delay(unsigned int i);
- void Timer0Cofig(void); //初始化定时器0
- void Timer1Cofig(void); //初始化定时器1
- void KEY_Scan(); //扫描按键
- unsigned char IncBcdLow(unsigned char bcd);
- unsigned char IncBcdHigh(unsigned char bcd); //加时间
- unsigned char DecBcdLow(unsigned char bcd); //减时间
- unsigned char keyTimeOK(); //按键时长
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- EA=1;//打开总中断
- TMOD = 0x11; //定时器0选择工作方式1
- // //Ds1302Init(); //---初始化DS1302.写入初始值--- 注释后,断电重启不被初始化
- Timer0Cofig();
- Timer1Cofig();
- while(1)
- {
- KEY_Scan();
- if (TIME[1]==0x10&&TIME[0]<0x05)
- {
- TR1 = 1; //启动定时器0
- }else{
- TR1 = 0; //启动定时器0
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : Timer0Cofig
- * 函数功能 : 配置定时器
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0Cofig(void)
- {
- TH0 = 0xd8; //设置初始值,定时10MS
- TL0 = 0xf0;
- ET0 = 1; //打开定时器0中断
- TR0 = 1; //启动定时器0
- }
- /*******************************************************************************
- * 函 数 名 : Timer0
- * 函数功能 : 定时器0中断函数
- *******************************************************************************/
- void Timer0() interrupt 1
- {
- TH0 = 0xd8; //设置初始值,定时10MS(55536)
- TL0 = 0xf0;
- Ds1302ReadTime(); //---读取时钟信息---
- DisplayData[0] = SMG_CODE[TIME[2]/16]; //时
- DisplayData[1] = SMG_CODE[TIME[2]&0x0f];
- DisplayData[2] = 0x40;
- DisplayData[3] = SMG_CODE[TIME[1]/16]; //分
- DisplayData[4] = SMG_CODE[TIME[1]&0x0f];
- DisplayData[5] = 0x40;
- DisplayData[6] = SMG_CODE[TIME[0]/16]; //秒
- DisplayData[7] = SMG_CODE[TIME[0]&0x0f];
- DigDisplay(); // 使用数码管显示
- }
- /*******************************************************************************
- * 函 数 名 : Timer1Cofig
- * 函数功能 : 配置定时器
- *******************************************************************************/
- void Timer1Cofig(void)
- {
- TH1 =(65536-200)/256; //设置初始值,定时200uS(55536)
- TL1 =(65536-200)%256;
- ET1 = 1; //打开定时器0中断
- TR1 = 0; //初始化不开启定时器0
- }
- /*******************************************************************************
- * 函 数 名 : Timer1
- * 函数功能 : 定时器1中断函数
- *******************************************************************************/
- void Timer1() interrupt 3
- {
- TH1 = (65536-200)/256; //设置初始值,定时200uS(55536)
- TL1 =(65536-200)%256;
- Beep=~Beep;
- }
请前辈指点一二~~~~
#include<reg51.h>
#include"ds1302.h"
//#include"smg.h"
//--定义使用的IO--//
sbit Beep = P3^7 ;
#define KEY P1 //8位按键
#define DUAN_SMG P0 //数码管段选
sbit LSA=P2^2; //数码管位选
sbit LSB=P2^3;
sbit LSC=P2^4;
//--定义全局变量--//
unsigned char keyTime; //保存按键时间长短
unsigned char DisplayData[8]; //用来存放要显示的8位数的值
unsigned char SMG_CODE[17]={ //数码管显示十进制数值
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//--声明使用到的函数--//
void DigDisplay(); //刷新数码管
void Delay10ms(unsigned int c); //延时函数
void delay(unsigned int i);
void Timer0Cofig(void); //初始化定时器0
void Timer1Cofig(void); //初始化定时器1
void KEY_Scan(); //扫描按键
unsigned char IncBcdLow(unsigned char bcd);
unsigned char IncBcdHigh(unsigned char bcd); //加时间
unsigned char DecBcdLow(unsigned char bcd); //减时间
unsigned char keyTimeOK(); //按键时长
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
EA=1;//打开总中断
TMOD = 0x11; //定时器0选择工作方式1
// //Ds1302Init(); //---初始化DS1302.写入初始值--- 注释后,断电重启不被初始化
Timer0Cofig();
Timer1Cofig();
while(1)
{
KEY_Scan();
if (TIME[1]==0x10&&TIME[0]<0x05)
{
TR1 = 1; //启动定时器0
}else{
TR1 = 0; //启动定时器0
}
}
}
/*******************************************************************************
* 函 数 名 : Timer0Cofig
* 函数功能 : 配置定时器
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Cofig(void)
{
TH0 = 0xd8; //设置初始值,定时10MS
TL0 = 0xf0;
ET0 = 1; //打开定时器0中断
TR0 = 1; //启动定时器0
}
/*******************************************************************************
* 函 数 名 : Timer0
* 函数功能 : 定时器0中断函数
*******************************************************************************/
void Timer0() interrupt 1
{
TH0 = 0xd8; //设置初始值,定时10MS(55536)
TL0 = 0xf0;
Ds1302ReadTime(); //---读取时钟信息---
DisplayData[0] = SMG_CODE[TIME[2]/16]; //时
DisplayData[1] = SMG_CODE[TIME[2]&0x0f];
DisplayData[2] = 0x40;
&