普中开源电子分享网

 找回密码
 立即注册
搜索
查看: 3347|回复: 2

[已解决] 蜂鸣器和数码管的问题

 关闭 [复制链接]

2

主题

3

帖子

24

积分

新手上路

Rank: 1

积分
24
发表于 2020-1-3 13:04:39 | 显示全部楼层 |阅读模式
大神们,求解,怎么能做到蜂鸣器放音乐的同时数码管能显示温度,

小弟做了一个测温度的,高于19.5度就报警,现在这个程序能用了,按键能中断。但是蜂鸣器声音难听,给它放一段音乐进去,播音乐时,数码管不显示。也不能中断程序了

#include "reg52.h" //此文件中定义了单片机的一些特殊功能
#include "temp.h"
typedef unsigned long int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P1^5;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit led=P2^0;
sbit KEY=P3^2;
char num=0;
int temp;
u8 DisplayData[8];
u8 Count = 0;
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
u8 code smgquan[10]={0x40,0x04,0x08,0x10,0x00};

void dela(uint i)
{uint k;
for(k=0;k<i;k++);
}
void delay(unsigned int del)
{
        uint i,j;
        for(i=0; i<del; i++)
        for(j=0; j<1827; j++)   
        ;
}
void datapross(int temp)  //测量温度函数
{
           float tp;  
        if(temp< 0)                                //当温度值为负数
          {
                DisplayData[0] = 0x40;           //   -显示负号
                //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;        
                //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
                //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
                //算加上0.5,还是在小数点后面。

          }
        else
          {                        
                DisplayData[0] = 0x00;
                tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
                //如果温度是正的那么,那么正数的原码就是补码它本身
                temp=tp*0.0625*100+0.5;        
                //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
                //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
                //算加上0.5,还是在小数点后面。
        }
        DisplayData[1] = smgduan[temp / 10000];
        DisplayData[2] = smgduan[temp % 10000 / 1000];
        DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;
        DisplayData[4] = smgduan[temp % 100 / 10];
        DisplayData[5] = smgduan[temp % 10];
       
                if(temp<1950)           //如果小于19.5度,启动报警
       
        {        beep=0;
                beep=~beep;
                dela(1);
                beep=~beep;
                dela(1);
        }
}


void DigDisplay()
{
        u8 i;

        for(i=0;i<6;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 位
                        }
                        P0=DisplayData[i];//发送数据
                        dela(10); //间隔一段时间扫描
                        P0=0x00;//消隐
                }
}                                                               



void Time0_Init()
{
        TMOD = 0x01;          //定时器0选用方式1
        TH0  = 0x4c;          //初值的计算
        TL0  = 0x00;       
        TR0 = 1;                  //启动定时器
        ET0 = 1;                  //打开定时器中断允许位
}
                                                                                 
void Time0_Int() interrupt 1
{
        TH0 = 0x4c;
        TL0 = 0x00;
        Count++;                        //长度加1
}

void cbh1()
{        u8 t=0;
        uint i = 0;
        Time0_Init();
        EA = 1;                //打开总中断
for(t=0;t<16;t++)                        //延时15秒左右
                {P0 = smgquan[t % 4];
                delay(100);          //取 i 的个位
                if(Count == 20)                    //当Count为 20 时,i 自加一次,20 * 50MS = 1S
                {
                        Count = 0;

                        i++;               
                }
                                P0=0x00;                                               
                                DigDisplay();//数码管显示函数
                }
       
}

void cbh3()
{        u8 t=0;
        uint i = 0;
for(t=0;t<16;t++)          //延时15秒左右
                {P0 = smgquan[t % 4];
                delay(100);          //取 i 的个位
                if(Count == 20)                    //当Count为 20 时,i 自加一次,20 * 50MS = 1S
                {
                        Count = 0;

                        i++;               
                }
                                P0=0x00;                                               
                                DigDisplay();//数码管显示函数
                                delay(1);
                }
       
}

void Outside_Init(void)
{
        IT0 = 1;  //负边沿触发
        EX0 = 1;  //外部中断0允许
}


void Outside_Int(void) interrupt 0
{
        delay(3);           //延时30ms,去掉这行会出现按一下中断几次的情况
        if(KEY == 0)   //对按键进行抗干扰处理
        {
                P0 = 0xff;
                cbh3();
        }
        delay(100);       
}

void cbh2()
{
           Outside_Init();
        EA = 1;
        while(1)
                        {        datapross(Ds18b20ReadTemp()); //数据处理函数
                                DigDisplay();//数码管显示函数
                                delay(1);
                         }
}


void main()
{

                while(1)
        {
                cbh1();
                cbh2();
        }         
}
回复

使用道具 举报

2

主题

3

帖子

24

积分

新手上路

Rank: 1

积分
24
 楼主| 发表于 2020-1-3 13:06:14 | 显示全部楼层
这是加入音乐后的程序,求大神们,帮忙看看。。。。

#include "reg52.h" //此文件中定义了单片机的一些特殊功能
#include "temp.h"
#include "intrins.h"
typedef unsigned long int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P1^5;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit led=P2^0;
sbit KEY=P3^2;
unsigned char n=0;  //n为节拍常数变量
char num=0;
int temp;
u8 DisplayData[8];
u8 Count = 0;
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
u8 code smgquan[10]={0x40,0x04,0x08,0x10,0x00};

   
unsigned char code music_tab[] ={   
0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,   
0x20, 0x40, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x10,   
0x1C, 0x10, 0x18 , 0x40,   
0x1C, 0x20, 0x20 , 0x20,   
0x1C, 0x20, 0x18 , 0x20,   
0x20, 0x80, 0xFF , 0x20,   
0x30, 0x1C, 0x10 , 0x18,   
0x20, 0x15, 0x20 , 0x1C,   
0x20, 0x20, 0x20 , 0x26,   
0x40, 0x20, 0x20 , 0x2B,   
0x20, 0x26, 0x20 , 0x20,   
0x20, 0x30, 0x80 , 0xFF,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x80,   
0x20, 0x30, 0x1C , 0x10,   
0x20, 0x10, 0x1C , 0x10,   
0x20, 0x20, 0x26 , 0x20,   
0x2B, 0x20, 0x30 , 0x20,   
0x2B, 0x40, 0x20 , 0x15,   
0x1F, 0x05, 0x20 , 0x10,   
0x1C, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x30,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x40, 0x1C , 0x20,   
0x20, 0x20, 0x26 , 0x40,   
0x13, 0x60, 0x18 , 0x20,   
0x15, 0x40, 0x13 , 0x40,   
0x18, 0x80, 0x00   
};   
   
void int0()  interrupt 1   //采用中断0 控制节拍   
{  TH0=0xd8;   
   TL0=0xef;   
   n--;   
}   
   
void dela(uint i)
{uint k;
for(k=0;k<i;k++);
}
void delaydel(unsigned int del)
{
        uint i,j;
        for(i=0; i<del; i++)
        for(j=0; j<1827; j++)   
        ;
}
void delay (unsigned char m)   //控制频率延时   
{   
unsigned i=3*m;   
while(--i);   
}   
   
