找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3434|回复: 5
打印 上一主题 下一主题
收起左侧

51单片机用按键切换时间和温度

[复制链接]
跳转到指定楼层
楼主
100黑币
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳LED段码表
uchar code tab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//含小数点共阳段码 0-9
char displayData[4];
uint shi,fen=9,miao=9,T50ms,tt;//时,分,秒,50ms
uchar bai,sh,ge,a,b,t;
sbit a0=P2^0;//连接P2.0
sbit a1=P2^1;//连接P2.1
sbit a2=P2^2;//连接P2.2
sbit a3=P2^3;//连接P2.3
sbit DQ=P3^7;//连接P3.7

/*void delay(uchar n)//延时5微秒函数
{
        do{
                _nop_();
                _nop_();
                _nop_();
                n--;
        }
        while(n);
}*/

void delay(uint n)
{
        while(n--);      
}

void init() //初始化子程序
{
        TMOD=0x01;//定时器T0为方式1
        TH0=(65536-50000)/256;//采用方式1,并设置定时器初值,50ms
        TL0=(65536-50000)%256;
        ET0=1;//启动T0中断允许
        EA=1;//总中断允许
        TR0=1;//启动T0
        EX0=1;//允许外部中断0中断
        //PX0=1;//外部中断0高优先级中断
        //PT0=1;//定时器T0中断高优先级中断
}

void scan()//扫描
{
          displayData[0] = tab[miao%10];
          displayData[1] = tab[(miao/10)%10];
          displayData[2] = tab[fen%10]|0x80;
          displayData[3] = tab[(fen/10)%10];      
}

void display()                //显示位数
{
        char i;
        for(i=0;i<=3;i++)
        {
                switch(i)
                {
                        case 0:a0=0;a1=0;a2=0;a3=1;break;//显示第0位
                        case 1:a0=0;a1=0;a2=1;a3=0;break;//显示第1位
                        case 2:a0=0;a1=1;a2=0;a3=0;break;//显示第2位
                        case 3:a0=1;a1=0;a2=0;a3=0;break;//显示第3位
                }
                if(i==2){
                        P0=(displayData[i]&0x7f);//加小数点
                        }else
                P0=displayData[i];//发送数据
                        delay(200); //间隔一段时间扫描
                        P0=0xff;//高电位清零
                        }
}

int_DS18b20()//对18b20初始化函数
{
        uchar x=0;
  DQ = 1;    //DQ复位
  delay(8);
  DQ=0;    //释放DQ
  delay(80); //DS18B20收到信号后延时
  DQ=1;   //读取DQ
  delay(10);
        x=DQ;
  delay(20);
        return x;
}

void write_byte(uchar dat)//写时序
{
        uchar i=0;
  for(i=8;i>0;i--){
                DQ=0;
                DQ=dat&0x01;//写1,在15微秒内拉低
                delay(5);//写0,拉低60微秒
                DQ=1;
                dat>>=1;//右移1位,原数值除以2
        }
        delay(4);
}

read_byte()//读时序
{
        uchar i=0;
  uchar dat=0;
  for(i=8;i>0;i--){
                DQ=0;//拉低ds18b20单总线
                dat>>=1;
    DQ=1;//15微秒内拉释放总线,等待ds18b20的存在脉冲
    if(DQ)
    dat|=0x80;
    delay(4);
        }
        return (dat);
}

void int_()
{
        while(int_DS18b20());
        write_byte(0xcc);//发Skip ROM命令,由于只有一只DS18B20就不需要读取ROM编码以及匹配ROM编码
  write_byte(0x44);//启动温度转换
}

void ReadTemperature()//读取温度的函数
  {
    uchar a=0;
    unsigned  b=0;
    unsigned  t=0;
                int_();
    delay(5);//延时,必要
    int_DS18b20();
    write_byte(0xCC);//跳过读写序列号
    write_byte(0xBE);//读温度寄存器
    delay(5);
    a=read_byte();//读取温度
    b=read_byte();      
    t=b<<4;//取高八位的后三位
    t+=(a&0xf0)>>4;//低八位的高四位加上高八位中后三位的值
    tt=a&0x0f;//小数位
    sh=((b*256+a)>>4);//实际温度
    ge=tt*0.0625*10;
   }

void wenduxianshi()//温度显示的函数
{
         a0=1;
         P0=tab[sh/10];//百
         delay(100);
         a0=0;

         a1=1;
         P0=tab[sh%10]+0x80;//十位,+0x80可以显示小数点后一位
   delay(100);
         a1=0;

   a2=1;
         P0=tab[ge%10];//个位
         delay(100);
         a2=0;

   a3=1;
         P0=0xc6;// C
         delay(100);
         a3=0;
}

void main()//主函数
{
        init();//初始化程序
        while(1){
                scan();//扫描
                display();//显示
        }
}

void timer0() interrupt 1//timer0中断服务子程序定是时间为50ms
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        T50ms++;
        if(T50ms==20)//仿分钟
                {
                        T50ms=0;
                        miao++;
                        if(miao>=60)
                                {
                                        miao=miao-60;
                                        fen++;
                                        if(fen>=60)
                                                {
                                                        fen=fen-60;
                                                        shi++;
                                                }
                                }
                }
}
void k4q8() interrupt 0//外部中断0
{
        uint count=0;
        while(1)
                {
                        count++;
                        ReadTemperature();
                        wenduxianshi();
                        wenduxianshi();
                        if(k2=0)//隔一段时间返回时钟
                                {
                                             miao=miao+4;
                                        break;
                                }
                }
}
这段程序的效果是 按下按键由时间模块切换到温度模块 4秒后自动切回时间模块。怎么修改能变成通过点击按键来回切换

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:584814 发表于 2020-6-30 07:47 | 只看该作者
居然没看出按键接在哪个端口
回复

使用道具 举报

板凳
ID:213173 发表于 2020-6-30 07:59 | 只看该作者
用按键切换时间和温度




  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳LED段码表
  6. uchar code tab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//含小数点共阳段码 0-9
  7. uchar displayData[4];
  8. uint shi,fen=9,miao=9,T5ms,tt;//时,分,秒,50ms
  9. uchar bai,sh,ge;
  10. bit biaozhi=0;
  11. //sbit a0=P2^0;//连接P2.0
  12. //sbit a1=P2^1;//连接P2.1
  13. //sbit a2=P2^2;//连接P2.2
  14. //sbit a3=P2^3;//连接P2.3
  15. sbit DQ=P3^7;//连接P3.7



  16. void delay(uint n)
  17. {
  18.         while(n--);      
  19. }

  20. void init() //初始化子程序
  21. {
  22.         TMOD=0x01;//定时器T0为方式1
  23.         TH0=(65536-5000)/256;//采用方式1,并设置定时器初值,5ms
  24.         TL0=(65536-5000)%256;
  25.         TF0=0;//中断请求清0
  26.         TR0=1;//启动T0
  27.         IT0=1;//下降沿触发
  28.         EA=1;//总中断允许
  29.         EX0=1;//允许外部中断0中断
  30.         //PX0=1;//外部中断0高优先级中断
  31.         //PT0=1;//定时器T0中断高优先级中断
  32. }

  33. void display()//显示
  34. {
  35.         static uchar i=0;
  36.         if(biaozhi==0)
  37.         {
  38.                 displayData[0] = tab[fen/10%10];
  39.                 displayData[1] = tab[fen%10]&0x7f;
  40.                 displayData[2] = tab[miao/10%10];
  41.                 displayData[3] = tab[miao%10];
  42.         }
  43.         else
  44.         {
  45.                 displayData[0] = tab[sh/10%10];
  46.                 displayData[1] = tab[sh%10]&0x7f;
  47.                 displayData[2] = tab[ge%10];
  48.                 displayData[3] = 0xc6;
  49.         }
  50.         P2&=0xf0;
  51.         P0=displayData[i];
  52.         P2|=0x01<<i;
  53.         i++;i%=4;
  54. }

  55. int_DS18b20()//对18b20初始化函数
  56. {
  57.         uchar x=0;
  58.         DQ = 1;    //DQ复位
  59.         delay(8);
  60.         DQ=0;    //释放DQ
  61.         delay(80); //DS18B20收到信号后延时
  62.         DQ=1;   //读取DQ
  63.         delay(10);
  64.         x=DQ;
  65.         delay(20);
  66.         return x;
  67. }

  68. void write_byte(uchar dat)//写时序
  69. {
  70.         uchar i=0;
  71.         for(i=8;i>0;i--)
  72.         {
  73.                 DQ=0;
  74.                 DQ=dat&0x01;//写1,在15微秒内拉低
  75.                 delay(5);//写0,拉低60微秒
  76.                 DQ=1;
  77.                 dat>>=1;//右移1位,原数值除以2
  78.         }
  79.         delay(4);
  80. }

  81. uchar read_byte()//读时序
  82. {
  83.         uchar i=0;
  84.         uchar dat=0;
  85.         for(i=8;i>0;i--)
  86.         {
  87.                 DQ=0;//拉低ds18b20单总线
  88.                 dat>>=1;
  89.                 DQ=1;//15微秒内拉释放总线,等待ds18b20的存在脉冲
  90.                 if(DQ)
  91.                 dat|=0x80;
  92.                 delay(4);
  93.         }
  94.         return (dat);
  95. }
  96. void ReadTemperature()//读取温度的函数
  97. {
  98.         static uchar i=0;
  99.         uchar a=0,b=0;
  100.         uint t=0;
  101.         switch(i)
  102.         {
  103.                 case 0: int_DS18b20();
  104.                                 write_byte(0xcc);//发Skip ROM命令,由于只有一只DS18B20就不需要读取ROM编码以及匹配ROM编码
  105.                                 write_byte(0x44);//启动温度转换
  106.                                 break;
  107.                 case 1: break;//利用定时循环周期替代5ms延时
  108.                 case 2: int_DS18b20();
  109.                                 write_byte(0xCC);//跳过读写序列号
  110.                                 write_byte(0xBE);//读温度寄存器
  111.                                 break;
  112.                 case 3: break;//利用定时循环周期替代5ms延时
  113.                 case 4: a=read_byte();//读取温度低8位
  114.                                 b=read_byte();  //读取温度高8位
  115.                                 t=b<<8|a;
  116.                                 sh=t>>4;//取整数
  117.                                 ge=(a&0x0f)*0.625;//取1位小数
  118.                                 break;
  119.         }
  120.         i++;i%=5;
  121. }

  122. void main()//主函数
  123. {
  124.         init();//初始化程序

  125.         while(1)
  126.         {
  127.                 if(TF0)//查询定时器中断请求位
  128.                 {
  129.                         TF0=0;
  130.                         TH0=(65536-5000)/256;//5ms
  131.                         TL0=(65536-5000)%256;
  132.                         T5ms++;
  133.                         if(T5ms==200)//1s
  134.                         {
  135.                                 T5ms=0;
  136.                                 miao++;
  137.                                 if(miao>=60)
  138.                                 {
  139.                                         miao=0;
  140.                                         fen++;
  141.                                         if(fen>=60)
  142.                                                 fen=0;
  143.                                 }
  144.                         }
  145.                         ReadTemperature();//读温度
  146.                         display();//显示
  147.                 }
  148.         }
  149. }

  150. void k4q8() interrupt 0//外部中断0
  151. {
  152.         biaozhi=~biaozhi;
  153. }
复制代码



回复

使用道具 举报

地板
ID:801878 发表于 2020-7-28 10:21 | 只看该作者
你要设bai置一个标志变量,如flag,在进入按键程du序后,flag++;然后zhi加个控制判断语句if(flag>3)flag=0;这样,在显示模dao块中再加入开关语句;switch(flag){  case 0:...显示时间..  case 1:...显示日期。。.  case 2:...显示温度。。。 }
回复

使用道具 举报

5#
ID:808700 发表于 2020-7-28 11:21 | 只看该作者
设定一个变量,,初始为0,进入时间显示的函数,,按一下 加1, 进行温度的函数,,再按清零,,
回复

使用道具 举报

6#
ID:808700 发表于 2020-7-28 11:22 | 只看该作者
用判断执行,
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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