STM8对DS1302读取的数据总是85,已加10K上拉,求指导
/* MAIN.C file*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include <stm8s003f3.h>
// - - 定义函数
#define BIAS 0x52 //0b1000 0101 00101/3duty 4com
#define SYSDIS 0X00 //0b1000 0000 0000关振系统荡器和LCD偏压发生器
#define SYSEN0X02 //0b1000 0000 0010 打开系统振荡器
#define LCDOFF 0X04 //0b1000 0000 0100关LCD偏压
#define LCDON0X06 //0b1000 0000 0110打开LCD偏压
#define XTAL 0x28 //0b1000 0010 1000 外部接时钟
#define RC2560X30 //0b1000 0011 0000内部时钟
#define TONEON0X12 //0b1000 0001 0010打开声音输出
#define TONEOFF 0X10 //0b1000 0001 0000 关闭声音输出
#define WDTDIS0X0A //0b1000 0000 1010禁止看门狗
#define WDTDIS0X0A
unsigned int b,v,v1,i,miao,fen,shi,e,f,yu;
unsigned char m,n,m1,n1,miaodian;
unsigned int flag,year,month,day,hour,min,a,keytime,set;
unsigned char
Ht1621wTab[]={0x0b,0x00,0x07,0x05,0x0c,0x0d,0x0f,0x00,0x0f,0x0d}; //seg 16
unsigned char
Ht1621cTab[]={0x0f,0x07,0x0d,0x0f,0x07,0x0b,0x0b,0x0f,0x0f,0x0f};//seg 17
unsigned char
Ht1621dTab[]={0x0e,0x06,0x0c,0x0e,0x06,0x0a,0x0a,0x0e,0x0e,0x0e};//seg 17
unsigned char
Ht1621eTab[]={0x00,0x0a,0x0d,0x0e};
_Bool CS @PC_ODR:5;
_Bool WR @PC_ODR:6;
_Bool DAT @PC_ODR:7;
_Bool SCLK @PD_ODR:4;
_Bool SDA @PD_ODR:5;
_Bool RST @PD_ODR:6;
_Bool k1 @PB_IDR:4;
_Bool k2 @PC_IDR:3;
_Bool k3 @PC_IDR:4;
//HT1621控制位(液晶模块接口定义,根据自已的需要更改)
#define CLS_HT_WR WR = 0 //拉低
#define SET_HT_WR WR = 1 //拉高
#define CLS_HT_CS CS = 0 //拉低
#define SET_HT_CS CS = 1 //拉高
#define SET_HT_DAT DAT= 1 //数据位
#define CLS_HT_DAT DAT = 0 //数据位
//GPIO口设置
void port_init(void)
{
PB_DDR |= 0x20;
PB_CR1 |= 0x20;
PB_CR2 |= 0x00;
PD_DDR |= 0x74;
PD_CR1 |= 0x04;
PD_CR2 |= 0x00;
PC_DDR |= 0xe0;
PC_CR1 |= 0xe0;
PC_CR2 |= 0x00;
}
void Init(void)
{
//CLK_ICKR |= 0x01; //打开内部高速RC
//CLK_CKDIVR = 0x10; //HSI--4MHZ
CLK_CKDIVR = 0x00;
}
//-----------------------------------------------------------------------------------------
//函数名称:Delay()
//功 能:延时子程序
//-----------------------------------------------------------------------------------------
void Delay(char us) //5,7,9
{
while(--us);
}
//-----------------------------------------------------------------------------------------
//函数名称:DelayMS()
//功 能:延时子程序
//-----------------------------------------------------------------------------------------
void DelayMS(int iMs)
{
int i,j;
for(i=0;i<iMs;i++)
for(j=0;j<65;j++)
{
Delay(1);
}
}
void writebyb(unsigned char temp)
{
unsigned char i;
SCLK=0;
Delay(20);
for(i=0;i<8;i++)
{
SDA=temp&0x01;
Delay(5);
SCLK=1;
Delay(5);
SCLK=0;
temp>>=1;
}
}
void write(unsigned char adress,unsigned char dat)
{
RST=0;
SCLK=0;
RST=1;
Delay(20);
writebyb(adress);
writebyb(dat);
SCLK=1;
RST=0;
}
unsigned char readbybe(void)
{
unsigned i,dat;
Delay(2);
for(i=0;i<8;i++)
{
dat>>=1;
if(SDA==1)
{
dat|=0x80;
}
else
{
dat&=0x7f;
}
SCLK=1;
Delay(5);
SCLK=0;
Delay(5);
}
return dat;
}
unsigned char read(unsigned char adress)
{
unsigned char temp;
RST=0;
SCLK=0;
RST=1;
Delay(1);
writebyb(adress);
temp=readbybe();
SCLK=1;
RST=0;
SDA=0;
return temp;
}
void ds1302(void)
{
write(0x8e,0x00);
write(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值
write(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值
write(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值
write(0x86,((16/10)<<4|(16%10))); //根据写日寄存器命令字,写入日的初始值
write(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值
write(0x8c,((8/10)<<4|(8%10))); //根据写小时寄存器命令字,写入小时的初始值
write(0x8e,0x80);
}
void settime(void)
{
unsigned char ReadValue;
ReadValue = read(0x81); //从秒寄存器读数据
miao=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
ReadValue = read(0x83);//从分寄存器读
min=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = read(0x85);//从分寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = read(0x87);//从分寄存器读
day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = read(0x89);//从分寄存器读
month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = read(0x8d);//从分寄存器读
year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
}
------------------------------------------------------------------------------------
void Ht1621_Init(void)
{
SET_HT_CS;//HT1621_CS=1;
SET_HT_WR;//HT1621_WR=1;
SET_HT_DAT;//HT1621_DAT=1;
DelayMS(20); //延时使LCD工作电压稳定
Ht1621WrCmd(BIAS);
Ht1621WrCmd(RC256); //使用内部振荡器
Ht1621WrCmd(SYSDIS);
Ht1621WrCmd(WDTDIS);
Ht1621WrCmd(SYSEN);
Ht1621WrCmd(LCDON);
Ht1621WrCmd(TONEON);
Ht1621WrCmd(TONEOFF);
}
void dispaytemp(int a)
{
int ge,shi,bai;
bai=a/100;
shi=(a-bai*100)/10;
ge=a%10;
Ht1621WrOneData(0x16,Ht1621wTab);
Ht1621WrOneData(0x15,Ht1621cTab);
Ht1621WrOneData(0x14,Ht1621wTab);
Ht1621WrOneData(0x13,Ht1621cTab);
Ht1621WrOneData(0x12,Ht1621wTab);
Ht1621WrOneData(0x11,Ht1621cTab);
}
void dispaytime(int b)
{
int fge,fshi,sge,sshi;
fshi=b/10;
fge=b%10;
Ht1621WrOneData(0x08,Ht1621cTab);
Ht1621WrOneData(0x09,Ht1621wTab);
Ht1621WrOneData(0x0a,Ht1621dTab);
Ht1621WrOneData(0x0b,Ht1621wTab);
}
void dispaytime2(int c,int d)
{
int fge,fshi,sge,sshi;
fshi=d/10;
fge=d%10;
sshi=c/10;
sge=c%10;
Ht1621WrOneData(0x08,Ht1621cTab);
Ht1621WrOneData(0x09,Ht1621wTab);
Ht1621WrOneData(0x0a,Ht1621cTab);
Ht1621WrOneData(0x0b,Ht1621wTab);
Ht1621WrOneData(0x0c,Ht1621cTab);
Ht1621WrOneData(0x0d,Ht1621wTab);
Ht1621WrOneData(0x0e,Ht1621eTab);
}
void dispaynian(int nian,int yue,int ri)
{
int niange,nianshi,rige,rishi,yueshi,yuege;
nianshi=nian/10;
niange=nian%10;
yueshi=yue/10;
yuege=yue%10;
rishi=ri/10;
rige=ri%10;
Ht1621WrOneData(0x1e,Ht1621cTab);
Ht1621WrOneData(0x1f,Ht1621wTab);
Ht1621WrOneData(0x1c,Ht1621cTab);
Ht1621WrOneData(0x1d,Ht1621wTab);
Ht1621WrOneData(0x19,Ht1621eTab);
Ht1621WrOneData(0x17,Ht1621cTab);
Ht1621WrOneData(0x18,Ht1621wTab);
if(yueshi==1)
{
Ht1621WrOneData(0x1a,Ht1621cTab);
Ht1621WrOneData(0x1b,Ht1621wTab);
}
else
{
Ht1621WrOneData(0x1a,Ht1621dTab);
Ht1621WrOneData(0x1b,Ht1621wTab);
}
}
void CLK_Init(void)
{
CLK_CKDIVR = 0x00;
}
void di(void)//蜂鸣器
{
Ht1621WrCmd(TONEON);
DelayMS(2000);
Ht1621WrCmd(TONEOFF);
}
void main( void )
{
ADC_Init();
ADC_CR1|=0x01;
_asm("sim");
CLK_Init();
TIM1_Init();
_asm("rim");
Init(); //时钟初始化
port_init();//GPIO初始化
Ht1621_Init(); //上电初始化LCD
ds1302();
DelayMS(50); //延时一段时间
Ht1621WrAllData();
flag=6;
while(1)
{
dispaytemp(b);
key();
settime();
}
}
没搞过,帮顶…… 多谢...... 帮顶!!! 已经折腾1个多月了, for(i=0;i<8;i++)
{
if(temp&0x01)
SDA=1;
else
SDA=0;
// SDA=temp&0x01;
Delay(5);
SCLK=1;
Delay(5);
SCLK=0;
temp>>=1;
}
这个底层操作改这样看看 #ifndef __DS1302_CONFIG_H__
#define __DS1302_CONFIG_H__
#include <stm8s.h>
#include "delay.h"
//PB4 ->SCLK; PB5 ->IO; PC3 ->CE;
// 1:自动转换成10进制0:BCD格式
#define DS1302_AUTO_TO_DEC 1
// 端口控制命令定义
#define DS1302_IO_0 GPIO_WriteLow(GPIOB,GPIO_PIN_5)
#define DS1302_IO_1 GPIO_WriteHigh(GPIOB,GPIO_PIN_5)
#define DS1302_IO_IN GPIO_Init(GPIOB,GPIO_PIN_5,GPIO_MODE_IN_PU_NO_IT)
#define DS1302_IO_OUT GPIO_Init(GPIOB,GPIO_PIN_5,GPIO_MODE_OUT_PP_LOW_FAST)
#define DS1302_IO_VALUE GPIO_ReadInputPin(GPIOB,GPIO_PIN_5)
#define DS1302_SCLK_0 GPIO_WriteLow(GPIOB,GPIO_PIN_4)
#define DS1302_SCLK_1 GPIO_WriteHigh(GPIOB,GPIO_PIN_4)
#define DS1302_SCLK_OUT GPIO_Init(GPIOB,GPIO_PIN_4,GPIO_MODE_OUT_PP_LOW_FAST)
#define DS1302_CE_0 GPIO_WriteLow(GPIOC,GPIO_PIN_3)
#define DS1302_CE_1 GPIO_WriteHigh(GPIOC,GPIO_PIN_3)
#define DS1302_CE_OUT GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_FAST)
// 延时时间定义(参照datasheet)
#define DS1302_DELAY_T_DC delay_us(1)
#define DS1302_DELAY_T_CDH delay_us(1)
#define DS1302_DELAY_T_CDD delay_us(1)
#define DS1302_DELAY_T_CL delay_us(1)
#define DS1302_DELAY_T_CH delay_us(1)
#define DS1302_DELAY_T_CC delay_us(4)
#define DS1302_DELAY_T_CCH delay_us(1)
#define DS1302_DELAY_T_CWH delay_us(4)
#endif /* __DS1302_CONFIG_H__ */
#ifndef __DS1302_H__
#define __DS1302_H__
#include "ds1302_config.h"
// 寄存器地址定义
#define DS1302_SECOND_ADDR 0x80
#define DS1302_MINUTE_ADDR 0x82
#define DS1302_HOUR_ADDR 0x84
#define DS1302_DATE_ADDR 0x86
#define DS1302_MONTH_ADDR 0x88
#define DS1302_DAY_ADDR 0x8a
#define DS1302_YEAR_ADDR 0x8c
#define DS1302_WRITE_PROTECT_ADDR 0x8e // 写保护
#define DS1302_TRICKLE_CHARGE_ADDR 0x90 // 涓流充电
#define DS1302_CLOCK_BURST_ADDR 0xbe // 连续读写
#if DS1302_AUTO_TO_DEC == 1
#define DEC_TO_BCD(d) DecToBcd(d)
#define BCD_TO_DEC(b) BcdToDec(b)
#else
#define DEC_TO_BCD(d) d
#define BCD_TO_DEC(b) b
#endif /* DS1302_AUTO_TO_DEC == 1 */
typedef enum
{
_12_hours, _24_hours
}HourMode_t;
typedef enum
{
am, pm
}AM_PM_t;
// DS1302日期时间结构
typedef struct
{
unsigned char Year; // 年 0 - 99
unsigned char Month; // 月 1 - 12
unsigned char Date; // 日 1 - 31
unsigned char Hour; // 时 1 - 12 或 0 - 23
unsigned char Minute; // 分 0 - 59
unsigned char Second; // 秒 0 - 59
unsigned char Day; // 星期 1 - 7 星期天 = 7
HourMode_t HourMode; // 小时模式 _12_hours 或 _24_hours
AM_PM_t AM_PM; // 上午下午标志 12时制时有效 am 或 pm
}DS1302_DateTime_t;
// 更新标记 1:已更新 0:未更新
// 调用 DS1302_GetDateTime 后自动清零
extern volatile unsigned char DS1302_Update;
/* 存放日期和时间的变量
执行 DS1302_GetDateTime 后 时间日期写入到该变量
修改此值,并执行 DS1302_SetDateTime, 更新到DS1302 */
extern DS1302_DateTime_t DS1302_DateTime;
extern DS1302_DateTime_t DS1302_DateTime_Now;
// 初始化
void DS1302_Init(void);
// 读取日期和时间, DS1302 -> DS1302_DateTime
void DS1302_GetDateTime(void);
// 设置日期和时间, DS1302_DateTime -> DS1302
void DS1302_SetDateTime(void);
// 扫描(轮询)函数, 扫描频率应大于1Hz
void DS1302_Scan(void);
void DS1302_SetDataTimeInit(void);
#endif /* __DS1302_H__ */
#include "ds1302.h"
volatile unsigned char DS1302_Update = 0;
DS1302_DateTime_t DS1302_DateTime;
DS1302_DateTime_t DS1302_DateTime_Now;
static unsigned char GetDayFromDate(unsigned char year, unsigned char month, unsigned char date);
// 发送一个字节,不操作CE
static void DS1302_TxByte(unsigned char byte)
{
unsigned char i = 0;
DS1302_IO_OUT;
for (i = 0; i < 8; i++)
{
DS1302_SCLK_0;
DS1302_DELAY_T_CL;
if (byte & 0x01)
{
DS1302_IO_1;
}
else
{
DS1302_IO_0;
}
DS1302_DELAY_T_DC;
DS1302_SCLK_1;
DS1302_DELAY_T_CH;
byte >>= 1;
}
}
// 接收一个字节,不操作CE
static unsigned char DS1302_RxByte(void)
{
unsigned char i = 0;
unsigned char byte = 0;
DS1302_IO_IN;
DS1302_IO_1;
for (i = 0; i < 8; i++)
{
DS1302_SCLK_0;
DS1302_DELAY_T_CDD;
byte >>= 1;
if (DS1302_IO_VALUE)
{
byte |= 0x80;
}
DS1302_SCLK_1;
DS1302_DELAY_T_CH;
}
return byte;
}
static void DS1302_WriteByte(unsigned char address, unsigned char _data)
{
DS1302_SCLK_0;
DS1302_CE_1;
DS1302_DELAY_T_CC;
DS1302_TxByte(address);
DS1302_TxByte(_data);
DS1302_SCLK_0;
DS1302_DELAY_T_CCH;
DS1302_CE_0;
DS1302_DELAY_T_CWH;
}
static unsigned char DS1302_ReadByte(unsigned char address)
{
unsigned char _data = 0;
DS1302_SCLK_0;
DS1302_CE_1;
DS1302_DELAY_T_CC;
DS1302_TxByte(address | 0x01);
_data = DS1302_RxByte();
DS1302_SCLK_0;
DS1302_DELAY_T_CCH;
DS1302_CE_0;
DS1302_DELAY_T_CWH;
return _data;
}
#if DS1302_AUTO_TO_DEC == 1
static unsigned char DecToBcd(unsigned char d)
{
return ((((d) / 10) << 4) + ((d) % 10));
}
static unsigned char BcdToDec(unsigned char b)
{
return ((((b) >> 4) * 10) + ((b) & 0x0f));
}
#endif /* DS1302_AUTO_TO_DEC == 1 */
void DS1302_SetDateTime(void)
{
unsigned char temp = 0;
DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x00); // 关闭写保护
DS1302_WriteByte(DS1302_YEAR_ADDR, DEC_TO_BCD(DS1302_DateTime.Year));
DS1302_WriteByte(DS1302_MONTH_ADDR,DEC_TO_BCD(DS1302_DateTime.Month));
DS1302_WriteByte(DS1302_DATE_ADDR, DEC_TO_BCD(DS1302_DateTime.Date));
DS1302_WriteByte(DS1302_MINUTE_ADDR, DEC_TO_BCD(DS1302_DateTime.Minute));
DS1302_WriteByte(DS1302_SECOND_ADDR, DEC_TO_BCD(DS1302_DateTime.Second));
DS1302_WriteByte(DS1302_DAY_ADDR, DEC_TO_BCD(GetDayFromDate(DS1302_DateTime.Year, DS1302_DateTime.Month, DS1302_DateTime.Date)));
temp = DEC_TO_BCD(DS1302_DateTime.Hour);
if (DS1302_DateTime.HourMode == _12_hours)
{
temp |= 0x80;
temp |= (DS1302_DateTime.AM_PM == pm ? 0x20 : 0);
}
DS1302_WriteByte(DS1302_HOUR_ADDR, temp);
DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x80); // 写入完毕后设置写保护
}
void DS1302_GetDateTime(void)
{
unsigned char temp = 0;
DS1302_Update = 0;
DS1302_DateTime_Now.Year = BCD_TO_DEC(DS1302_ReadByte(DS1302_YEAR_ADDR));
DS1302_DateTime_Now.Month= BCD_TO_DEC(DS1302_ReadByte(DS1302_MONTH_ADDR));
DS1302_DateTime_Now.Date = BCD_TO_DEC(DS1302_ReadByte(DS1302_DATE_ADDR));
DS1302_DateTime_Now.Hour = BCD_TO_DEC(DS1302_ReadByte(DS1302_HOUR_ADDR));
DS1302_DateTime_Now.Minute = BCD_TO_DEC(DS1302_ReadByte(DS1302_MINUTE_ADDR));
DS1302_DateTime_Now.Second = BCD_TO_DEC(DS1302_ReadByte(DS1302_SECOND_ADDR));
DS1302_DateTime_Now.Day = BCD_TO_DEC(DS1302_ReadByte(DS1302_DAY_ADDR));
temp = DS1302_ReadByte(DS1302_HOUR_ADDR);
if (temp & 0x80)
{
DS1302_DateTime_Now.HourMode = _12_hours;
DS1302_DateTime_Now.AM_PM = ((temp & 0x20) ? pm : am);
temp &= 0x1f;
}
DS1302_DateTime_Now.Hour = BCD_TO_DEC(temp);
}
void DS1302_Scan(void)
{
static unsigned second_last = 0;
DS1302_DateTime.Second = BCD_TO_DEC(DS1302_ReadByte(DS1302_SECOND_ADDR));
if (second_last != DS1302_DateTime.Second)
{
second_last = DS1302_DateTime.Second;
DS1302_Update = 1;
}
}
void DS1302_Init(void)
{
// 端口初始化
DS1302_CE_0;
DS1302_CE_OUT;
DS1302_SCLK_0;
DS1302_SCLK_OUT;
DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x00); // 关闭写保护
DS1302_WriteByte(DS1302_TRICKLE_CHARGE_ADDR, 0xa7); // 使能涓流充电 1 Diode, 8kΩ
if (DS1302_ReadByte(DS1302_SECOND_ADDR) & 0x80) // 振荡器未启动
DS1302_WriteByte(DS1302_SECOND_ADDR, 0x00); // 启动振荡器
DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x80); // 打开写保护
}
// 计算2000~2099年任一天星期几
// year : 00-99
// month : 01-12
// day : 01-31
// 返回 1 -> 7 : 星期一 -> 星期天
static unsigned char GetDayFromDate(unsigned char year, unsigned char month, unsigned char date)
{
if (month == 1 || month == 2)
{
month += 12;
if (year > 0)
year--;
else
year = 4;
}
return (1 + ((date + 2 * month + 3 * (month + 1) / 5 + year + year / 4) % 7));
}
void DS1302_SetDataTimeInit(void)
{
DS1302_DateTime.Year = 15;
DS1302_DateTime.Month = 4;
DS1302_DateTime.Date = 29;
DS1302_DateTime.Hour = 00;
DS1302_DateTime.Minute = 58;
DS1302_DateTime.Second = 00;
DS1302_DateTime.Day = 2;
DS1302_DateTime.HourMode = _24_hours;
DS1302_DateTime.AM_PM = am;
}
没搞过,帮顶… 多谢分享
页:
[1]