本文主要是介绍第十一届蓝桥杯单片机组省赛赛题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目
程序
官方已给出的底层驱动代码就不再陈列,其中iic.c文件的IIC_Delay函数以及iic.h文件需要做一些更改,已经给出。
iic.h
这里由于工程用不到IIC_SendAck函数,就将其注释掉,这样编译器就不会报warning。
#ifndef __IIC_H_
#define __IIC_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); unsigned char adc_pcf(void);
void eeprom_wr(unsigned char adr,unsigned char date);
unsigned char eeprom_re(unsigned char adr);#endif
iic.c
#include "intrins.h"void IIC_Delay(unsigned char i)
{do{_nop_();}while(i--);
}unsigned char adc_pcf(void)
{unsigned char date;IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x43);IIC_WaitAck();IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();date = IIC_RecByte();IIC_WaitAck();IIC_Stop();return date;
}void eeprom_wr(unsigned char adr,unsigned char date)
{EA = 0;IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(adr);IIC_WaitAck();IIC_SendByte(date);IIC_WaitAck();IIC_Stop();EA = 1;
}unsigned char eeprom_re(unsigned char adr)
{unsigned char date;EA = 0;IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(adr);IIC_WaitAck();IIC_Start();IIC_SendByte(0xa1);IIC_WaitAck();date = IIC_RecByte();IIC_WaitAck();IIC_Stop();EA = 1;return date;
}
other.h
主要存放了关闭外设,数码管驱动,定时器初始化,按键扫描,延时函数。
#ifndef __OTHER_H_
#define __OTHER_H_#include <stc15f2k60s2.h>void Delay2ms(void);
unsigned char seg_tran(int number);
void seg_disp(int adr,int number);
void seg_disp_f(int adr,int number);
int key_scan(void);
void close_perl(void);
void Timer0Init(void);#endif
other.c
#include <other.h>void Delay2ms(void) //@11.0592MHz
{unsigned char i, j;i = 22;j = 128;do{while (--j);} while (--i);
}unsigned char seg_tran(int number)
{unsigned char date;switch(number){case 0 : date = 0xc0 ; break;case 1 : date = 0xf9 ; break;case 2 : date = 0xa4 ; break;case 3 : date = 0xb0 ; break;case 4 : date = 0x99 ; break;case 5 : date = 0x92 ; break;case 6 : date = 0x82 ; break;case 7 : date = 0xf8 ; break;case 8 : date = 0x80 ; break;case 9 : date = 0x90 ; break;case 10 : date = 0xbf ; break;//-case 11 : date = 0xc6 ; break;//ccase 12 : date = 0x8c ; break;//pcase 13 : date = 0x86 ; break;//ecase 14 : date = 0xc7 ; break;//Lcase 15 : date = 0xc8 ; break;//acase 16 : date = 0xc1 ; break;//U}return date;
}void seg_disp(int adr,int number)
{unsigned char seg_adr[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};P2 = P2&0x1f|0xe0;P2 = P2&0x1f;P0 = seg_adr[adr];P2 = P2&0x1f|0xc0;P2 = P2&0x1f;P0 = seg_tran(number);P2 = P2&0x1f|0xe0;P2 = P2&0x1f;
}void seg_disp_f(int adr,int number)
{unsigned char seg_adr[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};P2 = P2&0x1f|0xe0;P2 = P2&0x1f;P0 = seg_adr[adr];P2 = P2&0x1f|0xc0;P2 = P2&0x1f;P0 = seg_tran(number)&0x7f;P2 = P2&0x1f|0xe0;P2 = P2&0x1f;
} int key_scan(void)
{int key,key_mark;P3 = 0x0f;P44 = 0;P42 = 1;P35 = 1;P34 = 1;key = P3;P44 = 1;P42 = 0;key = (key<<4)|(P3&0x0f);P42 = 1;P35 = 0;key = (key<<4)|(P3&0x0f);P35 = 1;P34 = 0;key = (key<<4)|(P3&0x0f);switch(~key){case 0x8000: key_mark = 4;break; case 0x4000: key_mark = 5;break; case 0x2000: key_mark = 6;break; case 0x1000: key_mark = 7;break; case 0x0800: key_mark = 8;break; case 0x0400: key_mark = 9;break; case 0x0200: key_mark = 10;break; case 0x0100: key_mark = 11;break; case 0x0080: key_mark = 12;break; case 0x0040: key_mark = 13;break; case 0x0020: key_mark = 14;break; case 0x0010: key_mark = 15;break; case 0x0008: key_mark = 16;break; case 0x0004: key_mark = 17;break; case 0x0002: key_mark = 18;break; case 0x0001: key_mark = 19;break; default : key_mark = 0 ;break;//这句很重要,必须有!}return key_mark;
}void close_perl(void)
{P0 = 0xff;P2 = P2&0x1f|0x80;P2 = P2&0x1f;P0 = 0x00;P2 = P2&0x1f|0xa0;P2 = P2&0x1f;
}void Timer0Init(void) //10毫秒@11.0592MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0x00; //设置定时初值TH0 = 0xDC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0 = 1;EA = 1;
}
main.c
#include <other.h>
#include <iic.h>#define Led1 0x01
#define Led2 0x02
#define Led3 0x04unsigned int key_nosymbol = 0;
unsigned int count;
unsigned int p_bigger_times;unsigned char key_old;unsigned char show_mode;int c_vol_100 = 0;
int c_vol_10;
int vol_100;
float vol_f;
unsigned char adc;
bit count_on;
bit led1_ok;void key_pro(void)
{unsigned char key_down,key_vol;key_vol = key_scan();key_down = key_vol&(key_vol^key_old);key_old = key_vol;switch(key_down){case 12:show_mode ++;if(show_mode == 3) {show_mode = 0;eeprom_wr(0x00,c_vol_10);}key_nosymbol = 0;break;case 13:if(show_mode == 2) {count = 0;key_nosymbol = 0;}else key_nosymbol ++;break;case 16:if(show_mode == 1) {c_vol_100 = c_vol_100 + 50;if(c_vol_100 == 550) c_vol_100 = 0;key_nosymbol = 0;}elsekey_nosymbol ++;break;case 17:if(show_mode == 1) {c_vol_100 = c_vol_100 - 50;if(c_vol_100 < 0) c_vol_100 = 500;key_nosymbol = 0;}elsekey_nosymbol ++;break;}
}void seg_pro(void)
{adc = adc_pcf();vol_f = (float)adc/255*5.00;vol_100 = vol_f*100;c_vol_10 = c_vol_100/10;if((count_on == 1)&&(vol_100 <= c_vol_100)){count = count + 1;count_on = 0;}else count_on = 0;if(vol_100 > c_vol_100){count_on = 1;}seg_disp(1,count_on);Delay2ms();switch(show_mode){case 0:seg_disp(0,16); Delay2ms();seg_disp_f(5,vol_100/100); Delay2ms();seg_disp(6,vol_100%100/10); Delay2ms();seg_disp(7,vol_100%10); Delay2ms();break;case 1:seg_disp(0,12); Delay2ms();seg_disp_f(5,c_vol_100/100); Delay2ms();seg_disp(6,c_vol_100%100/10); Delay2ms();seg_disp(7,c_vol_100%10); Delay2ms();break;case 2:seg_disp(0,15); Delay2ms();if(count > 1000) seg_disp(4,count/1000); Delay2ms();if(count > 100) seg_disp(5,count%1000/100); Delay2ms();if(count > 10) seg_disp(6,count%100/10); Delay2ms();seg_disp(7,count%10); Delay2ms();break;}
}void led_pro(void)
{P0 = 0xff;if(count%2 != 0) //计数值为奇数时,L2亮{P0 = P0&(~Led2);P2 = P2&0x1f|0x80;P2 = P2&0x1f;}else{P0 = P0|(Led2);P2 = P2&0x1f|0x80;P2 = P2&0x1f;}if(led1_ok == 1) //p > can 超过5s led1亮{P0 = P0&(~Led1);P2 = P2&0x1f|0x80;P2 = P2&0x1f;p_bigger_times = 0; }else{P0 = P0|(Led1);P2 = P2&0x1f|0x80;P2 = P2&0x1f;}if(key_nosymbol == 3){P0 = P0&(~Led3);P2 = P2&0x1f|0x80;P2 = P2&0x1f;}else{P0 = P0|(Led3);P2 = P2&0x1f|0x80;P2 = P2&0x1f;}
}void main(void)
{Timer0Init();close_perl();c_vol_100 = eeprom_re(0x00)*10;while(1){key_pro();seg_pro();led_pro();}
}void timer0(void) interrupt 1
{if(vol_100 > c_vol_100){p_bigger_times ++;if(p_bigger_times >= 500){led1_ok = 1;}}else {led1_ok = 0;p_bigger_times = 0;}
}
由于图快,就没有写注释,有问题或者觉得哪里写的不完美可以在评论区直接提出或私信,本小白csdn常在线。
这篇关于第十一届蓝桥杯单片机组省赛赛题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!