设计要求
读取DS1302时钟芯片的时、分、秒,当S9按键按下时,串口发送一次当前时、分、秒。
串口发送格式如下图所示:
Time:00:00:00
备注:
单片机IRC振荡器频率:12MHz。
串口通信波特率:9600bps。
按键模式:BTN;扩展方式:IO模式
代码
sys.h
#ifndef __SYS_H__
#define __SYS_H__
#include <STC15F2K60S2.H>
#include "intrins.h"
extern unsigned char time[3];
extern bit flag;
void init74hc138(unsigned char n);
void init();
void Key_Loop();
void w_ds1302();
void r_ds1302();
#endif
main.c
#include "sys.h"
unsigned char *str="Time:";
bit flag_key=0;
bit flag_time=0;
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES=1;
EA=1;
}
void Timer2_Init(void) //100微秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x50; //设置定时初始值
T2H = 0xFB; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04; //使能定时器2中断
EA=1;
}
void send_uart_date(unsigned char date){
SBUF=date;
while(TI==0);
TI=0;
}
void send_uart_str(unsigned char *str){
while(*str!='\0'){
send_uart_date(*str++);
}
}
void send_uart_time(){
send_uart_str(str);
send_uart_date(time[2]/10+'0');
send_uart_date(time[2]%10+'0');
send_uart_date(':');
send_uart_date(time[1]/10+'0');
send_uart_date(time[1]%10+'0');
send_uart_date(':');
send_uart_date(time[0]/10+'0');
send_uart_date(time[0]%10+'0');
send_uart_str("\r\n");
}
void main(){
init();
w_ds1302();
UartInit();
Timer2_Init();
while(1){
if(flag_key){
flag_key=0;
Key_Loop();
}
if(flag_time){
flag_time=0;
r_ds1302();
}
if(flag){
flag=0;
send_uart_time();
}
}
}
void uart() interrupt 4
{
if(RI){
RI=0;
}
}
void Timer2_Isr(void) interrupt 12
{
static unsigned char count=0;
static unsigned int count1=0;
count++;count1++;
if(count==50){
count=0;
flag_key=1;
}
if(count1==5000){
count1=0;
flag_time=1;
}
}
sys.c
#include "sys.h"
unsigned char keyval,keyold,keyup,keydown;
bit flag=0;
void init74hc138(unsigned char n){
P2=(P2&0x1f)|(n<<5);
P2&=0x1f;
}
void init(){
P0=0x00;
init74hc138(5);
P0=0xff;
init74hc138(4);
}
void Key_Loop(){
P32=0;
keyval=0;
if(P42==0)keyval=1;
keydown=keyval&(keyold^keyval);
keyup=~keyval&(keyold^keyval);
if(keyval&&!keyold)flag=1;
keyold=keyval;
}
ds1302.c
#include "sys.h"
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
unsigned char time[]={0,0,0};
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat/10*16|dat%10);//十进制——>8421BCD
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
unsigned char dat1,dat2;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
dat1=temp/16;
dat2=temp%16;
temp=dat1*10+dat2;
return (temp);
}
void w_ds1302(){
unsigned char i,addr=0x80;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<3;i++){
Write_Ds1302_Byte(addr,time[i]);
addr+=2;
}
Write_Ds1302_Byte(0x8e,0x80);
}
void r_ds1302(){
unsigned char i,addr=0x81;
for(i=0;i<3;i++){
time[i]=Read_Ds1302_Byte(addr);
addr+=2;
}
}