[求助] 大神们帮我看看哪里出问题了吧!关于串口的!毕业设计!

毛毛学习单片机   2015-4-6 13:06 楼主
目的很简单,就是通过串口发送想要设定的时间的时、分给单片机,单片机通过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;
                }
        }
}

回复评论 (2)

自己顶顶 大神们帮帮忙
点赞  2015-4-6 17:49
中断程序里有个小问题,那就是你用来控制接收数据个数的变量i,每进一次这个中断,i的值都会被初始化为0,这样就会出现i永远不会等于2,所以,flag是不会被置位的,这个变量应该使用static静态变量类型或者全局变量
点赞  2015-4-6 18:15
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复