DS1302+1602有问题啊 显示的只有“7?”
//串口: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部分没有问题 把时钟芯片的数据从串口送出来,看下,时钟正常不
我是送到串口了 一直显示“7?”
串口部分没有问题的
就是ds1302处理有问题啊