总是出现 excessive CPU load
源程序如下;望大神指点,不胜感激
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- code uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- code uchar seven_bit[] = {0xfe,0xfd,0xfb,0xf7}; //从左到右
- //生日快乐歌的音符频率表,不同频率由不同的延时来决定
- uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
- 212,212,106,126,159,169,190,119,119,126,159,142,159,0};
- //生日快乐歌节拍表,节拍决定每个音符的演奏长短
- uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
- 9,3,12,12,12,12,12,9,3,12,12,12,24,0};
- uchar c,temp,i;
- uint temp1,temp2;
- sbit beep = P1^1;
- sbit key = P1^2;
- sbit key1 = P1^3;
- sbit key2 = P1^4;
- sbit key3 = P1^5;
- sbit key4 = P1^6;
- sbit key5 = P2^4;
- sbit key6 = P2^5;
- sbit key7 = P2^6;
- sbit key8 = P2^7;
- sbit DQ = P1^0;
- sbit D1 = P1^7;
- void delay(uint x) //延时
- {
- while(x--);
- }
- void Init_DS18B20(void) //初始化函数
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- delay(8); //稍做延时
- DQ = 0; //单片机将DQ拉低
- delay(75); //精确延时 大于 480us ,800微秒
- DQ = 1; //拉高总线即单片机对总线电平管理权释放
- delay(14);
- x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 单片机读取DS18B20存在并相应
- delay(20);
- }
- /******************************从18B20中读一个字节****************************/
- uchar Read_OneChar(void)
- {
- uchar i = 0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给低脉冲信号即数据发送的起始信号
- dat >>= 1; //从低位到高位顺序发送数据 左移
- DQ = 1; // 给高脉冲信号
- if(DQ) //总线被拉高
- dat |= 0x80; //按位或然后赋值给dat,循环8次将每位送到dat中,完成一字节读取。
- delay(8);
- }
- return(dat);
- }
- /******************************向18B20中写一个字节****************************/
- void Write_OneChar(uchar dat)
- {
- uchar i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0; // 给低脉冲信号即单片机数据发送的起始信号 也即写周期的开始
- DQ = dat&0x01; //数据的最低位先写入
- delay(10);
- DQ = 1; //表示总线被拉高,
- dat >>= 1; //循环8次将每位送到dat中,完成一字节读取。
- }
- delay(8);
- }
- /***********************************读取温度**********************************/
- uchar Read_Temperature(void)
- { uchar a,b;
- uchar i = 0,t = 0;
- Init_DS18B20();
- Write_OneChar(0xcc); // 跳过读序号列号即ROM的操作
- Write_OneChar(0x44); // 启动温度转换
- Init_DS18B20();
- Write_OneChar(0xcc); //跳过读序号列号的操作
- Write_OneChar(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- a = Read_OneChar(); //读取温度值低位
- b = Read_OneChar(); //读取温度值高位
- c = 0x0f & a; //得到小数部分
- a = a >> 4; //低位右移4位
- b = b << 4; //高位左移4位
- t = a | b; //得到8位温度的整数部分,最高为符号位
- return(t);
- }
- /*********************************************************************/
- //读取DS18B20温度,通过数码管显示,在温度超过35度时蜂鸣器会发声-祝你生日快乐
- /*********************************************************************/
- void timer0_init(void) //初始化
- {
- TMOD = 0x01; //设置T0为工作模式1
- TH0 = 0xec;
- TL0 = 0x78; //为T0赋初值
- TR0 = 1; //启动T0
- EA = 1; //开总中断
- ET0 = 1; //开定时器中断
- }
- /*****************************************************************************/
- void timer0_isr(void) interrupt 1 //中断
- {
- uchar j,cp;
- TR0 = 0; //关闭T0
- EA = 0; //关总中断
- TH0 = 0xec;
- TL0 = 0x78; //为T0赋值
- TR0 = 1;
- EA = 1;
- cp++;
- if(cp >= 200) //刚好1秒
- {
- cp = 0;
- temp1 = Read_Temperature();//得到温度
- if((temp1 & 0x80) == 0x80) //如果温度为负值
- {
- temp2 =0x7f & ~temp1 + (0x0f & ~c) /15; //整数处理,需要加上小数来的借位
- c = 0x0f & ~c + 0x01; //小数处理
- }
- else temp2 = temp1;//如果温度为正值,不用处理
- }
- P0 = 0xff;
- switch(j)
- {
- case 0:P0 = seven_seg[c * 10/16];break;//显示小数 //正值乘以0.625就是实际温度
- case 1:P0 = 0x7f & seven_seg[temp2 % 10];break;//显示个位并加上小数点
- case 2:{
- if((temp2 < 10) && (temp1 < 0x80)){P0 = 0xff;break;}//如果温度小于10度,且为正值,十位0不显示
- if((temp1 > 0x80) && (temp2 < 10)){P0 = 0xbf;break;}//如果温度小于10度,且为负值,十位0不显示,只显示“-”
- P0 = seven_seg[temp2 / 10]; break;//如果温度大于10度,10位正常显示
- }
- case 3:{
- if((temp1 > 0x80) && ((temp2 / 10) > 0))//如果温度为负值,且十位不为0,百位显示“-”
- P0 = 0xbf;
- break;
- }
- }
- P2 = seven_bit[j];
- j++;
- if(j >= 4)
- j=0;
- }
- void PlayMusic() //播放函数
- { uint i1=0,j1,k1;
- while(SONG_LONG[i1]!=0||SONG_TONE[i1]!=0)
- { for(j1=0;j1<SONG_LONG[i1]*20;j1++) //播放各个音符,SONG_LONG为拍子长度
- {beep=~beep; //SONG_TONE延时表决定了每个音符的频率
- for(k1=0;k1<SONG_TONE[i1]/3;k1++); }
- delay(1200); i1++; }
- }
- void main(void)
- { D1=0;
- timer0_init();
- while(1)
- {
- if(temp2 >=37||key==0)
- { D1=1;
- PlayMusic();
- delay(50000); //播放完后暂停一段时间
- }
- else
- {D1=0;
- }
- if(key1==0)
- {
- temp=0x01; //8盏灯单个灭向右移
- for(i=0;i<8;i++)
- {
- P3=~temp;
- delay(10000);
- temp<<=1;
- }
- delay(200000);
- P3=0xff;//全亮
- }
-
- if(key2==0)
- {
- temp=0x80;
- for(i=0;i<8;i++)//8盏灯单个灭反向左移
- {
- P3=~temp;
- delay(10000);
- temp>>=1;
- }
- delay(200000);
- P3=0xff;//全亮
- }
- if(key3==0)
- {
- temp=0xfe;
- for(i=0;i<8;i++)//8盏灯逐个向右灭
- {
- P3=temp;
- delay(10000);
- temp<<=1;
- }
- delay(200000);
- P3=0xff;//全亮
- }
- if(key4==0)
- {
- temp=0xfe;
- for(i=0;i<8;i++)//8盏灯逐个亮向右
- {
- P3=~temp;
- delay(10000);
- temp<<=1;
- }
- delay(200000);
- P3=0xff;//全亮
- }
- if(key5==0)
- {
- temp=0x7f;
- for(i=0;i<8;i++)//8盏灯逐个灭向左
- {
- P3=temp;
- delay(10000);
- temp>>=1;
- }
- delay(200000);
- P3=0xff;//全亮
- }
- if(key6==0)
- {
- temp=0x7f;
- for(i=0;i<8;i++)//8盏灯逐个亮向左
- {
- P3=~temp;
- delay(10000);
- temp>>=1;
- }
- delay(200000);
- P3=0xff;//全亮
- }
- if(key7==0)
- {
- delay(200000);
- P3=0x55;//隔一个亮
- delay(200000);
- P3=0xaa;//隔一个亮
- delay(200000);
- P3=0xff;//全亮
- }
- if(key8==0)
- {
- delay(200000);
- P3=0x00;//全灭
- delay(200000);
- P3=0xff;//全亮
- }
- }
- }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
怎么减小啊。仿真刚开始是正常的,一会就出现那个。是不是数码管的中断造成的影响。单独运行数码管和蜂鸣器都正常啊,但是连在一起就有问题了
仿真刚开始是正常的,一会就出现那个。是不是数码管的中断造成的影响。单独运行数码管和蜂鸣器都正常啊,但是连在一起就有问题了
你上传一个全套的仿真和编译文件,我试试!
快毕业答辩了,还一直出问题,希望大神尽快指点下,我把电路图和程序都打包在下面了
一周热门 更多>