📄 pcf8563.c
字号:
//************************************************************************
// pcf8563.c: 24/11/2006
//
// 外部程序会调用到的函数有:
// pcf_init,pcf_set_time,pcf_get_time
// pcf_clkout_start,pcf_clkout_stop,pcf_timer_start,pcf_timer_stop
//
//***************************************************************************
#include "msp430x14x.h"
#include "pcf8563.h"
//定义全局变量
char pcf_bcon1; //Control/Status1
char pcf_bcon2; //Control/Status2
char pcf_bsecond; //Seconds
char pcf_bminute; //Minutes
char pcf_bhour; //Hours
char pcf_bday; //Days
char pcf_bweek; //Weekdays
char pcf_bmonth; //Months/Century
char pcf_byear; // Years
char pcf_bminutealarm; //Minute alarm
char pcf_bhouralarm; //Hour alarm
char pcf_bdayalarm; //Day alarm
char pcf_bweekalarm; //Weekday alarm
char pcf_bclkoutfreq; //CLKOUT frequency
char pcf_btimerfreq; //Timer control
char pcf_btimer; //Timer countdown value
char pcf_b10ms; //
unsigned int pcf_wdate; //储存seconds,minutes,hours
unsigned int pcf_wtime; //储存days,months,years
/****************************************************************************/
/* 开始iic总线 */
/* Function : iic_start */
/* Input : none */
/* Output : none */
/* Description : */
/* SDA置高、SCL置高、SDA置低、SCL置低, */
/****************************************************************************/
void iic_start ( void )
{
P3DIR &= ~PCF_SDA; //SDA置高
P3DIR &= ~PCF_SCL; //SCL置高
P3DIR |= PCF_SDA; //SDA置低,同时把SDA管脚设为输出
P3DIR |= PCF_SCL; //SCL置低
}
/*******************************************************************************/
/* 停止iic总线 */
/* Function : iic_stop */
/* Input : none */
/* Output : none */
/* Description : SDA置低、SCL置高、SDA置高 */
/* 说明:程序中是通过设置P口的方向寄存器来实现SDA、SCL置高和置低的 */
/* 由于有上拉电平,所以当P口是输入时为高电平,当切换为输出模式时,P口 */
/* 默认输出低电平。 */
/*******************************************************************************/
void iic_stop (void )
{
P3DIR |= PCF_SDA; //SDA置低
P3DIR &= ~PCF_SCL; //SCL置高
P3DIR &= ~PCF_SDA; //SDA置高
}
/*******************************************************************************/
/* 发送确认信息 SEND ACKNOWLEDGE */
/* Function : iic_set_ack */
/* Input : none */
/* Output : none */
/* Description : */
/* SCL置低、SDA置低、SCL置高、SCL置低、SDA置高; */
/* 表示从机收到一个字节 */
/*******************************************************************************/
void iic_set_ack ( void )
{
P3DIR |= PCF_SCL;
P3DIR |= PCF_SDA;
P3DIR &= ~PCF_SCL;
P3DIR |= PCF_SCL;
P3DIR &= ~PCF_SDA;
}
/*******************************************************************************/
/* Send NAK(not acknowledge) */
/* Function : iic_set_nak */
/* Input : none */
/* Output : none */
/* Description : */
/* SCL置低、SDA置高、SCL置高、SCL置低; */
/*******************************************************************************/
void iic_set_nak ( void )
{
P3DIR |= PCF_SCL;
P3DIR &= ~PCF_SDA;
P3DIR &= ~PCF_SCL;
P3DIR |= PCF_SCL;
}
/*******************************************************************************/
/* 获取应答信息(从机是否收到) */
/* Function : iic_get_ack */
/* Input : none */
/* Output : int */
/* Description : SCL置低,SCLP置高, */
/* 判断SDA是否为低,为低时(收到ACK)返回1,SCL置低 */
/*******************************************************************************/
char iic_get_ack ( void )
{
char temp = 0;
P3DIR |= PCF_SCL; //SCL置低
P3DIR &= ~PCF_SCL; //SCL置高
_NOP();
_NOP();
if ( !(P3IN & PCF_SDA) ) // SDA=0 ?
{
P3DIR |= PCF_SCL; //if SDA=0,表示收到ACKNOWLEDGE
temp = 1;
}
return(temp);
}
/*******************************************************************************/
/* 从PCF8563读取一个字节到MSP430,接受顺序是从MSB到LSB */
/* Function : ziic_read */
/* Input : none */
/* Output : char -- 读到的字节 */
/* Description : */
/* SCL置高、读SDA数据、SCL置低、SCL置高、读SDA数据...... */
/*******************************************************************************/
char ziic_read( void )
{
char value = 0;
char i;
for(i = 0;i<8;i++)
{
P3DIR &= ~PCF_SCL; //SCL置高
_NOP();
_NOP();
if(P3IN & PCF_SDA) // SDA=1 ?
value |= (0x01 << (7-i));
P3DIR |= PCF_SCL; //SCL置低
}
return (value);
}
/*******************************************************************************/
/* 将MSP430中的一个字节写入PCF8563(顺序从MSB到LSB) */
/* Function : ziic_write */
/* Input : char value -- 待写入PCF8563的字节 */
/* Output : none */
/* Description : */
/* 写SDA数据、SCL置高、SCL置低......写SDA数据、SCL置高、SCL置低 */
/*******************************************************************************/
void ziic_write( char value )
{
char i;
for(i = 0;i<8;i++)
{
if (value & 0x80)
P3DIR &= ~PCF_SDA; //value该位为1,SDA置高
else
P3DIR |= PCF_SDA; //value该位为0,SDA置低
P3DIR &= ~PCF_SCL; //SCL置高
_NOP();
_NOP();
P3DIR |= PCF_SCL; //SCL置低
_NOP();
_NOP();
value <<= 1; //value左移1位
}
P3DIR &= ~PCF_SDA; //SDA置高,并把SDA管脚设为输入
}
/*******************************************************************************/
/* 从PCF8563中读取数据到MSP430中 */
/* Function : ziic_page_read */
/* Input : char *adrmsp -- 接收数组的首地址 */
/* char num -- 读取的字节数 */
/* char adrpcf -- PCF8563内部寄存器的首地址 */
/* Output : none */
/* Description : */
/* 从PCF8563内部第adrpcf个寄存器开始读取num个字节,保存在MSP430的adrsmp数组中 */
/* MSP430写完一个字节,就要getack,以获得对方的反应; */
/* MSP430读完一个字节,发送setack,告知对方,发送有效; */
/* 读完最后一个字节时 发送setnak,告知对方,不必发送; */
/*******************************************************************************/
void ziic_page_read ( char *adrmsp,char num,char adrpcf )
{
char flag = 1;
char i;
while (flag)
{
P3OUT &= ~PCF_SCL;
P3OUT &= ~PCF_SDA; // INITIATE SCL&SDA LOW
iic_start(); // 启动IIC总线
ziic_write( 0x0A2 ); // 发送PCF8563 write slave address(0A2h)给PCF8563
if (!(iic_get_ack())) // iic_get_ack()= 0?
continue; // 如果没有收到ACK则跳转,重发一次
ziic_write( adrpcf ); // 发送PCF8563内部寄存器起始地址
if (!(iic_get_ack()))
continue; // 如果没有收到ACK则跳转,重发一次
iic_start(); // 启动IIC总线
ziic_write( 0x0A3 ); // 发送PCF8563 read slave address(0A3h)给PCF8563
if ( iic_get_ack() ) // iic_get_ack()=1?
flag = 0; // if iic_get_ack()=1,flag置0,结束循环
}
for (i = 0;i<num;i++)
{
adrmsp[i] = ziic_read(); // 把PCF8563内寄存器的数据读到MSP430中
iic_set_ack(); // MSP430发送ACK
} // PCF8563的寄存器可自动增量,不需软件操作了
iic_set_nak(); // MSP430发送NAK,表示不读了
iic_stop();
}
/*******************************************************************************/
/* 从MSP430中写数据到PCF8563中 */
/* Function : ziic_page_write */
/* Input : char *adrmsp -- 待发送数组的首地址 */
/* char num -- 待发送的字节数 */
/* char adrpcf -- 待写入的PCF8563内部寄存器的首地址 */
/* Output : none */
/* Description : */
/* 把430中darmsp[]数组中的字节写入PCF8563内部的寄存器 */
/*******************************************************************************/
void ziic_page_write ( char *adrmsp,char num,char adrpcf )
{
char flag = 1;
char i;
while (flag)
{
P3OUT &= ~PCF_SCL;
P3OUT &= ~PCF_SDA; // INITIATE SCL&SDA LOW
iic_start(); // 启动IIC总线
ziic_write( 0x0A2 ); // 发送PCF8563 write slave address(0A2h)给PCF8563
if(!(iic_get_ack())) //
continue; // 如果没有收到ACK则跳转,重发一次
ziic_write ( adrpcf ); // 发送PCF8563内部寄存器起始地址
if(iic_get_ack())
flag = 0; //if iic_get_ack()=1, 跳出循环
}
for (i = 0;i<num;)
{
ziic_write ( adrmsp[i] ); // 把430内部RAM中的数据写入PCF8563寄存器
if (!(iic_get_ack()))
continue; // 如果没有收到ACK则跳转,重发一次
i++; // 如果收到ACK,继续发送下一个字节
} // PCF8563的寄存器可自动增量,不需软件操作了
iic_stop(); //停止总线
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -