【冉冰的成长日记003】
课设耽误的,可不怪我咕!!
先说程序的问题,我感觉不到那个亮度等级变化的区别,好似有又好似没有0.0。。。。。
第二,按键的刷新和LED模块有冲突,需要长按按键才好使。。。
其他没啥了,,,就这样吧
看看代码吧,据说分块写也并不能使变量增加,我就还是写到一个main.c里了,不要跟我学,hhhh
#include<STC15F2K60S2.h>
#include<iic.h>
#include "intrins.h"
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
unsigned char code LED[]={ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF ,0xFF ,0xC6};//数码管
unsigned char LEDbuff[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; //数码管缓冲区
unsigned char code LED_M1[]={ 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
unsigned char code LED_M2[]={ 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE};
unsigned char code LED_M3[]={ 0x7E, 0xBD, 0xDB, 0xE7};
unsigned char code LED_M4[]={ 0xE7, 0xDB, 0xBD, 0x7E};
unsigned int cnt=0,num=0,clock=0;//中断计时
unsigned char AD=0,PWM_flag=0;//AD获取模拟量,PWM_flag用于亮度显示
unsigned int EEPROM,EEPROM_flag=6;//EEPROM用于设置流转时间间隔
bit S7_start=0,S7_LED=0;//S7_LED停止和启动led ,S7_start用于数码管启动
unsigned char S6_M=1,S6_flag=0; // S6_M模式切换模式,S6_flag用于切换运行和间隔两个单元
bit check_S7=0,check_S6=0,check_S5=0,check_S4=0,Fl=0;//check用来按键消抖,Fl用来选中是以0.8s闪烁
void Timer0Init(); //定时器0,1ms
void Initial(); //模块初始化
void KEY(); //按键模块,包括S7.S6.S5.S4
void Display_3(); //数码管模块
void delay(unsigned int x); //延时函数
void Get(); //每次上电后读取EEPROM内的数据,判断是否在4-12之间,如果在就不需要改变,如果不在默认重装初值为4,,
//我觉得这个思想好厉害,20级的大佬讲给我听的(p.s.:其实是大四的学长讲给他听的)
void LED_1();//彩虹灯的四种模式
void main()
{
Timer0Init();
Initial(); //初始化函数
AD_Init(); //AD初始化
Get();
while(1)
{
delay(5);
EEPROM_Write(0x01,EEPROM_flag); //将每次变化后的值再写入EEPROM内
if(clock>=500)
{
AD=AD_Get(); //AD值读取
clock=0;
}
KEY();
Display_3();
LED_1();
}
}
void delay(unsigned int x) //延时函数,ms单位
{
int X=0,Y=0;
for(X=0;X<x;X++)
{
for(Y=846;Y>0;Y--);
}
}
void Get()
{
EEPROM_flag = EEPROM_Get(0x01);
if(EEPROM_flag<=4||EEPROM_flag>=12) EEPROM_flag=4;
}
void Initial() //初始化函数
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFF; //初始化LED
P2 = (P2&0x1F)|0xA0;
P0 = 0x00; //初始化继电器和蜂鸣器
P2 = (P2&0x1F)|0xC0;
P0 = 0xFF;
P2 = (P2&0x1F)|0xE0;
P0 = 0xFF; //初始化数码管
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;
ET0 = 1;
}
void Display_1() //把数码管拆成前四位和后四位,方便管理
{
LEDbuff[7] = LED[10];
LEDbuff[6] = LED[S6_M];
LEDbuff[5] = LED[10];
LEDbuff[4] = LED[11];
}
void Display_2()
{
if(EEPROM/1000==0) LEDbuff[3] = LED[11];
else LEDbuff[3] = LED[EEPROM/1000];
LEDbuff[2] = LED[EEPROM/100%10];
LEDbuff[1] = LED[EEPROM/10%10];
LEDbuff[0] = LED[EEPROM%10];
}
void LED_1() //写成for语句和按键冲突,只好改变成switch语句了,即便如此,按键也需要长按才能百分百起作用
{
static unsigned char j=0;
if(S6_M==1&&S7_LED==1)
{
switch(j)
{
case 0:P2 = 0x80;P0 = LED_M1[0];j++;delay(EEPROM);break;
case 1:P2 = 0x80;P0 = LED_M1[1];j++;delay(EEPROM);break;
case 2:P2 = 0x80;P0 = LED_M1[2];j++;delay(EEPROM);break;
case 3:P2 = 0x80;P0 = LED_M1[3];j++;delay(EEPROM);break;
case 4:P2 = 0x80;P0 = LED_M1[4];j++;delay(EEPROM);break;
case 5:P2 = 0x80;P0 = LED_M1[5];j++;delay(EEPROM);break;
case 6:P2 = 0x80;P0 = LED_M1[6];j++;delay(EEPROM);break;
case 7:P2 = 0x80;P0 = LED_M1[7];j=0;delay(EEPROM);break;
default : break;
}
}
if(S6_M==2&&S7_LED==1)
{
switch(j)
{
case 0:P2 = 0x80;P0 = LED_M2[0];j++;delay(EEPROM);break;
case 1:P2 = 0x80;P0 = LED_M2[1];j++;delay(EEPROM);break;
case 2:P2 = 0x80;P0 = LED_M2[2];j++;delay(EEPROM);break;
case 3:P2 = 0x80;P0 = LED_M2[3];j++;delay(EEPROM);break;
case 4:P2 = 0x80;P0 = LED_M2[4];j++;delay(EEPROM);break;
case 5:P2 = 0x80;P0 = LED_M2[5];j++;delay(EEPROM);break;
case 6:P2 = 0x80;P0 = LED_M2[6];j++;delay(EEPROM);break;
case 7:P2 = 0x80;P0 = LED_M2[7];j=0;delay(EEPROM);break;
default : break;
}
}
if(S6_M==3&&S7_LED==1)
{
if(j>=4) j =0;
switch(j)
{
case 0:P2 = 0x80;P0 = LED_M3[0];j++;delay(EEPROM);break;
case 1:P2 = 0x80;P0 = LED_M3[1];j++;delay(EEPROM);break;
case 2:P2 = 0x80;P0 = LED_M3[2];j++;delay(EEPROM);break;
case 3:P2 = 0x80;P0 = LED_M3[3];j=0;delay(EEPROM);break;
default : break;
}
}
if(S6_M==4&&S7_LED==1)
{
if(j>=4) j =0;
switch(j)
{
case 0:P2 = 0x80;P0 = LED_M4[0];j++;delay(EEPROM);break;
case 1:P2 = 0x80;P0 = LED_M4[1];j++;delay(EEPROM);break;
case 2:P2 = 0x80;P0 = LED_M4[2];j++;delay(EEPROM);break;
case 3:P2 = 0x80;P0 = LED_M4[3];j=0;delay(EEPROM);break;
default : break;
}
}
if(S7_LED==0)
{
P2 = (P2&0x1F)|0x80; P0 = 0xFF;
}
}
void Display_1_2() //数码管闪烁时的灭的状态
{
LEDbuff[7] = LED[11];
LEDbuff[6] = LED[11];
LEDbuff[5] = LED[11];
LEDbuff[4] = LED[11];
}
void Display_2_2() //数码管闪烁时的灭的状态
{
LEDbuff[3] = LED[11];
LEDbuff[2] = LED[11];
LEDbuff[1] = LED[11];
LEDbuff[0] = LED[11];
}
void Display_PWM() //S4按键按下时的亮度等级
{
LEDbuff[1] = LED[10];
LEDbuff[0] = LED[PWM_flag];
}
void Display_3()
{
if(S7_start==1&&S6_flag==0) { Display_1();Display_2();}
if(S7_start==1&&S6_flag==1) { Display_1_2();Display_2_2();}
if(S7_start==1&&S6_flag==2)
{
if(Fl==0) { Display_1();Display_2();}
if(Fl==1) { Display_1_2();Display_2();}
}
if(S7_start==1&&S6_flag==3)
{
if(Fl==0) { Display_1();Display_2();}
if(Fl==1) { Display_1();Display_2_2();}
}
}
void KEY_S7()
{
if(S7==0)
{
delay(5);
if(S7==0)
check_S7=1;
}
if((S7==1)&&(check_S7==1))
{
check_S7 = 0;
S7_start = 1;
S7_LED = ~S7_LED;
}
}
void KEY_S6()
{
if(S6==0)
{
delay(5);
if(S6==0)
check_S6=1;
}
if((S6==1)&&(check_S6==1))
{
check_S6=0;
S6_flag++;
if(S6_flag>=4)
S6_flag=0;
}
}
void KEY_S5()
{
if(S5==0)
{
delay(5);
if(S5==0)
check_S5=1;
}
if((S5==1)&&(check_S5==1))
{
check_S5=0;
if(S6_flag==2)
{
S6_M++;
if(S6_M>=5)
S6_M=1;
}
if(S6_flag==3)
{
EEPROM_flag++;
if(EEPROM_flag>=13)
EEPROM_flag=4;
}
}
}
void KEY_S4()
{
if(S4==0)
{
delay(5);
if(S4==0)
check_S4=1;
}
if((S4==1)&&(check_S4==1))
{
check_S4=0;S7_start=1;
if(S6_flag==2)
{
S6_M--;
if(S6_M<=0)
S6_M=3;
}
if(S6_flag==3)
{
EEPROM_flag--;
if(EEPROM_flag<=4)
EEPROM_flag=12;
}
}
if(S4==0&&S6_flag==0)
{ S7_start=0;Display_PWM();}
}
void KEY()
{
KEY_S4();
KEY_S5();
KEY_S6();
KEY_S7();
}
void PWM()
{
if(AD>=0&&AD<64) PWM_flag=1;
if(AD>=64&&AD<128) PWM_flag=2;
if(AD>=128&&AD<192) PWM_flag=3;
if(AD>=192&&AD<256) PWM_flag=4;
if(PWM_flag==1&&S7_start==1)
{
if(cnt<=EEPROM*0.25) S7_LED=1;
if(cnt>=EEPROM*0.25&&cnt<=EEPROM) S7_LED=0;
cnt=0;
}
if(PWM_flag==2&&S7_start==1)
{
if(cnt<=EEPROM*0.5) S7_LED=1;
if(cnt>=EEPROM*0.5&&cnt<=EEPROM) S7_LED=0;
cnt=0;
}
if(PWM_flag==3&&S7_start==1)
{
if(cnt<=EEPROM*0.75) S7_LED=1;
if(cnt>=EEPROM*0.75&&cnt<=EEPROM) S7_LED=0;
cnt=0;
}
}
void InterruptTimer0() interrupt 1
{
static unsigned char i=0,j=0;
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
if(S7_start==1)
{
switch(i)
{
case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];P2=0x00;i++;break;
case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];P2=0x00;i++;break;
case 2:P2 = 0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];P2=0x00;i++;break;
case 3:P2 = 0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];P2=0x00;i++;break;
case 4:P2 = 0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];P2=0x00;i++;break;
case 5:P2 = 0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];P2=0x00;i++;break;
case 6:P2 = 0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];P2=0x00;i++;break;
case 7:P2 = 0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];P2=0x00;i=0;break;
default : break;
}
}
if(S7_start==0&&S4==0)
{
switch(j)
{
case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];P2=0x00;j++;break;
case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];P2=0x00;j=0;break;
default : break;
}
}
EEPROM= EEPROM_flag*100; //EEPROM写成4-12方便获取初值,不需要高八位低八位的或运算
cnt++;clock++;
num++;if(num>=800){ num=0;Fl=~Fl;}
PWM();
}
嗯,我觉得我写的超级短,而且满简洁的,就是按键需要长按,要不好使的很,上方是main.c文件
#include<STC15F2K60S2.h>
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Delay(unsigned char i)
{
do{ _nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
void AD_Init() //AD初始化
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_Stop();
}
unsigned char AD_Get() //AD获取
{
unsigned char temp=0;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
void EEPROM_Write(unsigned char add,unsigned char dat) //EEPROM数据写入
{
IIC_Start();
IIC_SendByte(0xA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char EEPROM_Get(unsigned char add) //EEPROM数据读取
{
unsigned char temp =0;
IIC_Start();
IIC_SendByte(0xA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xA1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
iic里写了EEPROM和AD的内容,应该没人需要看,还是放上吧。。。。
#ifndef _IIC_H
#define _IIC_H
sbit SDA = P2^1;
sbit SCL = P2^0;
#include<STC15F2K60S2.h>
#include "intrins.h"
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void AD_Init();
unsigned char AD_Get();
void EEPROM_Write(unsigned char add,unsigned char dat);
unsigned char EEPROM_Get(unsigned char add);
#endif
IIC.h文件。。。。。。。
其实写了好久,还是太差了,就这吧,感谢观看