void delayms(unsigned char a)  //豪秒延时子程序   
{   
  while(--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!   
}   
   
void music()   
{ unsigned char p,m;   //m为频率常数变量   
  unsigned char i=0;   
  TMOD&=0x0f;   
  TMOD|=0x01;   
  TH0=0xd8;TL0=0xef;   
  IE=0x82;   
play:   
   while(1)   
    {   
    a: p=music_tab[i];   
       if(p==0x00)       { i=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍   
       else if(p==0xff)  { i=i+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符   
            else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数   
             TR0=1;                                             //开定时器1   
           while(n!=0) beep=~beep,delay(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)   
       TR0=0;                                             //关定时器1   
    }   
}  
void datapross(int temp)  //测量温度函数
{
        float tp;
        if(temp< 0) //当温度值为负数
        {
                DisplayData[0] = 0x40; // 负号
                //因为读取的温度是实际温度的补码,所以减 1,再取反求出原码
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;
       
        }
        else
        {
                DisplayData[0] = 0x00;
                tp=temp;
        }
                temp=temp-100;                                                                       

         //为什么我减了1才正确!!!!!!!!!
                DisplayData[0] = 0x00;                 // %是求余符号
                DisplayData[1] = smgduan[temp % 10000 / 1000];
                DisplayData[2] = smgduan[temp % 1000 / 100];         
                DisplayData[3] = smgduan[temp % 100 / 10]| 0x80;//0x80为小数点
                DisplayData[4] = smgduan[temp % 10];

        if(temp<180)           //如果小于18度,启动报警
       
        {        music();
        }
}


void DigDisplay()
{
        u8 i;

        for(i=0;i<6;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 位
                        }
                        P0=DisplayData[i];//发送数据
                        dela(10); //间隔一段时间扫描
                        P0=0x00;//消隐
                }
}                                                               



//void Time0_Init()
//{
//        TMOD = 0x01;          //定时器0选用方式1
//        TH0  = 0x4c;          //初值的计算
//        TL0  = 0x00;       
//        TR0 = 1;                  //启动定时器
//        ET0 = 1;                  //打开定时器中断允许位
//}
//                                                                                 
//void Time0_Int() interrupt 1
//{
//        TH0 = 0x4c;
//        TL0 = 0x00;
//        Count++;                        //长度加1
//}

void cbh1()
{        u8 t=0;
        uint i = 0;
//        Time0_Init();
//        EA = 1;                //打开总中断
for(t=0;t<16;t++)                        //延时15秒左右
                {P0 = smgquan[t % 4];
                delaydel(100);          //取 i 的个位
                if(Count == 20)                    //当Count为 20 时,i 自加一次,20 * 50MS = 1S
                {
                        Count = 0;

                        i++;               
                }
                                P0=0x00;                                               
                                DigDisplay();//数码管显示函数
                }
       
}

void cbh3()
{        u8 t=0;
        uint i = 0;
for(t=0;t<16;t++)          //延时15秒左右
                {P0 = smgquan[t % 4];
                delaydel(100);          //取 i 的个位
                if(Count == 20)                    //当Count为 20 时,i 自加一次,20 * 50MS = 1S
                {
                        Count = 0;

                        i++;               
                }
                                P0=0x00;                                               
                                DigDisplay();//数码管显示函数
                                delaydel(1);
                }
       
}

void Outside_Init(void)
{
        IT0 = 1;  //负边沿触发
        EX0 = 1;  //外部中断0允许
}


void Outside_Int(void) interrupt 0
{
        delaydel(3);           //延时30ms,去掉这行会出现按一下中断几次的情况
        if(KEY == 0)   //对按键进行抗干扰处理
        {
                P0 = 0xff;
                cbh3();
        }
        delaydel(100);       
}

void cbh2()
{
           Outside_Init();
        EA = 1;
        while(1)
                        {        datapross(Ds18b20ReadTemp()); //数据处理函数
                                DigDisplay();//数码管显示函数
                                delaydel(1);
                         }
}


void main()
{

                while(1)
        {
                cbh1();
                cbh2();
        }         
}
回复 支持 反对

使用道具 举报

20

主题

216

帖子

1115

积分

金牌会员

Rank: 6Rank: 6

积分
1115
发表于 2020-1-3 15:30:10 | 显示全部楼层
cbhrqw 发表于 2020-1-3 13:06
这是加入音乐后的程序,求大神们,帮忙看看。。。。

#include "reg52.h" //此文件中定义了单片机的一些 ...

用的是51的开发板吧 集成的51开发板上模块比较多 如果驱动蜂鸣器可能会导致其他模块的电流电压不足无法正常工作
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|普中开源电子分享网 粤ICP备16123577号-2

GMT+8, 2024-5-2 22:58 , Processed in 0.169280 second(s), 30 queries .

Powered by 论坛搭建 X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表