蓝桥杯单片机第十二届赛题

该程序使用STC15系列单片机,通过DS18B20传感器读取温度,并利用PCF8591芯片读取电压。数码管显示温度和设定参数,按键控制显示切换和参数调整。程序中包含了IIC通信协议以及延时函数等关键模块。
摘要由CSDN通过智能技术生成

#include <stc15.h>
#include <intrins.h>
#include <onewire.h>
#include <iic.h>

sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;

sbit C4=P3^4;
sbit C3=P3^5;
sbit C2=P4^2;
sbit C1=P4^4;

unsigned char a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xbf,0xff,0xc6,0x8c,0x88};//0~9/./-/灭/C/P/R
unsigned char b[8]={0};
unsigned char n=0;
unsigned char moshi=0;
unsigned int wendu,count_wendu,wen_canshu=25;
unsigned int dat,count_dianya;

void BUZZ()//初始化
{
  P2=(P2&0x1f)|0x80;
    P0=0xff;
    P2&=0x1f;
    P2=(P2&0x1f)|0xa0;
    P0=0x00;
    P2&=0x1f;
    P2=(P2&0x1f)|0xc0;
    P0=0xff;
    P2&=0x1f;
    P2=(P2&0x1f)|0xe0;
    P0=0xff;
    P2&=0x1f;
}

void SMGxuanze()//数码管  位选 段选
{
    static int i=0;
    
  P2=(P2&0x1f)|0xc0;
    P0=0x01<<i;
    P2&=0x1f;
    
    if(n==0&i==5)
    {
      P2=(P2&0x1f)|0xe0;
      P0=a[b[i]]&0x7f;
      P2&=0x1f;
    }
    else if(n==2&i==5)
    {
      P2=(P2&0x1f)|0xe0;
      P0=a[b[i]]&0x7f;
      P2&=0x1f;
    }
    else 
    P2=(P2&0x1f)|0xe0;
    P0=a[b[i]];
    P2&=0x1f;
    
    i=(i+1)%8;
}

void Delay20ms()        //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 1;
    j = 216;
    k = 35;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void Key()//按键
{
    C1=0;
    C2=C3=C4=1;
    R1=R2=R3=R4=1;
    if(R4==0)
    {
      Delay20ms();
        if(R4==0)
        {
      n++;
            n=n%3;
        }while(R4==0);
    }
    else if(R3==0)
    {
      Delay20ms();
        if(R3==0)
        {
          moshi++;
            moshi=moshi%2;
        }while(R3==0);
    }
    
    C2=0;
    C1=C3=C4=1;
    R1=R2=R3=R4=1;
    if(R3==0&&n==1)
    {
        Delay20ms();
        if(R3==0)
        {
        wen_canshu++;
        }while(R3==0);
    }
    else if(R4==0&&n==1)
    {
        Delay20ms();
        if(R4==0)
        {
        wen_canshu--;
        }while(R4==0);
    }
}

unsigned int ds18b2_Read()//温度读取
{
    unsigned int wendu;    
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0x44);
    
    Delay_OneWire(1200);
    
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0xbe);    
    EA=0;
    wendu= Read_DS18B20();
    wendu |= (Read_DS18B20()<<8);
    wendu *=6.25;
    EA=1;
    return wendu;
}

void  wendu_xianshi()//温度显示
{
    P2=(P2&0x1f)|0x80;
    P0=0xfd;
    b[0]=13;
    b[1]=12;
    b[2]=12;
    b[3]=12;
    b[4]=wendu/1000;
    b[5]=wendu/100%10;
    b[6]=wendu/10%10;
    b[7]=wendu%10;    
}

void wendu_canshu()//温度参数
{
    P2=(P2&0x1f)|0x80;
    P0=0xfb;
    b[0]=14;
    b[1]=12;
    b[2]=12;
    b[3]=12;
    b[4]=12;
    b[5]=12;
    b[6]=wen_canshu/10;
    b[7]=wen_canshu%10;
}

void Read_AIN3()//电压读取
{
    IIC_Start();        //IIC总线起始信号                            
    IIC_SendByte(0x90);     //PCF8591的写设备地址        
    IIC_WaitAck();      //等待从机应答        
    IIC_SendByte(0x03);     //写入PCF8591的控制字节        
    IIC_WaitAck();      //等待从机应答                        
    IIC_Stop();         //IIC总线停止信号                    
    
    IIC_Start();        //IIC总线起始信号                                    
    IIC_SendByte(0x91);     //PCF8591的读设备地址        
    IIC_WaitAck();         //等待从机应答        
    dat = IIC_RecByte();    //读取PCF8591通道3的数据             
    IIC_SendAck(1);         //产生非应答信号                
    IIC_Stop();         //IIC总线停止信号    
  dat=dat/0.51;    
}

void PCF8591xainshi()//电压显示
{
    if(moshi==0)
    {
        P2=(P2&0x1f)|0x80;
      P0=0xfe;
      if(wendu/100<wen_canshu)
      {
        b[0]=15;
        b[1]=12;
        b[2]=12;
        b[3]=12;
        b[4]=12;
        b[5]=0;
        b[6]=0;
        b[7]=0;
      }
      else if(wendu/100>wen_canshu)
      {
        b[0]=15;
        b[1]=12;
        b[2]=12;
        b[3]=12;
        b[4]=12;
        b[5]=5;
        b[6]=0;
        b[7]=0;
      }
  }
    else if(moshi==1)
    {
        P2=(P2&0x1f)|0x80;
      P0=0xf7;
      if(wendu/100<=20)
        {
          b[0]=15;
            b[1]=12;
            b[2]=12;
            b[3]=12;
            b[4]=12;
            b[5]=1;
            b[6]=0;
            b[7]=0;
        }
        else if(wendu/100>=40)
        {
          b[0]=15;
            b[1]=12;
            b[2]=12;
            b[3]=12;
            b[4]=12;
            b[5]=4;
            b[6]=0;
            b[7]=0;
        }
        else if(wendu/100<40&&wendu/100>20)
        {
            dat=(wendu-20)/6;
          b[0]=15;
            b[1]=12;
            b[2]=12;
            b[3]=12;
            b[4]=12;
            b[5]=dat/100%10;
            b[6]=dat/10%10;
            b[7]=dat%10;
        }
    }
  
}

void Timer0Init(void)        //1毫秒@11.0592MHz
{
    AUXR |= 0x80;        //定时器时钟1T模式
    TMOD &= 0xF0;        //设置定时器模式
    TL0 = 0xCD;        //设置定时初值
    TH0 = 0xD4;        //设置定时初值
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    
    ET0=1;
    EA=1;
}


void ServiceTimer0() interrupt 1
{  
      count_wendu++;    
 if(n==0)
    {
      SMGxuanze();
      wendu_xianshi();
    }
    else if(n==1)
    {
      SMGxuanze();
        wendu_canshu();
    }
   else if(n==2)
    {
        SMGxuanze();
        PCF8591xainshi();
    count_dianya++;
        if(count_dianya%5==0)
        {
        Read_AIN3();
        }
    }
    
}

void main()
{
    BUZZ();
    Timer0Init();
  while(1)
    {
      Key();
              if(count_wendu%500==0)
          wendu=ds18b2_Read();//从底层读取温度显示
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值