这个星期和同学一起完成了这个课程设计,对单片机也有了更加近一步的了解。这次课程设计做的是基于芯片PCF8563和单片机stc12C5A60S2的万年历,在制作过程中,遇到了好几个问题,有些是硬件电路搭建时的疏忽导致的电路错误,有些是程序编写时的错误,经过反复的检查和调试后,最终完成了这次课程设计。做完这次课设,最大的感受就是搭建实验电路时必须非常严谨,检查每一根线路的正确性,在调试的时候,一定要耐心,不断进行检查。
/*************SMG1.H*************/
#define uint unsigned int
#define uchar unsigned char
uint c;
unsigned char rd[7];
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;
sbit P25=P2^5;
sbit P26=P2^6;
sbit P27=P2^7;
sbit P07=P0^7;
uchar code num[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay_time1(unsigned short t)
{
unsigned short i,n;
for(n=0;n<t;n++)
for(i=0;i<500;i++)
{;}
}
void display_time()
{
rd[2]&=0x3f;
P2=0xFF; //关闭所有位选
P20=0; //开某一位
c=rd[2]/16; //赋值
P0=num[c]; //送入P0
delay_time1(1); //延时
P2=0xFF;
P21=0;
c=rd[2]%16;
P0=num[c];
P07=1;
delay_time1(1);
P2=0xFF;
P22=0;
c=rd[1]/16;
P0=num[c];
delay_time1(1);
P2=0xFF;
P23=0;
c=rd[1]%16;
P0=num[c];
P07=1;
delay_time1(1);
P2=0xFF;
P24=0;
c=rd[0]/16;
P0=num[c];
delay_time1(1);
P2=0xFF;
P25=0;
c=rd[0]%16;
P0=num[c];
delay_time1(1);
}
void display_date()
{
rd[6]&=0x1f;
P2=0xFF;
P20=0;
c=rd[6]/16;
P0=num[c];
delay_time1(1);
P2=0xFF;
P21=0;
c=rd[6]%16;
P0=num[c];
P07=1;
delay_time1(1);
rd[5]&=0x1f;
P2=0xFF;
P22=0;
c=rd[5]/16;
P0=num[c];
delay_time1(1);
P2=0xFF;
P23=0;
c=rd[5]%16;
P0=num[c];
P07=1;
delay_time1(1);
rd[3]&=0x3f;
P2=0xFF;
P24=0;
c=rd[3]/16;
P0=num[c];
delay_time1(1);
P2=0xFF;
P25=0;
c=rd[3]%16;
P0=num[c];
delay_time1(1);
}
//#endif
/**********VIIC_C51.H*****************************/
#ifdef uchar
#define READYDEF1
#else
#define uchar unsigned char
#endif
extern bit ISendByte(uchar sla,uchar c);
extern bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no);
extern bit IRcvByte(uchar sla,uchar *c);
extern bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no);
#ifndef READYDEF
#undef uchar
#endif
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define _Nop() _nop_()
sbit SDA=P1^7;
sbit SCL=P1^6;
bit ack;
void delay12()
{
uchar i;
i=12;
while(--i);
}
void Start_I2c()
{
SDA=1;
_Nop();
SCL=1;
delay12();
SDA=0;
delay12();
SCL=0;
_Nop();
_Nop();
}
void Stop_I2c()
{
SDA=0;
_Nop();
SCL=1;
delay12();
SDA=1;
delay12();
}
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
if((c<<BitCnt)&0x80)SDA=1;
else SDA=0;
_Nop();
SCL=1;
delay12();
SCL=0;
}
_Nop();
_Nop();
SDA=1;
delay12();
SCL=1;
delay12();
if(SDA==1)ack=0;
else ack=1;
SCL=0;
delay12();
}
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0;
delay12();
SCL=1;
delay12();
retc=retc<<1;
if(SDA==1)retc=retc+1;
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
void Ack_I2c(bit a)
{
if(a==0)SDA=0;
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
delay12();
SCL=0;
delay12();
}
//bit ISendByte(uchar sla,uchar c)
//{
//Start_I2c();
//SendByte(sla);
// if(ack==0)return(0);
// SendByte(c);
// if(ack==0)return(0);
// Stop_I2c();
// return(1);
//}
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s);
if(ack==0)return(0);
s++;
}
Stop_I2c();
return(1);
}
//bit IRcvByte(uchar sla,uchar *c)
//{
//Start_I2c();
// SendByte(sla+1);
// if(ack==0)return(0);
// *c=RcvByte();
// Ack_I2c(1);
// Stop_I2c();
// return(1);
// }
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte();
Ack_I2c(0);
s++;
}
*s=RcvByte();
Ack_I2c(1);
Stop_I2c();
return(1);
}
/**********wannian.c*****************************/
#include "stc12.h"
#include "VIIC_C51.h"
#include "smg1.h"
#define PCF8563 0xA2
#define WRADDR 0x00
#define RDADDR 0x02
#define CON_STATUS1 0x01
#define MINALARMADDR 0x09
#define HOUALARMADDR 0x0A
sbit BUZZ=P1^1;
int flag1,flag2;
unsigned char rd[7];
unsigned char time=100;
unsigned char rcon_sta;
unsigned char wcon_sta;
unsigned char alarmflag=0;
unsigned char DelayNS(unsigned char no)
{
unsigned char i,j;
for(;no>0;no--)
for(i=0;i<100;i++)
for(j=0;j<100;j++);
return 0;
}
void delay_time(unsigned short t)
{
unsigned short i,n;
for(n=0;n<t;n++)
for(i=0;i<10000;i++)
{;}
}
void initmcu()
{
EA=1;
IT0=1;
EX0=1;
ET0=1;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
void tt0() interrupt 1 using 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
time--;
if(time==0){BUZZ=1;TR0=0;time=100;}
}
void intt0() interrupt 0 using 0
{
BUZZ=0;
TR0=1;
alarmflag=1;
}
void main()
{
unsigned char code td[9]={0x00,0x12,0x40,0x30,0x12,0x01,0x04,0x12,0x16};//2016.11.30.11.59.40
unsigned char minalarm=0x31;//定时12.00响
unsigned char houralarm=0x12;
delay_time(10);
initmcu();
ISendStr(PCF8563,WRADDR,td,0x5);
DelayNS(1);
ISendStr(PCF8563,WRADDR+5,&td[5],0x4);
DelayNS(1);
ISendStr(PCF8563,MINALARMADDR,&minalarm,0x1);
ISendStr(PCF8563,HOUALARMADDR,&houralarm,0x1);
IRcvStr(PCF8563,CON_STATUS1,&rcon_sta,0x01);
wcon_sta=rcon_sta|0x02;
ISendStr(PCF8563,CON_STATUS1,&wcon_sta,0x01);
while(1)
{
DelayNS(1);
IRcvStr(PCF8563,RDADDR,rd,0x7); //读现在的秒、分、时、日、星期、月、年
if(alarmflag==1)
{
IRcvStr(PCF8563,CON_STATUS1,&rcon_sta,0x01); //清PCF8563的AF标志位
wcon_sta=rcon_sta&0xF7; //清AF位,但其他位不改变
ISendStr(PCF8563,CON_STATUS1,&wcon_sta,0x01);
alarmflag=0;
}
if(flag2==0) //两段程序交替显示可以通过flag1和flag2调节时间。
{
display_time(); //时间显示
flag1++;
}
if(flag1==100) //flag2控制时间显示时间,flag1控制日期显示时间
{
display_date(); //日期显示
flag2++;
if(flag2==50)
{
flag1=0;
flag2=0;
}
}
}
}