📄 8563.c
字号:
/////////////////////////////////////////////////////////////
// 文件:RT_PCF8563.C //
// 环境:编译为ICC AVR6.31A,仿真为AVR Studio4.12sp4 //
// 硬件:ATMEGA16芯片 //
// 日期:2007年5月28日 //
// 功能:在LCD12864液晶屏显示时间 //
// 备注: //
/////////////////////////////////////////////////////////////
#include <iom16v.h> //包含单片机型号头文件
#include <macros.h> //包含"位"操作头文件
//#include "AVR_XQV12.h"
#include "lcd.h"
#include "delay.h" //包含延时头文件
#define rd_device_add 0xa3 //定义器件读地址
#define wr_device_add 0xa2 //定义器件写地址
#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28
#define RE_START 0x10
#define MR_SLA_ACK 0x40
#define MR_DATA_NOACK 0x58
#define MR_DATA_ACK 0x50
#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28
#define RE_START 0x10
#define MR_SLA_ACK 0x40
#define MR_DATA_NOACK 0x58
unsigned char read_shijian[7]={0x02,0x21,0x16,0x24,0x00,0x12,0x27};
unsigned char write_shijian[7]={0x00,0x48,0x10,0x10,0x00,0x06,0x07};
unsigned char temp[3];
/*******************************************************/
/****** TWI总线操作函数 ******/
/****** Start(): 总线起始命令 ******/
/****** Wait(): 等待命令 ******/
/****** TestAck(): 测试应答 ******/
/****** Write8Bit():写8位数据 ******/
/****** Stop(): 总线结束命令 ******/
/****** Ack(): 应答信号 ******/
/****** Twi(): 总线使能 ******/
/*******************************************************/
void Start(void)
{TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);}
void Wait(void)
{while((TWCR&0x80)!=0x80);}
unsigned char TestAck(void)
{unsigned char twsr;twsr=TWSR&0xf8;return twsr;}
void Write8Bit(unsigned char data)
{TWDR=data;TWCR=(1<<TWINT)|(1<<TWEN);}
void Stop(void)
{TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);}
void Ack(void)
{TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);}
void Twi(void)
{TWCR=(1<<TWINT)|(1<<TWEN);}
/*#####################################################*/
/*******************************************************/
/****** 函数名称: i2c_Write() ******/
/****** 功 能: 向I2C总线写数据 ******/
/****** 参 数: command--数据内容 ******/
/****** RomAddress--目标地址 ******/
/****** 返回值 : 无 ******/
/*******************************************************/
unsigned char i2c_Write(unsigned char command,unsigned char RomAddress)
{
Start(); //发总线起始命令
Wait(); //等待应答
if(TestAck()!=START)return 1; //测试应答
Write8Bit(wr_device_add); //写器件地址
Wait(); //等待应答
if(TestAck()!=MT_SLA_ACK)return 2; //测试应答
Write8Bit(RomAddress); //写器件内的寄存器地址
Wait(); //等待应答
if(TestAck()!=MT_DATA_ACK)return 3; //测试应答
Write8Bit(command); //写命令
Wait(); //等待应答
if(TestAck()!=MT_DATA_ACK)return 4; //测试应答
Stop(); //停止总线
delay_nms(10); //延时
return 0;
}
/*******************************************************/
/****** 函数名称: i2c_WriteData() ******/
/****** 功 能: 向I2C总线连续写入7个数据 ******/
/****** 参 数: RomAddress--目标起始寄存器 ******/
/****** 返回值 : 无 ******/
/*******************************************************/
unsigned char i2c_WriteData(unsigned char RomAddress)
{
unsigned char i;
Start(); //发总线起始命令
Wait(); //等待应答
if(TestAck()!=START)return 1; //测试应答
Write8Bit(wr_device_add); //写器件地址
Wait(); //等待应答
if(TestAck()!=MT_SLA_ACK)return 2; //测试应答
Write8Bit(RomAddress); //写器件内的寄存器地址
Wait(); //等待应答
if(TestAck()!=MT_DATA_ACK)return 3; //测试应答
for(i=0;i<7;i++) //循环7次
{
Write8Bit(write_shijian[i]); //写数据
Wait(); //等待应答
if(TestAck()!=MT_DATA_ACK)return 4; //测试应答
}
Stop(); //停止总线
delay_nms(10); //延时
return 0;
}
/*******************************************************/
/****** 函数名称: i2c_Read() ******/
/****** 功 能: 连续读取I2C总线 ******/
/****** 参 数: RomAddress--目标寄存器 ******/
/****** 返回值 : 读出的数据 ******/
/*******************************************************/
unsigned char i2c_Read(unsigned char RomAddress)
{
unsigned char i;
Start(); //发总线起始命令
Wait(); //等待应答
if(TestAck()!=START)return 1; //测试应答
Write8Bit(wr_device_add); //写器件地址
Wait(); //等待应答
if(TestAck()!=MT_SLA_ACK)return 2; //测试应答
Write8Bit(RomAddress); //写器件内的寄存器地址
Wait(); //等待应答
if(TestAck()!=MT_DATA_ACK)return 3; //测试应答
Start(); //重新发总线起始命令
Wait(); //等待应答
if(TestAck()!=RE_START)return 4; //测试应答
Write8Bit(rd_device_add); //写器件地址
Wait(); //等待应答
if(TestAck()!=MR_SLA_ACK)return 5; //测试应答
for(i=0;i<7;i++)
{
Ack(); //发送应答信号
Wait(); //等待应答
if(TestAck()!=MR_DATA_ACK)return 6; //测试应答
read_shijian[i]=TWDR; //将读取的数据放入数组中
}
Stop(); //停止总线
return 0;
}
/*******************************************************/
/****** 函数名称: ToStr() ******/
/****** 功 能: 整数转换成字符串 ******/
/****** 参 数: c--要转换的数据 ******/
/****** 返回值 : 无 ******/
/*******************************************************/
void ToStr(unsigned char c)
{
temp[2]=0;
temp[1]=(c&0x0f)+0x30;
temp[0]=((c&0xf0)>>4)+0x30;
}
/*******************************************************/
/****** 函数名称: Twi_Init() ******/
/****** 功 能: 初始化TWI总线 ******/
/****** 参 数: 无 ******/
/****** 返回值 : 无 ******/
/*******************************************************/
void Twi_Init(void)
{
TWBR=32; //设置波特率
TWSR=0; //复位TWI总线
i2c_Write(0,0); //设置时钟状态
i2c_Write(0x81,0x0d);
i2c_Write(0x82,0x0e);
i2c_Write(1,0x0f);
i2c_Write(0x81,0x01);
i2c_Write(0x50,0x02);
i2c_Write(0x04,0x03);
i2c_Write(0x09,0x04);
i2c_Write(0x01,0x05);
i2c_Write(0x05,0x06);
i2c_Write(0x08,0x07);
i2c_Write(0x08,0x02);
}
/*******************************************************/
/****** 函数名称: main() ******/
/****** 功 能: 在液晶屏显示时间 ******/
/****** 参 数: 无 ******/
/****** 返回值 : 无 ******/
/*******************************************************/
void main(void)
{ CLI();
Lcd_INT();
lcd_clear();
delay_nms(500); //延时
Twi_Init(); //初始化TWI总线
LCD_Write_string(0,0,"AVR_XQV1.2开发板");//向液晶屏写入初始数据
LCD_Write_string(1,0,"20");
LCD_Write_string(1,2,"年");
LCD_Write_string(1,4,"月");
LCD_Write_string(1,6,"日");
LCD_Write_string(2,0,"星");
LCD_Write_string(2,1,"期");
LCD_Write_string(3,1,"时");
LCD_Write_string(3,3,"分");
LCD_Write_string(3,5,"秒");
SEI(); //开中断
while(1)
{
i2c_Write(0x19,0x01); //向PCF8563写命令
i2c_Read(0x02); //读取时间数据
ToStr(read_shijian[0]&0x7f); //转换成字符串
LCD_Write_string(3,4,temp); //刷新时间
ToStr(read_shijian[1]&0x7f); //转换成字符串
LCD_Write_string(3,2,temp); //刷新时间
ToStr(read_shijian[2]&0x3f); //转换成字符串
LCD_Write_string(3,0,temp); //刷新时间
ToStr(read_shijian[3]&0x3f); //转换成字符串
LCD_Write_string(1,5,temp); //刷新时间
switch(read_shijian[4]&0x07) //转换成字符串
{
case 0:LCD_Write_string(2,2,"日");break;//刷新时间
case 1:LCD_Write_string(2,2,"一");break;//刷新时间
case 2:LCD_Write_string(2,2,"二");break;//刷新时间
case 3:LCD_Write_string(2,2,"三");break;//刷新时间
case 4:LCD_Write_string(2,2,"四");break;//刷新时间
case 5:LCD_Write_string(2,2,"五");break;//刷新时间
case 6:LCD_Write_string(2,2,"六");break;//刷新时间
}
ToStr(read_shijian[5]&0x1f); //转换成字符串
LCD_Write_string(1,3,temp); //刷新时间
ToStr(read_shijian[6]); //转换成字符串
LCD_Write_string(1,1,temp); //刷新时间
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -