蓝桥杯单片机第四届赛题

该程序实现了使用STM8微控制器进行电压读取并通过数码管显示的功能。它包括初始化、延时函数、数码管显示和按键处理等模块,同时通过IIC协议与PCF8591芯片通信获取电压数据,并根据电压值控制LED显示。
摘要由CSDN通过智能技术生成

#include <stc15.h>
#include <intrins.h>
#include <iic.h>
unsigned char a[13]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xbf,0xff};//0~9/./-/灭
unsigned char b[8]={0};
unsigned int liang=0,n=0;
unsigned int jia;
unsigned int count1,dat,count2=0;

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 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 SMG_xaunze()//数码管 位选 段选
{
    static int i=0;
    
  P2=(P2&0x1f)|0xc0;
    P0=0x01<<i;
    P2&=0x1f;
    if(i==1|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 SMG_xainshi_1()//数码管显示1
{
        b[0]=12;
        b[1]=0;
        b[2]=5;
        b[3]=0;
        b[4]=liang/1000;
        b[5]=liang/100%10;
        b[6]=liang/10%10;
        b[7]=liang%10;
}

void SMG_xainshi_2()//数码管显示2
{
      jia=liang*0.5;
    b[0]=12;
        b[1]=0;
        b[2]=5;
        b[3]=0;
        b[4]=jia/1000;
        b[5]=jia/100%10;
        b[6]=jia/10%10;
        b[7]=jia%10;
}

void Read_AIN3()//电压读取
{
    IIC_Start();        //IIC总线起始信号                            
    IIC_SendByte(0x90);     //PCF8591的写设备地址        
    IIC_WaitAck();      //等待从机应答        
    IIC_SendByte(0x01);     //写入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 dianya_LED()//光电压控制LED显示
{
  if(dat<125)
    {
      P2=(P2&0x1f)|0x80;
      P0=0xfe;
    }
    else
    {
      P2=(P2&0x1f)|0x80;
      P0=0xff;
    }
}

void Keys()//按键
{
  if(P30==0)
    {
      Delay20ms();
     if(P30==0&n==0)
        {
      n=1;
        }
    }while(P30==0);
    
    if(P31==0)
    {
        Delay20ms();
        if(P31==0)
        {
          n=2;
        }
    }while(P31==0);

    if(n==2)
    {
      if(P30==0)
        {
//            Delay20ms();
            if(P30==0)
            {
          liang=0;
            }
        }while(P30==0);
    }
    
    if(liang==0)
    {
        if(P30==0)
        {
//            Delay20ms();
            if(P30==0)
            {
          n=1;
            }
        }while(P30==0);
    }
    
    if(liang==9999)
    {
      n=2;
    }
}


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
{
    count2++;
    if(count2%200==0)
    {
    Read_AIN3();
    dianya_LED();
    }
  if(n==0)
    {
        SMG_xaunze();
      SMG_xainshi_1();
    }
    else if(n==1)
    {
        P2=(P2&0x1f)|0xa0;
      P0=0x10;
      SMG_xaunze();
        count1++;
        if(count1%100==0)
        liang=(liang+1);
      SMG_xainshi_1();
    }
    else if(n==2)
    {
        P2=(P2&0x1f)|0xa0;
      P0=00;
        SMG_xaunze();
      SMG_xainshi_2();
    }
}

void main()
{
    BUZZ();
    Timer0Init(); 
    
  while(1)
    {
      Keys();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值