蓝桥杯单片机第四届初赛
代码部分(已实现题目要求的所有功能)
#include<stc15f2k60s2.h>
#include<intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
//总线引脚定义
sbit SDB = P2^1; /* 数据线 /
sbit SCL = P2^0; / 时钟线 */
#define somenop {nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();}
#define uint unsigned int
#define uchar unsigned char
uchar tab[]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0xFF,0XBF};
uchar shijian[]={0,30,8,0,0,0,0};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar control_set=0;
uchar shidu_set=0;
uchar add=0,delate=0;
uint yuzhi=50;
uint shidu,shidu_manual;
uchar water_set=0;
uchar alarm_set=0;
uchar huansuan,huansuan_manual;
void allint();
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void Delayms(uint ms);
void Write_Ds1302_Byte(unsigned char temp);
void Write_Ds1302(uchar address,uchar dat);
unsigned char Read_Ds1302(uchar address);
void DS1302_init();
void DS1302_Get();
void keyscan();
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(bit ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
uint AD_Read(uchar dat);
void EEPROM_Write(uchar add,uchar dat);
uint EEPROM_Read(uchar dat);
void main()
{
allint();
DS1302_init();
yi=0;er=8;san=10;si=5;wu=9;liu=10;qi=5;ba=0;
while(1)
{
keyscan();
shidu=AD_Read(0x03)39;
qi=shidu/1000;ba=shidu%1000/100;
huansuan=qi10+ba;
if(control_set0)
{
if(shidu_set0)
{
if(huansuan<yuzhi)
{
P2=0X80;P0=0XFE;
P2=0XA0;P0=0X10;
}
else
{
P2=0X80;P0=0XFF;
P2=0XA0;P0=0X00;
}
yi=11;er=11;san=10;si=10;wu=10;liu=10;
display1(yi,er);
display2(san,si);
display3(wu,liu);
display4(qi,ba);
}
else if(shidu_set==1) //在存储EEPROM这里遇见了问题(已解决)
{
if((add==1)&&(delate==0))
{
EEPROM_Write(0x01,yuzhi);Delayms(2); //必须要延时
yuzhi=EEPROM_Read(0x01);Delayms(2); //必须要延时
yuzhi++;Delayms(2); //必须要延时
add=0;
}
else if((delate==1)&&(add==0))
{
EEPROM_Write(0x01,yuzhi);Delayms(2); //必须要延时
yuzhi=EEPROM_Read(0x01);Delayms(2); //必须要延时
yuzhi--;Delayms(2); //必须要延时
delate=0;
}
yi=11;er=11;san=10;si=10;wu=10;liu=10;
qi=yuzhi/10;ba=yuzhi%10;
display1(yi,er);
display2(san,si);
display3(wu,liu);
display4(qi,ba);
}
}
else if(control_set==1)
{
DS1302_Get();
if(water_set==0)
{
P2=0X80;P0=0XFD;
shidu_manual=AD_Read(0x03)*39;
qi=shidu_manual/1000;ba=shidu_manual%1000/100;
huansuan_manual=qi*10+ba;
}
else if(water_set==1)
{
P2=0X80;P0=0XFF;
qi=shidu_manual/1000;ba=shidu_manual%1000/100;
huansuan_manual=qi*10+ba;
}
if(alarm_set==0)
{
if(huansuan_manual<yuzhi)
{
if(water_set==0)
{
P2=0XA0;P0=0X50;
}
else
{
P2=0XA0;P0=0X40;
}
}
else if(huansuan_manual>yuzhi)
{
P2=0XA0;P0=0X00;
}
yi=shijian[2]/10;er=shijian[2]%10;san=11;
si=shijian[1]/10;wu=shijian[1]%10;liu=10;
qi=shidu_manual/1000;ba=shidu_manual%1000/100;
display1(yi,er);
display2(san,si);
display3(wu,liu);
display4(qi,ba);
}
else if(alarm_set==1)
{
if(water_set==0)
{
P2=0XA0;P0=0X10;
}
else
{
P2=0XA0;P0=0X00;
}
yi=shijian[2]/10;er=shijian[2]%10;san=11;
si=shijian[1]/10;wu=shijian[1]%10;liu=10;
qi=shidu_manual/1000;ba=shidu_manual%1000/100;
display1(yi,er);
display2(san,si);
display3(wu,liu);
display4(qi,ba);
}
}
}
}
void allint()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
}
void display1(uchar yi,uchar er)
{
P2=0XC0;P0=0X01;P2=0XE0;P0=tab[yi];Delayms(1);
P2=0XC0;P0=0X02;P2=0XE0;P0=tab[er];Delayms(1);
}
void display2(uchar san,uchar si)
{
P2=0XC0;P0=0X04;P2=0XE0;P0=tab[san];Delayms(1);
P2=0XC0;P0=0X08;P2=0XE0;P0=tab[si];Delayms(1);
}
void display3(uchar wu,uchar liu)
{
P2=0XC0;P0=0X10;P2=0XE0;P0=tab[wu];Delayms(1);
P2=0XC0;P0=0X20;P2=0XE0;P0=tab[liu];Delayms(1);
}
void display4(uchar qi,uchar ba)
{
P2=0XC0;P0=0X40;P2=0XE0;P0=tab[qi];Delayms(1);
P2=0XC0;P0=0X80;P2=0XE0;P0=tab[ba];Delayms(1);
P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
}
void Delayms(uint ms) //@11.0592MHz
{
unsigned char i, j;
uint n;
for(n=0;n<ms;n++)
{
nop();
nop();
nop();
i = 11;
j = 190;
do
{
while (–j);
} while (–i);
}
}
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302(uchar address,uchar dat)
{
RST=0;
nop();
SCK=0;
nop();
RST=1;
nop();nop();nop();
Write_Ds1302_Byte(address);
Write_Ds1302_Byte((dat/10<<4)|dat%10);
RST=0;
}
unsigned char Read_Ds1302(uchar address)
{
unsigned char i,temp=0x00;
uchar dat1,dat2;
RST=0;
nop();
SCK=0;
nop();
RST=1;
nop();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++)
{
SCK=0;
nop();nop();
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
SDA=0;
dat1=temp/16;dat2=temp%16;
temp=dat1*10+dat2;
return (temp);
}
void DS1302_init()
{
uchar add,i;
add=0x80;
Write_Ds1302(0X8E,0X00);
for(i=0;i<7;i++)
{
Write_Ds1302(add,shijian[i]);
add=add+2;
}
Write_Ds1302(0X8E,0X80);
}
void DS1302_Get()
{
uchar add,i;
add=0x81;
Write_Ds1302(0X8E,0X00);
for(i=0;i<7;i++)
{
shijian[i]=Read_Ds1302(add);
add=add+2;
}
Write_Ds1302(0X8E,0X80);
}
void keyscan()
{
if(P300)
{
Delayms(5);
if(P300)
{
if(control_set0) control_set=1;
else if(control_set1) control_set=0;
}
while(!P30);
}
if(P310)
{
Delayms(5);
if(P310)
{
if(control_set0){if(shidu_set0) shidu_set=1;else if(shidu_set1) shidu_set=0;}
else if(control_set1){if(alarm_set0) alarm_set=1;else if(alarm_set1) alarm_set=0;}
}
while(!P31);
}
if(P32==0)
{
Delayms(5);
if(P32==0)
{
if(shidu_set==1)
{
add=1;delate=0;
}
else if(control_set==1) water_set=0;
}
while(!P32);
}
if(P33==0)
{
Delayms(5);
if(P33==0)
{
if(shidu_set==1)
{
delate=1;add=0;
}
else if(control_set==1) water_set=1;
}
while(!P33);
}
}
//总线启动条件
void IIC_Start(void)
{
SDB = 1;
SCL = 1;
somenop;
SDB = 0;
somenop;
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDB = 0;
SCL = 1;
somenop;
SDB = 1;
}
//应答位控制
void IIC_Ack(bit ackbit)
{
if(ackbit)
{
SDB = 0;
}
else
{
SDB = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDB = 1;
somenop;
}
//等待应答
bit IIC_WaitAck(void)
{
SDB = 1;
somenop;
SCL = 1;
somenop;
if(SDB)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDB = 1;
}
else
{
SDB = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDB)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
uint AD_Read(uchar dat)
{
uint temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
uint EEPROM_Read(uchar dat)
{
uint temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Ack(1);
IIC_Stop();
return temp;
}
void EEPROM_Write(uchar add,uchar dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
**
小结:写了大概七八个小时,写写停停,个人感觉比上一届初赛题目难了不少。在这里里一个flag,每天做一遍赛题一直做到初赛!