#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.按键导致的状态改变应该单独设置变量。