目的很简单,就是通过串口发送想要设定的时间的时、分给单片机,单片机通过DS1302读取目前的时间,与预设的时间的时、分进行比对,在规定时间让LED点亮。为了测试准确,我让单片机每秒都把当时的时间读出来。
在之前的测试中,已经可以实现发送给串口一个预设时间的“分钟”,LED在那个分钟点亮,说明DS1302的设置是没有问题的。但是,当我把程序改成串口中断读取时和分并把这两个数存到port_shi_fen数组里的时候,就不行了。找来找去不知道哪里有问题。我把程序贴在下面,希望大神们可以帮忙指正!
#include
/*------------------------------------------------
声明
------------------------------------------------*/
sbit led = P1^0;
sbit RST = P1^5; //DS1302复位
sbit SCK = P1^6; //时钟
sbit SDA = P1^7; //数据
unsigned char a,i,flag,tmp;
unsigned char shi_fen_miao[3], port_shi_fen[2];
/*------------------------------------------------
串口初始化
------------------------------------------------*/
void InitUART (void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
//TL1 = 0xFD;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void reset_ds1302(void) //在每次写入数据前restds1302
{
RST = 0;
SCK = 0;
RST = 0;
}
void write_ds1302_byte(unsigned char dat) //按位写入ds1302程序
{
unsigned char i;
SCK = 0;
for(i=0;i<8;i++)
{
SDA = dat & 0x01;
SCK = 1;
dat>>=1;
SCK = 0;
}
}
void DS1302Write(unsigned char addr, unsigned char dat)//写入DS1302
{
reset_ds1302();
RST = 1;
write_ds1302_byte(addr);
write_ds1302_byte(dat);
SDA = 0;
RST = 0;
}
unsigned char read_ds1302_byte(void) //从DS1302按位读出
{
unsigned char i, dat = 0;
for (i=0;i<8;i++)
{
dat>>=1;
if(SDA)
dat|= 0x80;
SCK = 1;
SCK = 0;
}
return dat;
}
unsigned char read_ds1302(unsigned char addr) //从DS1302读出
{
unsigned char temp = 0;
reset_ds1302();
RST = 1;
write_ds1302_byte(addr);
temp = read_ds1302_byte();
SDA = 0;
RST = 0;
return(temp);
}
void InitDS1302(void)
{
DS1302Write(0x8e,0x00);
DS1302Write(0x80,0x00); //初始秒
DS1302Write(0x82,0x30); //初始分
DS1302Write(0x84,0x16); //初始时 16:30:00
//DS1302Write(0x90,0x01); //充电
DS1302Write(0xc0,0xf0); //初始化一次标识
DS1302Write(0x8e,0x80); //写保护开
}
void SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
void Delay(unsigned int time)
{
unsigned int i,j;
for(j = 0; j < time; j++)
for(i = 0; i < 250; i++);
}
void main (void)
{
InitUART();
InitDS1302();
while (1)
{
shi_fen_miao[0] = read_ds1302(0x85); //时
SendByte(shi_fen_miao[0]);
shi_fen_miao[1] = read_ds1302(0x83); //分
SendByte(shi_fen_miao[1]);
shi_fen_miao[2] = read_ds1302(0x81); //秒
SendByte(shi_fen_miao[2]);
if(flag) //取flag=1的情况读出串口得到的时、分
{
for(i=0;i<2;i++)
{
SendByte(port_shi_fen[i]);
}
flag = 0;
}
if((shi_fen_miao[0]==port_shi_fen[0])&&(shi_fen_miao[1]==port_shi_fen[1]))
led = 0;
Delay(500);
}
}
void zhongduan() interrupt 4
{
unsigned char i;
if(RI) //判断是接收中断产生
{
RI = 0; //标志位清零
a = SBUF; //读入缓冲区的值
port_shi_fen[i] = a;
i++;
if(i == 2) //连续接收2个字符信息
{
i = 0;
flag = 1;
}
}
}
中断程序里有个小问题,那就是你用来控制接收数据个数的变量i,每进一次这个中断,i的值都会被初始化为0,这样就会出现i永远不会等于2,所以,flag是不会被置位的,这个变量应该使用static静态变量类型或者全局变量