前言:4T官网第一套模拟题,也是省赛难度,里面仅有的新意也没有什么启示性的意义,权当练手
题目
个人理解和分析
把按键用了大半,也就意味着其他很多可考的模块没办法考,而且涉及一些重复的编程操作,比如其中的按键输入,这时候按键输入就得有个模块化的操作。
评测对EEPROM地址的检测说明不清晰,一个是用十六进制表示,一个是用十进制(时间我以为直接用BCD码存)导致扣了一点点分,其他模块检测都没有问题。
本次代码也比较简单,我也不做演示了。
底层驱动代码
IIC(我我的EEPROM读取只用于上电和调试)
void eepromwrite(unsigned char channel,unsigned char dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(channel);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned int eepromread(unsigned char channel){
unsigned int ret;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(channel);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
ret = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return ret;
}
DS1302
void ds1302config(){
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i = 0;i < 3;i++){
Write_Ds1302_Byte(ds1302writeaddr[i],rtctime[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void ds1302read(){
unsigned char i;
for(i = 0;i < 3;i++){
rtctime[i] = Read_Ds1302_Byte(ds1302readaddr[i]);
}
}
主程序核心代码
注:我已经修改了对于EEPROM时间存储要求BCD码转十进制的问题
#include <STC15F2K60S2.H>
#include "iic.h"
#include "inithc138.h"
#include "delay.h"
#include "ds1302.h"
#define de 5
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf
};
unsigned char show = 0;//显示界面切换
unsigned char ds1302readaddr[3] = {0x81,0x83,0x85};
unsigned char ds1302writeaddr[3] = {0x80,0x82,0x84};
unsigned char rtctime[3] = {0x59,0x09,0x23};
unsigned char mima[4] = {16,16,16,16};
unsigned char qishishijian[3] = {0x00};
bit shuru = 0;//正在输入中
unsigned char pos = 0;//当前正在输入的位数
bit wancheng = 0;//输入完成
unsigned int tmp[20] = {0};//存储之前的
unsigned char cishu = 0;
bit da = 0;//这次比上次大
unsigned char ledstat = 0xff;//led状态
//***************************************DS1302实时时钟
void ds1302config(){
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i = 0;i < 3;i++){
Write_Ds1302_Byte(ds1302writeaddr[i],rtctime[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void ds1302read(){
unsigned char i;
for(i = 0;i < 3;i++){
rtctime[i] = Read_Ds1302_Byte(ds1302readaddr[i]);
}
}
//***************************************
//***************************************显示界面
void shijianjiemian(){//时间界面
showsmg(8,Seg_Table[rtctime[0] % 16]);
showsmg(7,Seg_Table[rtctime[0] / 16]);
showsmg(6,Seg_Table[16]);
showsmg(5,Seg_Table[rtctime[1] % 16]);
showsmg(4,Seg_Table[rtctime[1] / 16]);
showsmg(3,Seg_Table[16]);
showsmg(2,Seg_Table[rtctime[2] % 16]);
showsmg(1,Seg_Table[rtctime[2] / 16]);
}
void showsmgmima(unsigned char pos,unsigned char dat){
if(dat == 16){
showsmg(pos,0xff);
}else{
showsmg(pos,Seg_Table[dat]);
}
}
void shurujiemian(){//输入界面
showsmg(1,Seg_Table[12]);
showsmgmima(8,mima[0]);
showsmgmima(7,mima[1]);
showsmgmima(6,mima[2]);
showsmgmima(5,mima[3]);
}
void jilushijian(){
if((mima[0] != 16) && (shuru == 0)){
shuru = 1;
qishishijian[0] = (rtctime[0] / 16 * 10) + rtctime[0] % 16;
qishishijian[1] = (rtctime[1] / 16 * 10) + rtctime[1] % 16;
qishishijian[2] = (rtctime[2] / 16 * 10) + rtctime[2] % 16;
eepromwrite(0x00,qishishijian[2]);
Delay(2);
eepromwrite(0x01,qishishijian[1]);
Delay(2);
}
}
void jilujiemian(){//记录界面
showsmg(1,Seg_Table[14]);
if(shuru){
showsmg(8,Seg_Table[qishishijian[1] % 16]);
showsmg(7,Seg_Table[qishishijian[1] / 16]);
showsmg(6,Seg_Table[16]);
showsmg(5,Seg_Table[qishishijian[2] % 16]);
showsmg(4,Seg_Table[qishishijian[2] / 16]);
}
}
/*void eeprom(){
unsigned char huancun;
huancun = eepromread(0x03);
showsmg(8,Seg_Table[huancun % 16]);
showsmg(7,Seg_Table[huancun / 16]);
huancun = eepromread(0x02);
showsmg(6,Seg_Table[huancun % 16]);
showsmg(5,Seg_Table[huancun / 16]);
huancun = eepromread(0x01);
showsmg(4,Seg_Table[huancun % 16]);
showsmg(3,Seg_Table[huancun / 16]);
huancun = eepromread(0x00);
showsmg(2,Seg_Table[huancun % 16]);
showsmg(1,Seg_Table[huancun / 16]);
}*/
//***************************************
//***************************************
void showselect(){
switch(show){
case 0:shijianjiemian();break;
case 1:shurujiemian();break;
case 2:jilujiemian();break;
//case 3:eeprom();break;
}
}
//***************************************
//***************************************按键扫描
void shurushuzi(unsigned char num){//密码输入通法
if(pos < 4){
mima[3] = mima[2];
mima[2] = mima[1];
mima[1] = mima[0];
mima[0] = num;
}
pos++;
if(pos > 4){pos = 4;}
}
void qingchu(){//清除
unsigned char i;
for(i = 0;i < 4;i++){
mima[i] = 16;
}
pos = 0;
shuru = 0;
wancheng = 0;
}
void scankey(){
P33 = 0;P32 = 1;P31 = 1;P30 = 1;
P44 = 1;P42 = 1;P35 = 1;P34 = 1;
if(P44 == 0){Delay(de);while(P44 == 0){showselect();}//S4
show++;
show %= 3;
if(show == 0){
qingchu();
}
}
if(show == 1){
if(P42 == 0){Delay(de);while(P42 == 0){showselect();}//S4
shurushuzi(7);//S8为7
}
if(P35 == 0){Delay(de);while(P35 == 0){showselect();}//S4
shurushuzi(8);//S12为8
}
if(P34 == 0){Delay(de);while(P34 == 0){showselect();}//S4
shurushuzi(9);//S16为9
}
}
P33 = 1;P32 = 0;P31 = 1;P30 = 1;
P44 = 1;P42 = 1;P35 = 1;P34 = 1;
if(show == 1){
if(P44 == 0){Delay(de);while(P44 == 0){showselect();}//S4
qingchu();
}
if(P42 == 0){Delay(de);while(P42 == 0){showselect();}//S4
shurushuzi(4);//S9为4
}
if(P35 == 0){Delay(de);while(P35 == 0){showselect();}//S4
shurushuzi(5);//S13为5
}
if(P34 == 0){Delay(de);while(P34 == 0){showselect();}//S4
shurushuzi(6);//S17为6
}
}
P33 = 1;P32 = 1;P31 = 0;P30 = 1;
P44 = 1;P42 = 1;P35 = 1;P34 = 1;
if(show == 1){
if(P44 == 0){Delay(de);while(P44 == 0){showselect();}//S4
shurushuzi(0);//S6为0
}
if(P42 == 0){Delay(de);while(P42 == 0){showselect();}//S4
shurushuzi(1);//S10为1
}
if(P35 == 0){Delay(de);while(P35 == 0){showselect();}//S4
shurushuzi(2);//S14为2
}
if(P34 == 0){Delay(de);while(P34 == 0){showselect();}//S4
shurushuzi(3);//S18为6
}
}
}
//***************************************
//***************************************
void shujubijiao(){//比较
if(cishu > 1){
if(tmp[cishu - 1] > tmp[cishu - 2]){
da = 1;
}else{
da = 0;
}
}
}
void shujucunchu(){
unsigned char huancun;
if((pos >= 4) && (wancheng == 0)){
wancheng = 1;
tmp[cishu] = mima[0] + mima[1]*10 + mima[2]*100 +mima[3]*1000;
huancun = tmp[cishu] / 256;
eepromwrite(0x02,huancun);
Delay(2);
huancun = tmp[cishu] % 256;
eepromwrite(0x03,huancun);
Delay(2);
cishu++;
}
}
//***************************************
//***************************************LED
void led(){
if(show == 0){
ledstat = ledstat & ~0x01;
}else{
ledstat = ledstat | 0x01;
}
if(show == 1){
ledstat = ledstat & ~0x02;
}else{
ledstat = ledstat | 0x02;
}
if(show == 2){
ledstat = ledstat & ~0x04;
}else{
ledstat = ledstat | 0x04;
}
if(da){
ledstat = ledstat & ~0x08;
}else{
ledstat = ledstat | 0x08;
}
outputp0(4,ledstat);
}
//***************************************
void main(){
ds1302config();
initsys();
while(1){
jilushijian();
ds1302read();
showselect();
scankey();
shujucunchu();
shujubijiao();
showselect();
led();
}
}