微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > DS1302显示乱码,不间断跳出85

DS1302显示乱码,不间断跳出85

时间:10-02 整理:3721RD 点击:
用DS1302做时钟信号,用来计时,在protues中仿真没问题,在开发板搭硬件时,时间能显示,时分秒显示一直是正常时间跟85间断显示,到一分钟时秒停留在85不动。#ifndef _REAL_TIMER_DS1302
#define _REAL_TIMER_DS1302
sbit DS1302_CLK = P2^7; //实时时钟时钟线引脚
sbit DS1302_IO = P2^6; //实时时钟数据线引脚
sbit DS1302_RST = P2^5; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute ;
unsigned char Hour;
unsigned char TimeString[9];
}SYSTEMTIME; //定义的时间类型
#define AM(X) X
#define PM(X) (X+12) // 转成24 小时制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302 地
//址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte 数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302 某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte 数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10)));
}
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
}
void Initial_DS1302(void)
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80)
DS1302_SetTime(DS1302_SECOND,0);
}
void SetTime(void)
{
Write1302(0x8e,0x00);
Write1302(0x80,0x00);//写秒
Write1302(0x82,0x00); //写分
Write1302(0x84,0x08);
Write1302(0x8e,0x80);
}
#endif

你的代码里面是不是有18B20了?代码不全

没有,用到了LCD1602#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"
char str1[4]={""};
char str2[4]={""};
unsigned char Minute ;
unsigned char Second_cnt;
sbit r1=P3^4;
sbit r2=P2^4;
sbit key=P2^3;
unsigned int count1=0;
unsigned int count2=0;
unsigned int count=0;
unsigned char A,D,C;
unsigned char E,F,G;
unsigned char flag;
void delay(unsigned char n)
{
unsigned char i,j;
for(i=n;i>0;i--)
{
for(j=0;j<10;j++) ;
}
}
void Delay1ms(unsigned int count)
{
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
void int0()
{
TMOD=0x01 ;
TH0=0xed ;
TL0=0xff ;
EA=1;
ET0=1;
TR0=1 ;
if(r1 == 0)
{
delay(10);
{
count1++;
if(count1==999)
count1 =0;
A=count1/100;
D=count1%100/10;
C=count1%100%10;
}
while(r1==0);
}
}
void int1()
{
if(r2 == 0)
{ delay(10);
{
count2++;
if(count2==999)
count2 =0;
E=count2/100;
F=count2%100/10;
G=count2%100%10;
}
while(r2==0);
}
}
main()
{
SYSTEMTIME CurrentTime;
LCD_Initial();
Initial_DS1302();
GotoXY(0,0);
Print("Cin:");
GotoXY(8,0);
Print(" Out:000");
GotoXY(0,1);
Print("Time: ");
key=1;
while(1)
{
if(key==0)
SetTime();
int0();
int1();
DS1302_GetTime(&CurrentTime);
TimeToStr(&CurrentTime);
GotoXY(6,1);
Print(CurrentTime.TimeString);
str1[0]=A+'0';
str1[1]=D+'0';
str1[2]=C+'0';
str1[3]='\0';
GotoXY(4,0);
Print(str1);
Delay1ms(40);
str2[0]=E+'0';
str2[1]=F+'0';
str2[2]=G+'0';
str2[3]='\0';
GotoXY(13,0);
Print(str2);
Delay1ms(40);
Delay1ms(400);
}
}
/*  THE 1602 CHAR LCD LIB
COPYRIGHT (c) 2005 BY JJJ.
-- ALL RIGHTS RESERVED --
File Name: LCD.h
Author: Jiang Jian Jun
Created: 2005/4/3
Modified: NO
Revision: 1.0
***************************************************************************/
#ifndef LCD_CHAR_1602_2005_4_9
#define LCD_CHAR_1602_2005_4_9
#include <intrins.h>
//Port Definitions**********************************************************
sbit LcdRs = P2^0;
sbit LcdRw = P2^1;
sbit LcdEn = P2^2;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.
//内部等待函数
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
//while(DBPort&0x80);//在用Proteus 仿真时,注意用屏蔽此语句,在调用GotoXY()时,
//可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80
//实际硬件时打开此语句
LcdEn=0;
return DBPort;
}
//向LCD 写入命令或数据
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input; _nop_();//注意顺序
LcdEn=1; _nop_();//注意顺序
LcdEn=0; _nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//移动光标或屏幕************************************************************
/*
#define LCD_CURSOR 0x02
#define LCD_SCREEN 0x08
#define LCD_LEFT 0x00
#define LCD_RIGHT 0x04
void LCD_Move(unsigned char object, unsigned char direction)
{
if(object==LCD_CURSOR)
LCD_Write(LCD_COMMAND,0x10|direction);
if(object==LCD_SCREEN)
LCD_Write(LCD_COMMAND,0x18|direction);
}
*/
//初始化LCD************************************************************
void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8 位数据端口,2 行显示,5*7 点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC 递增, 画面不动
}
//************************************************************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char *str)
{while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
void LCD_LoadChar(unsigned char user[8], unsigned char place)
{
unsigned char i;
LCD_Write(LCD_COMMAND,0x40|(place*8));
for(i=0; i<8; i++)
LCD_Write(LCD_DATA,user);
}
*/
//************************************************************************
#endif
#ifndef _REAL_TIMER_DS1302
#define _REAL_TIMER_DS1302
sbit DS1302_CLK = P2^7; //实时时钟时钟线引脚
sbit DS1302_IO = P2^6; //实时时钟数据线引脚
sbit DS1302_RST = P2^5; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute ;
unsigned char Hour;
unsigned char TimeString[9];
}SYSTEMTIME; //定义的时间类型
#define AM(X) X
#define PM(X) (X+12) // 转成24 小时制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302 地
//址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte 数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302 某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte 数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10)));
}
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
}
void Initial_DS1302(void)
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80)
DS1302_SetTime(DS1302_SECOND,0);
}
void SetTime(void)
{
Write1302(0x8e,0x00);
Write1302(0x80,0x00);//写秒
Write1302(0x82,0x00); //写分
Write1302(0x84,0x08);
Write1302(0x8e,0x80);
}
#endif
所有代码

dsfsdf

unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
DS1302_IO  = 0;这里把IO拉低试试,反正我的就是这样成功的。
return(ACC);
}

很多人说是电源的问题。但是我发现同样4.7v电源,同样是DS1302
DS1302
1107A4
+102BN
工作正常
DS1302
1528C2
+163AN
经常跳出85然后卡住不动

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

网站地图

Top