第10届蓝桥答案解析

#include "reg52.h"
#include "iic.h"
sbit s4 =P3^3;
sbit s5 =P3^2;
sbit s6 =P3^1;
sbit s7 =P3^0;
#define char unsigned char
#define int unsigned int
char code smgnodot[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc1,0x8e};//0~9,u,f
char code smgdot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
bit s4_state=0;   //=0显示电压测量   =1显示频率测量
bit s5_state=0;   //=0默认输出2v     =1跟随电位器rb2
bit s6_state=0;   //=0LED灯启用
bit s7_state=0;   //=0数码管启用
int dat_u=0;      //电压
char dat_rb2=0;   //读取电位器RB2的值
int dat_f=0;      //频率
int count_f=0;    //计数频率
char count_t=0;   //计时一秒
void select573(char channel)//573锁存器位选函数
{
    switch(channel)
    {
        case 0:
            P2=(P2 & 0x1f) | 0x00;break;
        case 4:
            P2=(P2 & 0x1f) | 0x80;break;
        case 5:
            P2=(P2 & 0x1f) | 0xa0;break;
        case 6:
            P2=(P2 & 0x1f) | 0xc0;break;
        case 7:
            P2=(P2 & 0x1f) | 0xe0;break;
    }
}
void init_system()//初始化系统函数(关闭led灯和蜂鸣器)
{
    select573(4);
    P0=0xfe;
    select573(5);
    P0=0x00;
    select573(0);
}
void delay_smg(char t)//数码管延时函数
{
    while(t--);
}
void display_onesmg(char value,char pos)//点亮单个数码管函数
{
    select573(7);
    P0=0xff;
    select573(6);
    P0=0x01 << pos;
    select573(7);
    P0=value;
    
}
void close_allsmg()//关闭所有数码管,消除数码管最后一位过亮
{
    select573(6);
    P0=0xff;
    select573(7);
    P0=0xff;
}
void display_smg()//数码管显示函数
{
    if(s4_state == 0)//显示电压
    {
        display_onesmg(smgnodot[10],0);
        delay_smg(100);
        display_onesmg(smgdot[dat_u / 100],5);
        delay_smg(100);
        display_onesmg(smgnodot[(dat_u % 100) / 10],6);
        delay_smg(100);
        display_onesmg(smgnodot[dat_u % 10],7);
        delay_smg(100);
        close_allsmg();
        delay_smg(200);
        
    }
    if(s4_state == 1)//显示频率
    {
        display_onesmg(smgnodot[11],0);
        delay_smg(100);
        if(dat_f > 99999)
            display_onesmg(smgnodot[dat_f / 100000],2);
          delay_smg(100);
        if(dat_f > 9999)
            display_onesmg(smgnodot[(dat_f / 10000) % 10],3);
          delay_smg(100);
        if(dat_f > 999)
            display_onesmg(smgnodot[(dat_f / 1000) % 10],4);
          delay_smg(100);
        if(dat_f > 99)
            display_onesmg(smgnodot[(dat_f / 100) % 10],5);
          delay_smg(100);
        if(dat_f > 9)
            display_onesmg(smgnodot[(dat_f / 10) % 10],6);
          delay_smg(100);
        display_onesmg(smgnodot[dat_f % 10],7);
        delay_smg(100);
        close_allsmg();
    }
}
void read_rb2()//读取电位器RB2的数据
{
    IIC_Start();
    IIC_SendByte(0x90);
    IIC_WaitAck();
    IIC_SendByte(0x43);
    IIC_WaitAck();
    IIC_Stop();
    
    IIC_Start();
    IIC_SendByte(0x91);
    IIC_WaitAck();
    
    dat_rb2=IIC_RecByte();
    IIC_Ack(1);
    IIC_Stop();
    
    dat_u=dat_rb2 * 1.961;//获取实际电压(500 / 255 = 1.961)
}
void write_u(char dat)//数模转换
{
    IIC_Start();
    IIC_SendByte(0x90);
    IIC_WaitAck();
    IIC_SendByte(0x40);
    IIC_WaitAck();
    
    IIC_SendByte(dat);
    IIC_WaitAck();
    IIC_Stop();
}
void key_s4()//按键S4
{
    if(s4 == 0)
    {
        delay_smg(100);
        if(s4 == 0)
        {
            while(s4 == 0);
            s4_state =~s4_state;
        }
    }
}
void key_s5()//按键S5
{
    if(s5 == 0)
    {
        delay_smg(100);
        if(s5 == 0)
        {
            while(s5 == 0)
            {
                display_smg();
            }
            s5_state=~s5_state;
        }
    }
}
void choose_dac()//选择电压固定输出2V或者跟随电位器RB2
{
    if(s5_state == 0)
    {
        write_u(102);//固定输出两伏200 * (255 / 500)
    }
    if(s5_state == 1)
    {
        read_rb2();
        write_u(dat_rb2);
    }
}
void led_u()//电压变化引起led灯的变化函数
{
    select573(0);
    if(dat_u < 150)
    {
        P0 |=0x04;
    }
    else if(dat_u < 250)
    {
        P0 &=~0x04;
    }
    else if(dat_u <350)
    {
        P0 |=0x04;
    }
    else P0 &=~0x04;
    select573(4);
}
void led_f()//频率变化引起led灯的变化函数
{
    select573(0);
    if(dat_f < 1000)
    {
        P0 |=0x08;
    }
    else if(dat_f < 250)
    {
        P0 &=~0x08;
    }
    else if(dat_f <350)
    {
        P0 |=0x08;
    }
    else P0 &=~0x08;
    select573(4);
}
void all_led()//LED灯总的开关函数
{
    select573(0);
    if(s6_state == 0)
    {
        if(s4_state == 0)//点亮L1
        {
            P0 &=0xfe;
            led_u();
        }
        else//点亮L2
        {
            P0 &=0xfd;
            led_f();
        }
        if(s5_state == 0)
        {
            P0 |=0x10;
        }
        else
        {
            P0 &=~0x10;//点亮L5
        }
    }
    else
    {
        P0=0xff;
    }
    select573(4);
}
void key_s6()
{
    if(s6 == 0)
    {
        delay_smg(100);
        if(s6 == 0)
        {
            while(s6 == 0)
            {
                display_smg();
            }
            s6_state=~s6_state;
        }
    }
}

void key_s7()
{
    if(s7 == 0)
    {
        delay_smg(100);
        if(s7 == 0)
        {
            while(s7 == 0);
            s7_state=~s7_state;
        }
    }
}
void choose_smg()//数码管总开关控制函数
{
    if(s7_state == 0)
            {
                display_smg();
            }
    if(s7_state == 1)
            {
                close_allsmg();
            }
}
void init_timer()
{
    TMOD=0x16;//定时器1计时,方式一16位;定时器0计数,方式二,自动重装8位
    
    TH0=0xff;
    TL0=0xff;
    
    TH1=(65536 - 50000) / 256;
    TL1=(65535 - 50000) % 256;
    
    EA=1;
    
    ET0=1;
    TR0=1;
    
    ET1=1;
    TR1=1;
}
void service_t0() interrupt 1
{
    count_f++;
}
void service_t1() interrupt 3
{
    TH1=(65536 - 50000) / 256;
    TL1=(65535 - 50000) % 256;
    count_t++;
    if(count_t == 20)
    {
        count_t=0;
        dat_f=count_f;
        count_f=0;
    }
}
void main()
{
    init_system();
    init_timer();
    while(1)
    {
        key_s4();
        key_s5();
        key_s6();
        key_s7();
        all_led();
        read_rb2();
        choose_smg();
        choose_dac();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值