微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > DS1302+1602有问题啊 显示的只有“7?”

DS1302+1602有问题啊 显示的只有“7?”

时间:10-02 整理:3721RD 点击:
UART.c

//串口:4800BPS
#include"uart.h"
void uart_init(void)
{
          SCON = 0x50;      //REN=1允许串行接受状态,串口工作模式1                             
    TMOD|= 0x20;      //定时器1工作方式2                    
    PCON|= 0x00;      //双倍速  0x80                                                   
        TH1  = 0xFD;     //baud*2  /* reload value 19200、数据位8、停止位1。效验位无 (11.0592)
        TL1  = 0xFD;
        //TH1 = 0xF4;                                        // //baud*2  /*  波特率4800、数据位8、停止位1。效验位无 (11.0592)
           //TL1 = 0xF4;         
        TR1  = 1;                                                            
        //ES   = 1;        //开串口中断                  
}
//向串口发送一个字节的数据
void ch_send(unsigned char temp)
{
        SBUF = temp;                     //SUBF接受/发送缓冲器
        while(!TI);
        TI=0;
}
/**
* 将数据转换成ASC码并通过UART发送出去
*/
void UART_Send_Dat(unsigned char dat)
{
        ch_send(dat/16 + '0');
        ch_send(dat%16 + '0');
}

1602.c
#include"lcd1602.h"
//功能引脚定义
sbit LCD_RS=P3^5;
sbit LCD_RW=P3^6;
sbit LCD_EN=P3^4;
//数据D0~D7接P0
//写数据;写命令
//读数据;
void delay(unsigned int xms)
{                           
   int i,j;
   for(i=xms;i>=0;i--)
           for(j=110;j>=0;j--);
}
/*******************************************************************/
/*                                                                 */
/*检查LCD忙状态                                                    */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
/*                                                                 */
/*******************************************************************/
bit lcd_busy()
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
     result = (bit)(P0&0x80);
    LCD_EN = 0;
    return result;
}
/*******************************************************************/
/*                                                                 */
/*写指令数据到LCD                                                  */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
/*                                                                 */
/*******************************************************************/
void lcd_wcmd(unsigned char cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 0;  
}
/*******************************************************************/
/*                                                                 */
/*写显示数据到LCD                                                  */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
/*                                                                 */
/*******************************************************************/
void lcd_wdat(unsigned char dat) /*写显示数据到LCD                */
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 0;
}
/*******************************************************************/
/*                                                                 */
/*  设定显示位置                                                   */
/*                                                                 */
/*******************************************************************/
void lcd_pos(unsigned char pos)
{                          
   lcd_wcmd(pos|0x80);      //数据指针=80+地址变量
}
/*******************************************************************/
/*                                                                 */
/*  LCD初始化设定                                                  */
/*                                                                 */
/*******************************************************************/
void lcd_init()
{                        
    lcd_wcmd(0x38);          //16*2显示,5*7点阵,8位数据
    delay(5);
    lcd_wcmd(0x0c);          //显示开,关光标
    delay(5);
    lcd_wcmd(0x06);          //移动光标
    delay(5);
    lcd_wcmd(0x01);          //清除LCD的显示内容
    delay(5);
}
//左移指令 lcd_wcmd(0x18)

1302.c
#include"ds1302.h"
/*--------------------------------------------------------------*/
//引脚定义声明
sbit SCK=P3^2;        //时钟       
sbit SDA=P3^3;        //数据       
sbit RST = P2^4;// DS1302复位
bit ReadRTC_Flag;//定义读DS1302标志
unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00
//unsigned char l_tmpdisplay[8];
code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};  


void reset_Ds1302(void)        //复位
{
        RST = 0;
        SCK = 0;
        RST = 1;
}
/*                   写一个字节                                   */
/******************************************************************/
void Write_Ds1302_Byte(unsigned  char temp)
{
        unsigned char i;
        for (i=0;i<8;i++)             //循环8次 写入数据
          {
                    SCK=0;
             SDA=temp&0x01;     //每次传输低字节
             temp>>=1;                  //右移一位
             SCK=1;
     }
}
/*--------------------------------------------------------------*/
/*                  写入DS1302 在指定地址写入指定的数据                                   */
/******************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )     
{
        reset_Ds1302();               //启动
        Write_Ds1302_Byte(address);        //发送地址
        Write_Ds1302_Byte(dat);                //发送数据
        SDA = 0;
        RST=0;                              //恢复
}

/******************************************************************/
/*                   读出DS1302数据                               */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
        unsigned char i,temp=0x00;
        reset_Ds1302();
        Write_Ds1302_Byte(address);
        for (i=0;i<8;i++)                 //循环8次 读取数据
        {               
                if(SDA)
                temp|=0x80;                        //每次传输低字节
                SCK=0;
                temp>>=1;                        //右移一位
                _nop_();
           _nop_();
           _nop_();
                SCK=1;
        }
        RST=0;
        _nop_();                          //以下为DS1302复位的稳定时间
        _nop_();
        RST=0;
        SCK=0;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        SCK=1;
        _nop_();
        _nop_();
        SDA=0;
        _nop_();
        _nop_();
        SDA=1;
        _nop_();
        _nop_();
        return (temp);                        //返回
}

/*--------------------------------------------------------------*/
//是否写入保护
void DS1302_SetProtect(bit Flag)
{
        if(Flag)
                Write_Ds1302(0x8E,0x80);  //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
        else
                Write_Ds1302(0x8E,0x00);  //WP=0 允许数据写入DS1302
}  

/******************************************************************/
/*                  设定时钟数据                                  */
/******************************************************************/
void Set_RTC(void)                    //设定 日历
{
        unsigned char i,*p,tmp;
        for(i=0;i<7;i++)
        {       //BCD处理
                tmp=l_tmpdate/10;
                l_tmpdate=l_tmpdate%10;
                l_tmpdate=l_tmpdate+tmp*16;
        }  
        DS1302_SetProtect(0);//Write_Ds1302(0x8E,0X00);
       
        p=write_rtc_address;        //传地址       
        for(i=0;i<7;i++)                //7次写入 秒分时日月周年
        {
                 Write_Ds1302(*p,l_tmpdate);
                 p++;  
         }
         DS1302_SetProtect(1);        //Write_Ds1302(0x8E,0x80); // 0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
}

/******************************************************************/
/*                   读时钟数据                                   */
/******************************************************************/
void Read_RTC(void)                //读取 日历
{
         unsigned char i,*p;
         p=read_rtc_address;             //地址传递
         for(i=0;i<7;i++)                    //分7次读取 秒分时日月周年
         {
                  l_tmpdate=Read_Ds1302(*p);
                  p++;
         }
}
/*--------------------------------------------------------------*/
//初始化DS1302
//void DS1302_Initial (void)
//{
//        unsigned char Second=Read1302(DS1302_SECOND);
//        if(Second&0x80)//bit7=CH CH=0 振荡器允许工作,CH=1振荡器停止工作
//        DS1302_SetTime(DS1302_SECOND,0);
//}
/*--------------------------------------------------------------*/





main.c
#include"lcd1602.h"
#include"ds1302.h"
#include"uart.h"
#define lcd  0
extern unsigned char l_tmpdate[];       //{0,0,12,15,5,3,8}秒分时日月周年08-05-15 12:00:00
code unsigned char string1[]="I LOVE YOU" ;
code unsigned char string2[]="Xie Zijuan" ;
unsigned char i,num;
void main()
{

/*-------------------------------------------------*/
//----------------lcd1602部分----------------------//       
       
        uart_init();
        lcd_init();
        lcd_pos(17);
        while(string1!='\0')
        {
                lcd_wdat(string1);
                i++;       
        }
        i=0;
        lcd_pos(81); //0x80+0x42
        while(string2!='\0')
        {
                lcd_wdat(string2);
                i++;       
        }
        for(num=0;num<14;num++)        //左移14次
        {
                lcd_wcmd(0x18);
                delay(500);
        }
        delay(2000);
        lcd_pos(14);  //因为整平移动过后  液晶模块的首地址变换了
        lcd_wdat(0x00+0x30);//0
        delay(1000);
        lcd_pos(93);
        lcd_wdat(0x03+0x30);//3
        delay(1000);
        lcd_pos(78);
        lcd_wdat(0x02+0x30);//2
        delay(1000);
       
        lcd_pos(29);
        lcd_wdat(0x01+0x30);//1
        delay(3000);
        for(num=0;num<15;num++)        //左移14次
        {
                lcd_wcmd(0x18);
                delay(500);
        }
        lcd_init();
/*-----------------------------------------------*/
//------------------ds1302实时时钟部分----------//
        Set_RTC(); //set RTC
        while(1)
        {
                Read_RTC();//read RTC
                UART_Send_Dat(l_tmpdate[0]);
                ch_send('\n');
                //l_tmpdisplay[0]=l_tmpdate[2]/16;                        //数据的转换,因我们采用数码管0~9的显示,将数据分开
                //l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
                //l_tmpdisplay[2]=10;                                                    //加入"-"
                delay(100);         
        }



}

1602部分没有问题
串口部分没有问题的
就是ds1302处理有问题啊

把时钟芯片的数据从串口送出来,看下,时钟正常不

我是送到串口了 一直显示“7?”

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top