自己用AVR驱动PCF8563程序为什么显示出错
时间:10-02
整理:3721RD
点击:
自己用AVR驱动PCF8563程序为什么显示出错
写进去的跟读出来的不一样而且还不变化
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include "pgmspace.h"
#include "iocompat.h"
#include "math.h"
#include "define.h"
#include "pcf8563.h"
unsigned char nian=13,yue=8,ri=12,xingqi=1,shi=10,fen=30,miao=25; //初始化的年月日时分秒型
/************************************************************/
/********************IIC_Start起始函数***********************/
/************************************************************/
void IIC_Start(void)
{
SDA_OUT; //数据总线输出
SCL_OUT; //数据总线输出
SDA_1; //数据总线拉高
SCL_1; //时钟总线拉高
delay_us(5); //延迟
SDA_0; //数据总线拉低
delay_us(5);
SCL_0; //数据总线拉高
delay_us(1);
}
/************************************************************/
/********************IIC_Stop停止函数************************/
/************************************************************/
void IIC_Stop(void)
{
SDA_OUT; //数据总线输出
SCL_OUT; //数据总线输出
SCL_1; //时钟总线拉高
delay_us(5); //延迟
SDA_0; //数据总线拉高
delay_us(5);
SDA_1; //数据总线拉低
}
/************************************************************/
/********************IIC_Ack发送应答函数*********************/
/************************************************************/
void IIC_Ack(void)
{
SDA_OUT; //数据输出
SCL_OUT; //时钟输出
delay_us(1);
SDA_0; //发送应答
delay_us(1);
SCL_0; //SCL拉低
delay_us(5);
SCL_1; //SCL拉高
delay_us(5);
SCL_0; //SCL拉低
}
/************************************************************/
/********************IIC_NoAck发送应答函数*********************/
/************************************************************/
void IIC_NoAck(void)
{
SDA_OUT; //数据输出
SCL_OUT; //时钟输出
delay_us(1);
SDA_1; //不发送应答
delay_us(1);
SCL_0; //SCL拉低
delay_us(5);
SCL_1; //SCL拉高
delay_us(5);
SCL_0; //SCL拉低
}
/************************************************************/
/*******************IIC_ReadACK等待应答**********************/
/************************************************************/
unsigned char IIC_ReadACK(void)
{
unsigned char errtime=255;
SCL_OUT; //时钟总线输出
SDA_IN; //数据总线输入
delay_us(1);
SCL_0;
delay_us(5);
SCL_1;
delay_us(5);
SDA_IN; //数据总线输入
delay_us(1);
while(SDA_READ) //等待应答信号
{
errtime--;
if(errtime<0)
{
IIC_Stop(); //没有应答返回0
}
}
SCL_0;
return true; //有返回1
}
/************************************************************/
/*******************Write_Bit写一位数据**********************/
/************************************************************/
void Write_Bit(unsigned char data2)
{
unsigned char i;
SDA_OUT; //数据总线输出
SCL_OUT; //数据总线输出
for(i=8;i>0;i--)
{
SCL_0; //时钟拉低因为只有在SCL=0时SDA变化才有效
if(data&=0x80)
{
SDA_1; //写1
}
else
{
SDA_0; //写0
}
SCL_1; //时钟拉高
delay_us(1);
data<<=1; //左移一位
}
SDA_1;
delay_us(1);
SCL_1; //时钟拉低
delay_us(1);
}
/************************************************************/
/*******************Read_Bit读一位数据***********************/
/************************************************************/
unsigned char Read_Bit(void)
{
unsigned char Read_data;
unsigned char i;
SCL_OUT; //时钟总线输出
SDA_IN; //时钟输入
for(i=8;i>0;i++) //8位一位一位的写
{
SCL_0; //给一个时钟脉冲
delay_us(5);
SCL_1;
delay_us(5);
if(SDA_READ) //读取1写1
{
data|=0x01;
}
data<<=1; //左移一位
delay_us(1);
}
SCL_0;
delay_us(1);
return Read_data; //返回数据
}
/************************************************************/
/*****************Write_Data指定地址写数据*******************/
/************************************************************/
void Write_Data(unsigned char address,unsigned char Write_data)
{
IIC_Start(); //起始信号
Write_Bit(0xa2); //允许写
IIC_ReadACK();
Write_Bit(address); //写地址
IIC_ReadACK();
Write_Bit(Write_data); //写数据
IIC_ReadACK();
IIC_Stop(); //停止信号
}
/************************************************************/
/*****************Read_Data读指定地址数据********************/
/************************************************************/
unsigned char Read_Data(unsigned char address)
{
unsigned char Data_PCF;
IIC_Start(); //起始信号
Write_Bit(0xa2); //允许写
IIC_ReadACK();
Write_Bit(address); //写地址
IIC_ReadACK();
IIC_Start(); //起始信号
Write_Bit(0xa3); //允许读
IIC_ReadACK();
Data_PCF=Read_Bit(); //读数据
IIC_Stop(); //停止信号
return Data_PCF; //返回
}
/************************************************************/
/*****************BCD_16BCD转16进制**************************/
/************************************************************/
unsigned char BCD_16(unsigned char BCD_Data)
{
unsigned char temp_16;
temp_16=((BCD_Data>>4)*10)+(BCD_Data&0x0f);
return temp_16;
}
/************************************************************/
/*****************Six_BCD*16进制转BCD************************/
/************************************************************/
unsigned char Six_BCD(unsigned char Six_BCD)
{
unsigned char temp;
unsigned char data_bcd;
temp=Six_BCD%100;
data_bcd=((temp/10)<<4)|(temp%10);
return data_bcd;
}
/************************************************************/
/******************PCF_Start*启动时钟************************/
/************************************************************/
void PCF_Start(void)
{
Write_Data(0X00,0X00); //启动时钟
}
/************************************************************/
/******************PCF_Stop*停止时钟*************************/
/************************************************************/
void PCF_Stop(void)
{
Write_Data(0X00,0X20); //停止时钟
}
/************************************************************/
/******************Init_PCF*初始化时间***********************/
/************************************************************/
void Init_PCF(void)
{
Write_Data(0x02,Six_BCD(miao)); //初始化秒
Write_Data(0x03,Six_BCD(fen)); //初始化分
Write_Data(0x04,Six_BCD(shi)); //初始化时
Write_Data(0x05,Six_BCD(ri)); //初始化日
Write_Data(0x06,xingqi); //初始化星期
Write_Data(0x07,Six_BCD(yue)); //初始化月
Write_Data(0x08,Six_BCD(nian)); //初始化年
}
void Read_PCF(void) //读取时钟的变化
{
year=BCD_16(Read_Data(0x08)); //读取年
month=BCD_16(Read_Data(0x07)&0X1F); //读取月
week=Read_Data((0x06)&0X07); //读取星期
day=BCD_16(Read_Data(0x05)&0X3f); //读取天
time=BCD_16(Read_Data(0x04)&0X3f); //读取时
minute=BCD_16(Read_Data(0x03)&0X7f); //读取分
second=BCD_16(Read_Data((0x02)&0X7f)); //读取秒
}
写进去的跟读出来的不一样而且还不变化
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include "pgmspace.h"
#include "iocompat.h"
#include "math.h"
#include "define.h"
#include "pcf8563.h"
unsigned char nian=13,yue=8,ri=12,xingqi=1,shi=10,fen=30,miao=25; //初始化的年月日时分秒型
/************************************************************/
/********************IIC_Start起始函数***********************/
/************************************************************/
void IIC_Start(void)
{
SDA_OUT; //数据总线输出
SCL_OUT; //数据总线输出
SDA_1; //数据总线拉高
SCL_1; //时钟总线拉高
delay_us(5); //延迟
SDA_0; //数据总线拉低
delay_us(5);
SCL_0; //数据总线拉高
delay_us(1);
}
/************************************************************/
/********************IIC_Stop停止函数************************/
/************************************************************/
void IIC_Stop(void)
{
SDA_OUT; //数据总线输出
SCL_OUT; //数据总线输出
SCL_1; //时钟总线拉高
delay_us(5); //延迟
SDA_0; //数据总线拉高
delay_us(5);
SDA_1; //数据总线拉低
}
/************************************************************/
/********************IIC_Ack发送应答函数*********************/
/************************************************************/
void IIC_Ack(void)
{
SDA_OUT; //数据输出
SCL_OUT; //时钟输出
delay_us(1);
SDA_0; //发送应答
delay_us(1);
SCL_0; //SCL拉低
delay_us(5);
SCL_1; //SCL拉高
delay_us(5);
SCL_0; //SCL拉低
}
/************************************************************/
/********************IIC_NoAck发送应答函数*********************/
/************************************************************/
void IIC_NoAck(void)
{
SDA_OUT; //数据输出
SCL_OUT; //时钟输出
delay_us(1);
SDA_1; //不发送应答
delay_us(1);
SCL_0; //SCL拉低
delay_us(5);
SCL_1; //SCL拉高
delay_us(5);
SCL_0; //SCL拉低
}
/************************************************************/
/*******************IIC_ReadACK等待应答**********************/
/************************************************************/
unsigned char IIC_ReadACK(void)
{
unsigned char errtime=255;
SCL_OUT; //时钟总线输出
SDA_IN; //数据总线输入
delay_us(1);
SCL_0;
delay_us(5);
SCL_1;
delay_us(5);
SDA_IN; //数据总线输入
delay_us(1);
while(SDA_READ) //等待应答信号
{
errtime--;
if(errtime<0)
{
IIC_Stop(); //没有应答返回0
}
}
SCL_0;
return true; //有返回1
}
/************************************************************/
/*******************Write_Bit写一位数据**********************/
/************************************************************/
void Write_Bit(unsigned char data2)
{
unsigned char i;
SDA_OUT; //数据总线输出
SCL_OUT; //数据总线输出
for(i=8;i>0;i--)
{
SCL_0; //时钟拉低因为只有在SCL=0时SDA变化才有效
if(data&=0x80)
{
SDA_1; //写1
}
else
{
SDA_0; //写0
}
SCL_1; //时钟拉高
delay_us(1);
data<<=1; //左移一位
}
SDA_1;
delay_us(1);
SCL_1; //时钟拉低
delay_us(1);
}
/************************************************************/
/*******************Read_Bit读一位数据***********************/
/************************************************************/
unsigned char Read_Bit(void)
{
unsigned char Read_data;
unsigned char i;
SCL_OUT; //时钟总线输出
SDA_IN; //时钟输入
for(i=8;i>0;i++) //8位一位一位的写
{
SCL_0; //给一个时钟脉冲
delay_us(5);
SCL_1;
delay_us(5);
if(SDA_READ) //读取1写1
{
data|=0x01;
}
data<<=1; //左移一位
delay_us(1);
}
SCL_0;
delay_us(1);
return Read_data; //返回数据
}
/************************************************************/
/*****************Write_Data指定地址写数据*******************/
/************************************************************/
void Write_Data(unsigned char address,unsigned char Write_data)
{
IIC_Start(); //起始信号
Write_Bit(0xa2); //允许写
IIC_ReadACK();
Write_Bit(address); //写地址
IIC_ReadACK();
Write_Bit(Write_data); //写数据
IIC_ReadACK();
IIC_Stop(); //停止信号
}
/************************************************************/
/*****************Read_Data读指定地址数据********************/
/************************************************************/
unsigned char Read_Data(unsigned char address)
{
unsigned char Data_PCF;
IIC_Start(); //起始信号
Write_Bit(0xa2); //允许写
IIC_ReadACK();
Write_Bit(address); //写地址
IIC_ReadACK();
IIC_Start(); //起始信号
Write_Bit(0xa3); //允许读
IIC_ReadACK();
Data_PCF=Read_Bit(); //读数据
IIC_Stop(); //停止信号
return Data_PCF; //返回
}
/************************************************************/
/*****************BCD_16BCD转16进制**************************/
/************************************************************/
unsigned char BCD_16(unsigned char BCD_Data)
{
unsigned char temp_16;
temp_16=((BCD_Data>>4)*10)+(BCD_Data&0x0f);
return temp_16;
}
/************************************************************/
/*****************Six_BCD*16进制转BCD************************/
/************************************************************/
unsigned char Six_BCD(unsigned char Six_BCD)
{
unsigned char temp;
unsigned char data_bcd;
temp=Six_BCD%100;
data_bcd=((temp/10)<<4)|(temp%10);
return data_bcd;
}
/************************************************************/
/******************PCF_Start*启动时钟************************/
/************************************************************/
void PCF_Start(void)
{
Write_Data(0X00,0X00); //启动时钟
}
/************************************************************/
/******************PCF_Stop*停止时钟*************************/
/************************************************************/
void PCF_Stop(void)
{
Write_Data(0X00,0X20); //停止时钟
}
/************************************************************/
/******************Init_PCF*初始化时间***********************/
/************************************************************/
void Init_PCF(void)
{
Write_Data(0x02,Six_BCD(miao)); //初始化秒
Write_Data(0x03,Six_BCD(fen)); //初始化分
Write_Data(0x04,Six_BCD(shi)); //初始化时
Write_Data(0x05,Six_BCD(ri)); //初始化日
Write_Data(0x06,xingqi); //初始化星期
Write_Data(0x07,Six_BCD(yue)); //初始化月
Write_Data(0x08,Six_BCD(nian)); //初始化年
}
void Read_PCF(void) //读取时钟的变化
{
year=BCD_16(Read_Data(0x08)); //读取年
month=BCD_16(Read_Data(0x07)&0X1F); //读取月
week=Read_Data((0x06)&0X07); //读取星期
day=BCD_16(Read_Data(0x05)&0X3f); //读取天
time=BCD_16(Read_Data(0x04)&0X3f); //读取时
minute=BCD_16(Read_Data(0x03)&0X7f); //读取分
second=BCD_16(Read_Data((0x02)&0X7f)); //读取秒
}
