第四届考查了PCF8591的ADC采集、at24c02的读写操作和ds1302的时钟显示
主要的难点我觉得是手动模式下的蜂鸣器和继电器的使用冲突,巧设标志位来进行执行不同的开关。
代码风格学习大科的,相对简单通俗易懂。
主函数
#include <STC15F2K60S2.H>
#include "iic.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
void delayms(int ms);
void display1(uchar yi,uchar er,uchar san,uchar si);
void display2(uchar wu,uchar liu,uchar qi,uchar ba);
void writetime();
void readtime();
void keyscan();
uchar ADread(uchar add);
void iicwrite(uchar add,uchar dat);
uchar iicread(uchar add);
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar time[]={0,30,8,29,2,6,20};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar shidu,fazhi;
uchar hand,aut=1,beep=1,relay,set;
void allinit()
{
P2=0xa0;
P0=0x00;
P2=0x80;
P0=0xff;
P2=0xc0;
P0=0xff;
P2=0xe0;
P0=0xff;
}
void main()
{
allinit();
fazhi=iicread(0x02);
writetime();
while(1)
{
readtime();
shidu=ADread(0x03);
yi=time[2]/10;er=time[2]%10;san=10;
si=time[1]/10;wu=time[1]%10;liu=10;
qi=shidu/10;ba=shidu%10;
keyscan();
if(aut==1)
{
P2=0x80;P0=0xfe;
if(set==0)
{
if(shidu<fazhi)
{
P2=0xa0;P0=0x10;
}
else if(shidu>=fazhi)
{
P2=0xa0;P0=0x00;
}
}
else if(set==1)
{
yi=10;er=10;san=11;si=11;wu=11;liu=11;
qi=fazhi/10;ba=fazhi%10;
}
}
else if(hand==1)
{
P2=0x80;P0=0xfd;
if(shidu<fazhi)
{
if(beep==1 && relay==0)//判断两个条件,避免冲突
{
P2=0xa0;P0=0x40;
}
else if(beep==1 && relay==1)
{
P2=0xa0;P0=0x50;
}
else if(beep==0 && relay==0)
{
P2=0xa0;P0=0x00;
}
else if(beep==0 && relay==1)
{
P2=0xa0;P0=0x10;
}
}
}
display1(yi,er,san,si);
display2(wu,liu,qi,ba);
}
}
按键执行函数
void keyscan()
{
if(P30==0) //S7
{
delayms(5);
if(P30==0)
{
if(aut==1)//设置为一个状态变量也可以
{
hand=1;
aut=0;
}
else if(hand==1)
{
aut=1;
hand=0;
}
}
while(!P30);
}
else if(P31==0)//S6
{
delayms(5);
if(P31==0)
{
if(hand==1)
{
if(beep==0)beep=1;
else if(beep==1)beep=0;//相当于bit的位取反
}
else if(aut==1)
{
if(set==0)set=1;
else if(set==1)
{
set=0;
iicwrite(0x02,fazhi);
}
}
}
while(!P31);
}
else if(P32==0) //S5
{
delayms(5);
if(P32==0)
{
if(hand==1)
{
relay=1;
}
else if(aut==1)
{
fazhi++;
}
}
while(!P32);
}
else if(P33==0)//S4
{
delayms(5);
if(P33==0)
{
if(hand==1)
{
relay=0;
}
else if(aut==1)
{
fazhi--;
}
}
while(!P33);
}
}
ADC采集、at24c02读写函数和时钟显示函数
void iicwrite(uchar add,uchar dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
uchar iicread(uchar add)
{
uchar 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;
}
uchar ADread(uchar add)
{
uchar temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
temp=99*temp/255;
return temp;
}
void writetime()
{
uchar i,add=0x80;
for(i=0;i<7;i++)
{
time[i]=((time[i]/10)<<4)|(time[i]%10);//拆分时间
}
Write_Ds1302_Byte(0x8e,0x00);//打开写保护
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(add,time[i]);//add,dat
add=add+2;
}
Write_Ds1302_Byte(0x8e,0x80);//关闭写保护
}
void readtime()
{
uchar i,add=0x81;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<7;i++)
{
time[i]=Read_Ds1302_Byte(add);
add=add+2;
time[i]=(time[i]/16)*10+time[i]%16;//组合时间
}
Write_Ds1302_Byte(0x8e,0x80);
}
数码管显示和延时函数
void display1(uchar yi,uchar er,uchar san,uchar si)
{
P2=0xc0;
P0=0x01;
P2=0xe0;
P0=tab[yi];
delayms(1);
P2=0xc0;
P0=0x02;
P2=0xe0;
P0=tab[er];
delayms(1);
P2=0xc0;
P0=0x04;
P2=0xe0;
P0=tab[san];
delayms(1);
P2=0xc0;
P0=0x08;
P2=0xe0;
P0=tab[si];
delayms(1);
}
void display2(uchar wu,uchar liu,uchar qi,uchar ba)
{
P2=0xc0;
P0=0x10;
P2=0xe0;
P0=tab[wu];
delayms(1);
P2=0xc0;
P0=0x20;
P2=0xe0;
P0=tab[liu];
delayms(1);
P2=0xc0;
P0=0x40;
P2=0xe0;
P0=tab[qi];
delayms(1);
P2=0xc0;
P0=0x80;
P2=0xe0;
P0=tab[ba];
delayms(1);
}
void delayms(int ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=0;j<845;j++);
}
iic驱动和ds1302驱动为官网驱动
qq_43783627 发布了3 篇原创文章 · 获赞 0 · 访问量 58 私信 关注