PCF8563时钟读取芯片程序 STM32

阅读: 评论:0

#include "PCF8563.h"
u8 c8563_Store[7]={0x50,0x28,0x15,0x05,0x04,0x02,0x15};  //2015.1.1  1时1分1秒
u8 g8563_Store[7];
extern char rtc_num[6];
////上午时间段、下午时间段、晚上时间段
extern char time_morning[4];
extern char time_afternoon[4];
extern char time_night[4];
//读写地址
#define PCF_WR_ADDR  0xA2 //write device-address
#define PCF_RD_ADDR  0xA3 //read device-address
/
/FM24CL16引脚定义
#define PCF_Part  GPIOC
#define PCF_SCL  GPIO_Pin_9
#define PCF_SDA  GPIO_Pin_10
#define SCL_H    GPIO_SetBits(PCF_Part,PCF_SCL);       
#define SCL_L    GPIO_ResetBits(PCF_Part,PCF_SCL);
#define SDA_H    GPIO_SetBits(PCF_Part,PCF_SDA);
#define SDA_L    GPIO_ResetBits(PCF_Part,PCF_SDA);
/*------------------------------------PCF8563 I2C 总线从地址:读:0A3H;写:0A2H;
(地址00H,01H)  用于控制寄存器和状态寄存器
(地址02H~08H)  用于时钟计数器(秒~年计数器)
(地址09H~0CH ) 用于报警寄存器(定义报警条件)
(地址0DH)            控制CLKOUT 管脚的输出频率
(地址0EH 和0FH)  分别用于定时器控制寄存器和定时器寄存器。
秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器,编码格式为BCD,
星期和星期报警寄存器不以BCD 格式编码。
5:BCD 格式寄存器概况
标明“-”的位无效
地址 寄存器名称 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
02h 秒 VL 00~59BCD 码格式数
03h 分钟 - 00~59BCD 码格式数
04h 小时 - - 00~59BCD 码格式数
05h 日 - - 01~31BCD 码格式数
06h 星期 - - - - - 0~6
07h 月/世纪 C - - 01~12 BCD 码格式数
08h 年 00~99 BCD 码格式数
09h 分钟报警 AE 00~59 BCD 码格式数
0Ah 小时报警 AE - 00~23 BCD 码格式数
0BH 日报警 AE - 01~31 BCD 码格式数
0CH 星期报警 AE - - - - 0~6
------------------------------------*/
/********************************************
内部函数,I2C开始
********************************************/
void Start(void)
{
PCF8653_I2C_OutputConfig();
SDA_H;                                          //拉高数据线
SCL_H;                                          //拉高时钟线
delay_us(10);                                    //延时
SDA_L;                                          //产生下降沿
delay_us(10);                                    //延时
SCL_L;                                          //拉低时钟线
}
/********************************************
内部函数,I2C结束
********************************************/
void Stop(void)
{
PCF8653_I2C_OutputConfig();
SDA_L;                                      //拉低数据线
SCL_H;                                      //拉高时钟线
delay_us(10);                                //延时
SDA_H;                                      //产生上升沿
delay_us(
10);                                //延时
}
/**************************************************************************
内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
***************************************************************************/
void WriteACK(u8  ack)
{
PCF8653_I2C_OutputConfig();
if(ack==1) {SDA_H; }
if(ack==0) {SDA_L; }
SCL_H;                                      //拉高时钟线
delay_us(10);                                  //延时
SCL_L;                                      //拉低时钟线
delay_us(10);                                //延时
}
/**************************************
功能:读取SDA应答信号
**************************************/
u8 WaitACK(void)   
{
u8 ACK;
PCF8653_I2C_InputConfig();
SCL_H;                                          //拉高时钟线
delay_us(10);                                    //延时
ACK=GPIO_ReadInputDataBit(PCF_Part,PCF_SDA);    //读应答信号
SCL_L;                                          //拉低时钟线
delay_us(10);                                    //延时
return ACK;
}
/********************************************
内部函数.输出数据字节
入口:B=数据
********************************************/
u8 writebyte(u8 dat)
{
u8 i,ack;
PCF8653_I2C_OutputConfig();
for (i=0; i<8; i++)                            //8位计数器
{
if(dat&0x80){ SDA_H; } 
else    { SDA_L; }
dat <<= 1;                                  //移出数据的最高位
SCL_H;                                      //拉高时钟线
delay_us(10);                                //延时
SCL_L;                                      //拉低时钟线
栏木机delay_us(10);                                //延时
}
ack=WaitACK();
return ack;
}
/********************************************
内部函数.输入数据
出口:B
********************************************/
u8 Readbyte(void)
{
u8 i=0,dat=0;
PCF8653_I2C_OutputConfig();
SDA_H;                                                  //使能内部上拉,准备读取数据,
delay_us(6);
PCF8653_I2C_InputConfig();
for (i=0; i<8; i++)                                    //8位计数器
卡盘扳手
{
dat <<= 1;   
SCL_H;                                              //拉高时钟线
delay_us(10);                                        //延时
dat |= GPIO_ReadInputDataBit(PCF_Part,PCF_SDA);    //读数据             
SCL_L;                                              //拉低时钟线
delay_us(10);                                        //延时
}
return dat;
}
/********************************************
输出数据->pcf8563
********************************************/
void writeDat
a(u8 address,u8 mdata)
{
Start();
writebyte(0xa2);    /*写命令*/
writebyte(address); /*写地址*/
writebyte(mdata);  /*写数据*/
Stop();
}
/********************************************
输入数据<-pcf8563
********************************************/
u8 ReadData(u8 address) /*单字节*/
{
u8  rdata;
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
Start();
writebyte(0xa3); /*读命令*/
rdata=Readbyte();
WriteACK(1);
Stop();
return(rdata);
}
void ReadData1(u8 address,u8 count,u8 * buff) /*多字节*/
{
u8 i;
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
Start();
writebyte(0xa3); /*读命令*/
for(i=0;i<count;i++)
{
buff[i]=Readbyte();
if(i<count-1) WriteACK(0);
}
WriteACK(1);
Stop();
}
/********************************************
内部函数,读入时间到内部缓冲区
********************************************/
void P8563_Read(void)
{
u8 time[7];
ReadData1(0x02,0x08,time);
g8563_Store[0]=time[0]&0x7f; /*秒*/
g8563_Store[1]=time[1]&0x7f; /*分*/
g8563_Store[2]=time[2]&0x3f; /*小时*/
g8563_Store[3]=time[3]&0x3f; /*日*/
g8563_Store[4]=time[4]&0x07; /*星期*/
g8563_Store[5]=time[5]&0x1f; /*月/世纪*/
g8563_Store[6]=time[6]; /*年*/
}
/
********************************************
读入时间到内部缓冲区----外部调用
********************************************/
void P8563_gettime(void)
{
// char i = 0;
//  char a[10] = {0};
P8563_Read();
if(g8563_Store[0]==0)
P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/
//  for( i = 0; i < 7; i++ )
/
/  {
//  a[i] = convert_time(g8563_Store[i]);
//  }
//  printf("%d\t%d\t%d\t%d\t%d\t%d\n", g8563_Store[6], g8563_Store[5], g8563_Store[3], g8563_Store[2],\
//                  g8563_Store[1], g8563_Store[0]);
//  printf("%d\t%d\t%d\t%d\t%d\t%d\n", a[6], a[5],a[3], a[2], a[1], a[0] );
rtc_num[0] = convert_time(g8563_Store[6]); //年
rtc_num[1] = convert_time(g8563_Store[5]); //月
rtc_num[2] = convert_time(g8563_Store[3]); //日
rtc_num[3] = convert_time(g8563_Store[2]); //时
rtc_num[4] = convert_time(g8563_Store[1]); //分
rtc_num[5] = convert_time(g8563_Store[0]); //秒
if( (rtc_num[3] >= time_morning[0]) && (rtc_num[3] < time_morning[2]) )
{
tempOpenWind[0] = openwind_morning[0];
tempOpenWind[1] = openwind_morning[1];
tempCloseWind[0] = closewind_morning[0];
tempCloseWind[1] = closewind_morning[1];
}
else if( (rtc_num[3] >= time_afternoon[0]) && (rtc_num[3] < time_afternoon[2]) )
{
tempOpenWind[0] = openwind_afternoon[0];
tempOpenWind[1] = openwind_afternoon[1];
tempCloseWind[0] = closewind_afternoon[0];格兰注塑机射咀头
tempCloseWind[1] = closewind_afternoon[1];
}
else if( (rtc_num[3] >= time_night[0]) || (rtc_num[3] < time_night[2]) )
{
tempOpenWind[0] = openwind_night[0];
tempOpenWind[1
] = openwind_night[1];
tempCloseWind[0] = closewind_night[0];
tempCloseWind[1] = closewind_night[1];
}
}
/********************************************
写时间修改值
********************************************/
void P8563_settime(void)
{
u8 i;
for(i=2;i<=8;i++) { writeData(i,g8563_Store[i-2]); } //写含小时之后时间
//writeData(6,g8563_Store[3]); //写星期
}
/
********************************************
P8563的初始化-----外部调用
********************************************/
void P8563_init(void)
{
u8 i;
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/*--Config EEPROM SCL GPIO--*/
GPIO_InitStructure.GPIO_Pin = PCF_SCL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PCF_Part,&GPIO_InitStructure);
/*--Config EEPROM SDA GPIO--*/
GPIO_InitStructure.GPIO_Pin = PCF_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;子母锁>竹炭颗粒
GPIO_Init(PCF_Part,&GPIO_InitStructure);
if((ReadData(0x02)&0x7f)==0x8) /* 检查是否第一次启动,是则初始化时间,检查对象为秒
//(0x02)最高位为1则初始化*/
{
for(i=0;i<=6;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
P8563_settime();
P8563_settime();
}
}
/********************************************
把时间数据形式转库十进制
***********************************************/
u8 convert_time(u8 x)
{
return (x>>4)*10+(x&0x0f);
}
/
******************
修改时间,并将修改后的时间写入rtc
**********************/
void Set_time(void)
{
g8563_Store[6] = ((rtc_num[0] / 10) << 4) + rtc_num[0] % 10;
g8563_Store[5] = ((rtc_num[1] / 10) << 4) + rtc_num[1] % 10;
g8563_Store[3] = ((rtc_num[2] / 10) << 4) + rtc_num[2] % 10;
医用手套g8563_Store[2] = ((rtc_num[3] / 10) << 4) + rtc_num[3] % 10;
g8563_Store[1] = ((rtc_num[4] / 10) << 4) + rtc_num[4] % 10;
g8563_Store[0] = ((rtc_num[5] / 10) << 4) + rtc_num[5] % 10;
P8563_settime();
}
/***************************************
功能:SDA设置为浮空输入
****************************************/
void PCF8653_I2C_InputConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = PCF_SDA;        //SDA浮空输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PCF_Part, &GPIO_InitStructure);
}
/***************************************
功能:FRAM_I2C设置为推挽输出
****************************************/
void PCF8653_I2C_OutputConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = PCF_SDA;        //SDA推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PCF_Part, &GPIO_InitStructure);
}
void delay_us(int m)
{
int  i,j;
for(i=0;i<m;i++)
for(j=0;j<10;j++);
}

本文发布于:2023-05-14 08:51:19,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/4/99180.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:寄存器   时间   报警   数据   输出   函数   用于   产生
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图