今天试着吧串口的部分重新写了一次,这次的主要功能是可以通过按键与接收数据来返回时间。基本如下:
波特率调至9600,无校验位,停止位一位。
将内部震荡器频率设定为12MHz。
当按下S4或者发送“TIME”时,向上位机发送当前的时间,否则发送“error”。
然后呢这次用的底层驱动代码是2022年的最新底层代码。
main.c
/*
波特率调至9600,无校验位,停止位一位。
将内部震荡器频率设定为12MHz。
当按下S4或者发送“TIME”时,向上位机发送当前的时间,否则发送“error”。
*/
#include "reg52.h"
#include "intrins.h"
#include "ds1302.h"
#include "string.h" //使用其中的strcmp方法
unsigned char code write_add[]={0x80,0x82,0x84};
unsigned char code read_add[]={0x81,0x83,0x85};
unsigned char code xianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
int time[]={0x50,0x59,0x23};
unsigned char uart_dat[10];//接收数据数组
int uart_index;
sfr AUXR=0x8e;
sbit S4=P3^3;
void send_information_time();
void choose_573(int i)
{
switch(i)
{
case(0):P2=(P2&0x1f)|0x00;break;
case(4):P2=(P2&0x1f)|0x80;break;
case(5):P2=(P2&0x1f)|0xa0;break;
case(6):P2=(P2&0x1f)|0xc0;break;
case(7):P2=(P2&0x1f)|0xe0;break;
}
}
void init_system() //初始化系统
{
choose_573(4);
P0=0xff;
choose_573(5);
P0=0x00;
choose_573(0);
}
//=======================================时间
void write_time() //向ds1302中写入时间
{
int i;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<3;i++)
{
Write_Ds1302_Byte(write_add[i],time[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void read_time() //从ds1302中读取时间
{
int i;
for(i=0;i<3;i++)
{
time[i]=Read_Ds1302_Byte(read_add[i]);
}
}
//=======================================
//=======================================数码管
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void SMG(int wei,int dat)
{
choose_573(6);
P0=0x80>>(wei-1);
choose_573(7);
P0=xianshi[dat];
choose_573(0);
Delay1ms();
choose_573(7);
P0=xianshi[10];
choose_573(0);
}
void smg_display() //通过数码管显示当前时间
{
SMG(1,time[0]%16);
SMG(2,time[0]/16);
SMG(3,11);
SMG(4,time[1]%16);
SMG(5,time[1]/16);
SMG(6,11);
SMG(7,time[2]%16);
SMG(8,time[2]/16);
}
//=======================================
//=======================================按键
void Delay10ms() //@12.000MHz
{
unsigned char i, j;
i = 117;
j = 184;
do
{
while (--j);
} while (--i);
}
void key_board() //当按下S4时,串口返回当前时间
{
if(S4==0)
{
Delay10ms();
if(S4==0)
{
send_information_time();
}
}
while(!S4);
}
//=======================================
//=======================================串口通讯
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器%d中断
TR1 = 1; //定时器1开始计时
ES=1;
EA=1;
}
void uart_service() interrupt 4
{
if(RI==1)
{
uart_dat[uart_index++]=SBUF;
RI=0;
}
}
void send_dat(unsigned char dat) //返回数据
{
SBUF=dat;
while(TI==0);
TI=0;
}
void send_string(unsigned char *str) //返回字符串
{
while(*str!='\0')
{
send_dat(*str++);
}
}
//=======================================
//=======================================返回当前时间
void send_information_time()
{
send_string("now time is:");
send_dat(time[2]/16+0x30);
send_dat(time[2]%16+0x30);
send_dat('-');
send_dat(time[1]/16+0x30);
send_dat(time[1]%16+0x30);
send_dat('-');
send_dat(time[0]/16+0x30);
send_dat(time[0]%16+0x30);
send_string("\r\n");
}
//=======================================返回错误
void send_information_error()
{
send_string("ERROR");
send_string("\r\n");
}
//=======================================
//=======================================接收数据判断是否发送当前时间
void judge()
{
if(uart_index==4)
{
if(strcmp(uart_dat,"TIME")==1) //当判断接收为“TIME”时返回当前时间
{
send_information_time();
}
else //否则返回“error”
{
send_information_error();
}
uart_index=0;
}
if(uart_index>4) //如果接收到的数据串大于4个,则也返回“error”
{
uart_index=0;
send_information_error();
}
}
//=======================================
void main()
{
init_system();
write_time();
UartInit();
while(1)
{
read_time();
smg_display();
key_board();
judge();
}
}
ds1302.c
#include "ds1302.h"
//写字节
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//向DS1302寄存器写入数据
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);
RST=0;
}
//从DS1302寄存器读出数据
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
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_();
return (temp);
}
ds1302.h
#ifndef __DS1302_H
#define __DS1302_H
#include <reg52.h>
#include <intrins.h>
sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif