蓝桥杯单片机学习过程记录(十七)第九届彩灯控制器
错误提示:
WARNING L5: CODE SPACE MEMORY OVERLAP
地址重叠。两个定时器重名,interrupt都用了1,一直报警告。
然后不得不说,从历年省赛来看,单片机是越来越难了,从开始到完成差不多正好比赛时间,包括吃饭啊啥的,比往届感觉要难,中间出了一个问题,因为审题不清楚,一开始只用了一个eep进行存储状态,后来分析,应该是4个模式下的小灯分别对应着一个流转间隔,又重新改了一下,头都大了,4个寄存器用数组来表示,但是重复的东西太多,超级繁琐,后续慢慢学习进行改进,放进函数里应该会好很多。用了两个定时器,一个控制小灯模式和亮度,另一个控制设置时得闪烁。在进行设置模式的流转间隔时,分别用中间变量进行存储。
应用内容:
数码管、LED小灯
独立按键、定时器
EEPROM寄存器存写读取
滑动变阻器IIC的读取
主函数:
//第九届彩灯控制
#include<STC15F2K60S2.H>
#include<iic.h>
sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
unsigned char led_count;
unsigned char flag_yemian=1,s6_flag,flag_set;
char led_mode=1,count_mode,led_mode_temp,led_light_mode=1;
unsigned char seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
unsigned char eep[4];
unsigned char yi,er,san,si,wu,liu,qi,ba;
unsigned char t_0,t,t_1;
int dianya,eep_temp,count_eep;
void allinit();
void delayms(int ms);
void display_12(yi,er);
void display_34(san,si);
void display_56(wu,liu);
void display_78(qi,ba);
void key_scan();
void Timer0Init();
void Timer1Init();
unsigned char iic_read();
unsigned char eep_read(add);
void eep_write(add,dat);
void led_light();
void main(){
//初始化
allinit();
Timer0Init();Timer1Init();
EA=1;ET0=1;ET1=1;
//四个寄存器
eep[0]=eep_read(0x10);eep[1]=eep_read(0x20);
eep[2]=eep_read(0x40);eep[3]=eep_read(0x80);
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;
while(1){
dianya=iic_read();
dianya=dianya*2;
//亮度等级判断
led_light();
//eep中间暂存
eep_temp=count_eep+eep;
//设置页面模式及间隔
if(flag_yemian==1){
//选择模式
if(s6_flag==1){
//模式中间暂存
led_mode_temp=(led_mode+count_mode)%4;
if(led_mode_temp==0)
led_mode_temp=4;
if(flag_set==0){
//亮
switch(led_mode_temp){
case 1: yi=10;er=led_mode_temp;san=10;si=11;wu=eep[0]/10;liu=eep[0]%10;qi=0;ba=0;break;
case 2: yi=10;er=led_mode_temp;san=10;si=11;wu=eep[1]/10;liu=eep[1]%10;qi=0;ba=0;break;
case 3: yi=10;er=led_mode_temp;san=10;si=11;wu=eep[2]/10;liu=eep[2]%10;qi=0;ba=0;break;
case 4: yi=10;er=led_mode_temp;san=10;si=11;wu=eep[3]/10;liu=eep[3]%10;qi=0;ba=0; break;
}
}
//灭
else {
switch(led_mode_temp){
case 1: yi=11;er=11;san=11;si=11;wu=eep[0]/10;liu=eep[0]%10;qi=0;ba=0;break;
case 2: yi=11;er=11;san=11;si=11;wu=eep[1]/10;liu=eep[1]%10;qi=0;ba=0;break;
case 3: yi=11;er=11;san=11;si=11;wu=eep[2]/10;liu=eep[2]%10;qi=0;ba=0;break;
case 4: yi=11;er=11;san=11;si=11;wu=eep[3]/10;liu=eep[3]%10;qi=0;ba=0; break;
}
}
}
//流转间隔设置
else if(s6_flag==2){
led_mode=led_mode_temp;
if(flag_set==0){
//进行边界的判断大于4小于12
switch(led_mode_temp){
case 1: yi=10;eep_temp=eep[0]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4){ eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=eep_temp/10;liu=eep_temp%10;qi=0;ba=0;break;
case 2: yi=10;eep_temp=eep[1]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4) {eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=eep_temp/10;liu=eep_temp%10;qi=0;ba=0;break;
case 3: yi=10;eep_temp=eep[2]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4) {eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=eep_temp/10;liu=eep_temp%10;qi=0;ba=0;break;
case 4: yi=10;eep_temp=eep[3]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4) {eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=eep_temp/10;liu=eep_temp%10;qi=0;ba=0;break;
}
}
else {
switch(led_mode_temp){
case 1: yi=10;eep_temp=eep[0]+count_eep;if(eep_temp>12){ eep_temp=12;count_eep=0;}
else if(eep_temp<4){ eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=11;liu=11;qi=0;ba=0;break;
case 2: yi=10;eep_temp=eep[1]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4) {eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=11;liu=11;qi=0;ba=0;break;
case 3: yi=10;eep_temp=eep[2]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4) {eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=11;liu=11;qi=0;ba=0;break;
case 4: yi=10;eep_temp=eep[3]+count_eep;if(eep_temp>12) {eep_temp=12;count_eep=0;}
else if(eep_temp<4) {eep_temp=4;count_eep=0;}er=led_mode_temp;san=10;si=11;wu=11;liu=11;qi=0;ba=0;break;
}
}
}
//熄灭数码管
else if(s6_flag==0){
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;
}
}
key_scan();
display_12(yi,er);
display_34(san,si);
display_56(wu,liu);
display_78(qi,ba);
}
}
按键设置
//按键
void key_scan(){
//s7控制小灯开关
if(s7==0){
delayms(5);
if(s7==0){
if(led_mode==0){
led_mode=1;led_count=0;
}
else{
led_mode=0;
P2=0X80;P0=0XFF;
}
}
while(!s7);
}
//s6控制设置选择
else if(s6==0){
delayms(5);
if(s6==0){
if(flag_yemian==1){
if(s6_flag==0){
s6_flag=1;
}
else if(s6_flag==1){
s6_flag=2;
}
else if(s6_flag==2){
//设置完成进行保存写入寄存器
switch(led_mode){
case 1:eep[0]=eep_temp;eep_write(0x10,eep[0]);break;
case 2:eep[1]=eep_temp;eep_write(0x20,eep[1]);break;
case 3:eep[2]=eep_temp;eep_write(0x40,eep[2]);break;
case 4:eep[3]=eep_temp;eep_write(0x80,eep[3]);break;
}
s6_flag=0;
count_mode=0;count_eep=0;
}
}
}
while(!s6);
}
//s5控制加
else if(s5==0){
delayms(5);
if(s5==0){
if(flag_yemian==1){
if(s6_flag==1){
count_mode++;
}
else if(s6_flag==2){
count_eep++;
}
}
}
while(!s5);
}
//s4控制减,在非设置时查看亮度
else if(s4==0){
delayms(5);
if(s4==0){
if(flag_yemian==1){
if(s6_flag==1){
count_mode--;
}
else if(s6_flag==2){
count_eep--;
}
}
}
while(!s4){
if(s6_flag==0){
yi=11;er=11;san=11;si=11;
wu=11;liu=11;qi=10;ba=led_light_mode;
display_12(yi,er);
display_34(san,si);
display_56(wu,liu);
display_78(qi,ba);
}
}
}
}
定时器判断和亮度等级判断
//定时器0设置,数码管闪烁控制
void time_0() interrupt 1{
t_0++;
if(t_0==160){
t_0=0;
if(flag_set==0)
flag_set=1;
else flag_set=0;
}
}
//定时器1设置,模式控制亮度和流转间隔
void time_1() interrupt 3{
t_1++;
t++;
if(t==5)
t=0;
//模式1
if(led_mode==1){
//控制亮度
if(t<led_light_mode){
P2=0X80;P0=~(0X01<<led_count);P2=P2&0X1F;
}
else{
P2=0X80;P0=0xff;
}
//控制流转间隔
if(t_1==20*eep[0]){
t_1=0;
P2=0X80;P0=~(0X01<<led_count);P2=P2&0X1F;
led_count++;
if(led_count==8){led_count=0;led_mode++;}
}
}
else if(led_mode==2){
//亮度
if(t<led_light_mode){
P2=0X80;P0=~(0X80>>led_count);P2=P2&0X1F;
}
else{
P2=0X80;P0=0xff;
}
//流转间隔
if(t_1==20*eep[1]){
t_1=0;
P2=0X80;P0=~(0X80>>led_count);P2=P2&0X1F;
led_count++;
if(led_count==8){
led_count=0;
led_mode++;
}
}
}
else if(led_mode==3){
//亮度
if(t<led_light_mode){
P2=0X80;P0=~((0X80>>led_count)|(0x01<<led_count));P2=P2&0X1F;
}
else{
P2=0X80;P0=0xff;
}
//流转间隔
if(t_1==20*eep[2]){
t_1=0;
P2=0X80;P0=~((0X80>>led_count)|(0x01<<led_count));
led_count++;
if(led_count==4){
led_count=0;
led_mode++;
}
}
}
else if(led_mode==4){
//亮度
if(t<led_light_mode){
P2=0X80;P0=~((0X10<<led_count)|(0x08>>led_count));P2=P2&0X1F;
}
else{
P2=0X80;P0=0xff;
}
//流转间隔
if(t_1==20*eep[3]){
t_1=0;
P2=0X80;P0=~((0X10<<led_count)|(0x08>>led_count));
led_count++;
if(led_count==4){
led_count=0;
led_mode++;
}
}
}
if(led_mode>4)
led_mode=1;
}
//亮度等级
void led_light(){
if(dianya<125){
led_light_mode=1;
}
else if(dianya<250){
led_light_mode=2;
}
else if(dianya<375){
led_light_mode=3;
}
else{
led_light_mode=4;
}
}
iic通信,eep读取和写入
//eep读取
unsigned char eep_read(add){
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
//eep写入
void eep_write(add,dat){
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//读取外部电压Rb2
unsigned char iic_read(){
unsigned int temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
初始化等设置
//定时器0,5ms
void Timer0Init(void)
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 = 0x00;
TH0 = 0x28;
TF0 = 0;
TR0 = 1;
}
//定时器1,5ms
void Timer1Init(void)
{
AUXR |= 0x40;
TMOD &= 0x0F;
TL1 = 0x00;
TH1 = 0x28;
TF1 = 0;
TR1 = 1;
}
void allinit(){
P2=0XA0;P0=0X00;
P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
P2=0X80;P0=0XFF;
}
void delayms(int ms){
int q,w;
for(q=0;q<ms;q++)
for(w=0;w<845;w++);
}
void display_12(yi,er){
P2=0XC0;P0=0X01;P2=0XE0;P0=seg[yi];
delayms(1);
P2=0XC0;P0=0X02;P2=0XE0;P0=seg[er];
delayms(1);
}
void display_34(san,si){
P2=0XC0;P0=0X04;P2=0XE0;P0=seg[san];
delayms(1);
P2=0XC0;P0=0X08;P2=0XE0;P0=seg[si];
delayms(1);
}
void display_56(wu,liu){
P2=0XC0;P0=0X10;P2=0XE0;P0=seg[wu];
delayms(1);
P2=0XC0;P0=0X20;P2=0XE0;P0=seg[liu];
delayms(1);
}
void display_78(qi,ba){
P2=0XC0;P0=0X40;P2=0XE0;P0=seg[qi];
delayms(1);
P2=0XC0;P0=0X80;P2=0XE0;P0=seg[ba];
delayms(1);
P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
delayms(1);
}