蓝桥杯单片机:第九届省赛——彩灯控制器

#include <reg52.h>
#include "iic.h"

/**************变量定义区******************/
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
bit Led_Flag;
bit Nixie_Star_Flag;//    数码管闪烁变量 0-灭 1-量
bit Nixie_Dis_Mode;    //  数码管显示模式专用界面 0-参数界面 1-亮度等级
unsigned char Nixie_Data[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
unsigned int Led_Time_Disp[4]={400,400,400,400};     //流转时间间隔
unsigned int Led_Time_Ctrol[4]={400,400,400,400};    //流转时间间隔控制
unsigned char Led_Time_Index;                                            //模式指针
unsigned int Timer_400ms;    //400ms计时间
unsigned char Nixie_Index;//0-熄灭 1-模式编号亮灭 2-流转时间亮灭
unsigned char EEPROM_Data[4];
unsigned char    Led_Mode;        //1 2 3 4==Led_Time_Index+1;
unsigned int Led_Time;
unsigned char Led_Pos;
unsigned char Led_Level;
unsigned char Led_Count;        //PWM占空比
unsigned char PWM_Duty;
/*******************************************/

void HC573_Select(unsigned char channel);
void Led_Show();
void HC573_Select(unsigned char channel);
void Delay(unsigned int t);

void Timer0_Init()
{
    TMOD=0;
    TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
    TR0=1;
    EA=1;
    ET0=1;
}

void Timer0_Service() interrupt 1
{
    TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
    Timer_400ms++;
    Led_Count++;
    if(Timer_400ms==40)
    {
        Nixie_Star_Flag=~Nixie_Star_Flag;
        Timer_400ms=0;
    }
    
    if(Led_Flag==1)
    {
        Led_Time++;                //1Led_Time=10ms
    }
    
    if(Led_Count==100)
    {
        Led_Count=0;
    }
}

void Led_Show()
{
    unsigned char i=0;
    HC573_Select(4);
    if(Led_Flag==1)
    {
        if(Led_Time==Led_Time_Ctrol[Led_Mode]/10)
        {
            Led_Time=0;
            switch(Led_Mode)
            {
                case 0:
                    Led_Pos++;
                    if(Led_Pos==8)
                    {
                        Led_Pos=7;
                        Led_Mode=1;
                    }
                    break;
                case 1:
                    Led_Pos--;
                    if(Led_Pos==255)
                    {
                        Led_Pos=0;
                        Led_Mode=2;
                    }
                    break;
                case 2:
                    Led_Pos++;
                    if(Led_Pos>3)
                    {
                        Led_Pos=0;
                        Led_Mode=3;
                    }
                    break;
                case 3:
                    Led_Pos++;
                    if(Led_Pos>3)
                    {
                        Led_Pos=0;
                        Led_Mode=0;
                    }
            }
        }
        if(Led_Mode<2)
        {
            P0=~(0x01<<Led_Pos);
            Delay(PWM_Duty);
            P0=0XFF;
            Delay(100-PWM_Duty);
        }
        if(Led_Mode==2)
        {
            P0=~(0x81<<Led_Pos|0x81>>Led_Pos);
            Delay(PWM_Duty);
            P0=0XFF;
            Delay(100-PWM_Duty);
        }
        if(Led_Mode==3)
        {
            P0=~(0x10<<Led_Pos|0X08>>Led_Pos);
            Delay(PWM_Duty);
            P0=0XFF;
            Delay(100-PWM_Duty);
        }
    }
}

void HC573_Select(unsigned char channel)
{
    switch(channel)
    {
        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 Delay(unsigned int t)
{
    while(t--);
}

void Nixie_Display(unsigned char pos,val)
{
    HC573_Select(6);
    P0=0x01<<pos;
    HC573_Select(7);
    P0=val;
    Delay(100);
    P0=0xff;
}

void Nixie_CloseAll()
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        Nixie_Display(i,0xff);
    }
}

void Nixie_Show()
{
    if(Nixie_Dis_Mode==0)                        //处于参数界面
    {
        if(Nixie_Index==0)
        {
            Nixie_CloseAll();
        }
        else if(Nixie_Index==1)
        {
            if(Nixie_Star_Flag==0)            //模式编号亮灭
            {
                Nixie_Display(0,0xff);        
                Nixie_Display(2,0xff);
                Nixie_Display(1,0xff);
            }
            else if(Nixie_Star_Flag==1)
            {
                Nixie_Display(0,0xbf);        
                Nixie_Display(2,0xbf);
                Nixie_Display(1,Nixie_Data[Led_Time_Index+1]);
            }
            if(Nixie_Data[Led_Time_Disp[Led_Time_Index]/1000%10]==0xc0)    
            {
                Nixie_Display(4,0xff);
            }
            else
            {
                Nixie_Display(4,Nixie_Data[Led_Time_Disp[Led_Time_Index]/1000%10]);
            }
            Nixie_Display(5,Nixie_Data[Led_Time_Disp[Led_Time_Index]/100%10]);
            Nixie_Display(6,Nixie_Data[Led_Time_Disp[Led_Time_Index]/10%10]);
            Nixie_Display(7,Nixie_Data[Led_Time_Disp[Led_Time_Index]%10]);
        }
        else if(Nixie_Index==2)
        {
            Nixie_Display(0,0xbf);        
            Nixie_Display(2,0xbf);
            Nixie_Display(1,Nixie_Data[Led_Time_Index+1]);
            if(Nixie_Star_Flag==0)            //流转时间亮灭
            {
                Nixie_Display(4,0xff);        
                Nixie_Display(5,0xff);
                Nixie_Display(6,0xff);
                Nixie_Display(7,0xff);
            }
            else if(Nixie_Star_Flag==1)
            {
                if(Nixie_Data[Led_Time_Disp[Led_Time_Index]/1000%10]==0xc0)    
                {
                    Nixie_Display(4,0xff);
                }
                else
                {
                    Nixie_Display(4,Nixie_Data[Led_Time_Disp[Led_Time_Index]/1000%10]);
                }
                Nixie_Display(5,Nixie_Data[Led_Time_Disp[Led_Time_Index]/100%10]);
                Nixie_Display(6,Nixie_Data[Led_Time_Disp[Led_Time_Index]/10%10]);
                Nixie_Display(7,Nixie_Data[Led_Time_Disp[Led_Time_Index]%10]);
            }
        }
    }
}

void Keys_Scan()
{
    unsigned char i=0;
    if(S7==0)
    {
        Delay(50);
        if(S7==0)
        {
            Led_Flag=~Led_Flag;                //1亮 0灭 LED
        }
        while(S7==0)
        {
            Led_Show();
        }
    }
    if(S6==0)
    {
        Delay(50);
        if(S6==0)
        {
            if(Nixie_Index==0)
            {
                Nixie_Index=1;
            }
            else if(Nixie_Index==1)
            {
                Nixie_Index=2;
            }
            else if(Nixie_Index==2)
            {
                Nixie_Index=0;
            }
            if(Nixie_Index==0)
            {
                for(i=0;i<4;i++)
                {
                    Led_Time_Ctrol[i]=Led_Time_Disp[i];
                    EEPROM_Data[i]=Led_Time_Ctrol[i]/100;
                }
                EEPROM_Write(EEPROM_Data,0,4);
            }
        }
        while(S6==0)
        {
            Nixie_Show();
            Led_Show();
        }
    }
    if(S5==0)
    {
        Delay(50);
        if(S5==0)
        {
            if(Nixie_Dis_Mode==0&&Nixie_Index==1)
            {
                ++Led_Time_Index;
                if(Led_Time_Index==4)
                {
                    Led_Time_Index=0;
                }
            }
            else if(Nixie_Dis_Mode==0&&Nixie_Index==2)
            {
                Led_Time_Disp[Led_Time_Index]=Led_Time_Disp[Led_Time_Index]+100;
                if(Led_Time_Disp[Led_Time_Index]>1200)
                {
                    Led_Time_Disp[Led_Time_Index]=400;
                }
            }
        }
        while(S5==0)
        {
            Nixie_Show();
            Led_Show();
        }
    }
    if(S4==0)
    {
        Delay(50);
        if(S4==0)
        {
            if(Nixie_Dis_Mode==0&&Nixie_Index==1)
            {
                Led_Time_Index--;
                if(Led_Time_Index>99)
                {
                    Led_Time_Index=3;
                }
            }
            else if(Nixie_Dis_Mode==0&&Nixie_Index==2)
            {
                Led_Time_Disp[Led_Time_Index]=Led_Time_Disp[Led_Time_Index]-100;
                if(Led_Time_Disp[Led_Time_Index]<400)
                {
                    Led_Time_Disp[Led_Time_Index]=1200;
                }
            }
            if(Nixie_Index==0)
            {
                while(S4==0)
                {
                    for(i=0;i<6;i++)
                    {
                        Nixie_Display(i,0xff);
                    }
                    Nixie_Display(6,0xbf);
                    Nixie_Display(7,Nixie_Data[Led_Level+1]);
                    Led_Show();
                }
            }
            while(S4==0)
            {
                Nixie_Show();
                Led_Show();
            }
        }
    }
}

void Ad_Init()
{
    Led_Level=AD_Read(0x43)/64;
    if(Led_Level==0)
    {
        PWM_Duty=25;
    }
    else if(Led_Level==1)
    {
        PWM_Duty=50;
    }
    else if(Led_Level==2)
    {
        PWM_Duty=75;
    }
    else if(Led_Level==3)
    {
        PWM_Duty=100;
    }
}

void main()
{
    unsigned char i;
    Timer0_Init();
    EEPROM_Read(EEPROM_Data,0,4);
    for(i=0;i<4;i++) 
    {
        Led_Time_Ctrol[i]=Led_Time_Disp[i]=EEPROM_Data[i]*100;
    }
    while(1)
    {
        Ad_Init();
        Led_Show();
        Nixie_Show();
        Keys_Scan();
    }
}

作者水平有限,代码比较冗杂,有需要的同学辩证地看。

学习到的点:

1.EEPROM读写代码的学习,具体代码如下:

void EEPROM_Write(unsigned char* EEPROM_String,unsigned char addr,unsigned char num)
{
    I2CStart();                    //发送开启信号
    I2CSendByte(0xA0);    //选择EEPROM芯片 确定模式
    I2CWaitAck();               //等待EEPROM反馈
    
    I2CSendByte(addr);    //写入要存储的地址
    I2CWaitAck();             //等待EEPROM反馈
    
    while(num--)
    {
        I2CSendByte(*EEPROM_String++);    //将要写入的信息写入
        I2CWaitAck();                                       //等待EEPROM反馈
        I2C_Delay(200);                                   //等待
    }
    
    I2CStop();
}

void EEPROM_Read(unsigned char* EEPROM_String,unsigned char addr,unsigned char num)
{
    I2CStart();
    I2CSendByte(0XA0);
    I2CWaitAck();
    
    I2CSendByte(addr);
    I2CWaitAck();
    
    I2CStart();
    I2CSendByte(0XA1);
    I2CWaitAck();
    
    while(num--)
    {
        *EEPROM_String++=I2CReceiveByte();
        if(num)
        {
            I2CSendAck(0);
        }
        else
        {
            I2CSendAck(1);
        }
    }
    
    I2CStop();
}

2.PCF8591芯片实现的AD/DA转换,代码如下:

unsigned char AD_Read(unsigned char addr)        //PCF8591 滑变 0X43 光敏 0X41;
{        
    unsigned char temp;
    I2CStart();
    I2CSendByte(0x90);        //告诉PCF8591开始读
    I2CWaitAck();
    
    I2CSendByte(addr);        //告诉PCF8591哪里开始读
    I2CWaitAck();
    
    I2CStart();
    I2CSendByte(0x91);
    I2CWaitAck();
    
    temp=I2CReceiveByte();
    I2CSendAck(1);                //读出来后发送非应答信号 因为只需要读一次
    I2CStop();
    
    return temp;
}

void DA_Write(unsigned char addr)
{
    I2CStart();
    I2CSendByte(0x90);
    I2CWaitAck();
    I2CSendByte(0X41);
    I2CWaitAck();  
    I2CSendByte(addr);
    I2CWaitAck();
    I2CStop();
}

3.按键导致的状态改变应该单独设置变量。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值