單片機(jī)和PCF8563通信采用IIC協(xié)議,單片機(jī)讀取時(shí)鐘芯片內(nèi)寄存器數(shù)據(jù)或者時(shí)鐘芯片輸出時(shí)間信息給單片機(jī).
本程序知識簡單的顯示時(shí)間,也沒有加入芯片損壞延時(shí)判斷應(yīng)答子函數(shù).,只是了解芯片使用方法
IIC總線和LCD1602函數(shù)包屬于標(biāo)準(zhǔn)代碼。
IIC協(xié)議子函數(shù)包
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA=P2^2; //SDA口設(shè)置
sbit SCL=P2^3; //SCL口設(shè)置
void delay() //略微延時(shí) 6us約>4.7us
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void iic_start() //啟動(dòng)信號
{
SDA=1;
SCL=1;
delay();
SDA=0;
delay();
SCL=0;
}
void iic_stop() //停止信號
{
SDA=0;
SCL=1;
delay();
SDA=1;
delay();
SCL=0;
}
void iic_ack() //應(yīng)答信號
{
uchar i=0;
SCL=1;
delay();
while((SDA==1)&&(i<255))
i++;
SCL=0;
delay();
}
void iic_send_byte(uchar bat) //發(fā)送數(shù)據(jù)
{
uchar i,temp;
temp=bat;
for(i=0;i<=7;i++)
{
temp=temp<<1;
SCL=0;
SDA=CY;
delay();
SCL=1;
delay();
}
SCL=0;
delay();
SDA=1;
delay();
}
uchar iic_rev() //接受數(shù)據(jù)
{
uchar temp,i;
SCL=0;
delay();
SDA=1;
for(i=0;i<=7;i++)
{
SCL=1;
delay();
temp=(temp<<1)|SDA;
SCL=0;
delay();
}
delay();
return temp;
}
void iic_send_add_byte(uchar add,uchar bat) //向某個(gè)地址發(fā)送某數(shù)據(jù)
{
iic_start();
iic_send_byte(0xa2);
iic_ack();
iic_send_byte(add);
iic_ack();
iic_send_byte(bat);
iic_ack();
iic_stop();
}
uchar iic_rec_add_byte(uchar add) //從某個(gè)地址讀出數(shù)據(jù)
{
uchar temp;
iic_start();
iic_send_byte(0xa2);
iic_ack();
iic_send_byte(add);
iic_ack();
iic_start();
iic_send_byte(0xa3);
iic_ack();
temp=iic_rev();
iic_stop();
return temp;
}
LCD1602函數(shù)包:
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;
void Delay1us(uint a)
{
uint b,c;
for(c=a;c>0;c--)
for(b=110;b>0;b--);
}
void LCD1602_WriteCom(uchar com) //寫入命令
{
LCD1602_E=0;
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_DATAPINS=com; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
Delay1us(10);
LCD1602_E=1;
Delay1us(10);
LCD1602_E=0;
Delay1us(10);
LCD1602_DATAPINS=com<<4;
Delay1us(10);
LCD1602_E=1;
Delay1us(10);
LCD1602_E=0;
}
void LCD1602_WriteData(uchar dat) //寫入數(shù)據(jù)
{
LCD1602_E=0;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_DATAPINS=dat; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
Delay1us(10);
LCD1602_E=1;
Delay1us(10);
LCD1602_E=0;
LCD1602_DATAPINS=dat<<4;
Delay1us(10);
LCD1602_E=1;
Delay1us(10);
LCD1602_E=0;
}
void LCD1602_Init() //LCD初始化子程序
{
LCD1602_WriteCom(0x32); //將8位總線轉(zhuǎn)為4位總線
LCD1602_WriteCom(0x28); //在四位線下的初始化
LCD1602_WriteCom(0x0c); //開顯示不顯示光標(biāo)
LCD1602_WriteCom(0x06); //寫一個(gè)指針加1
LCD1602_WriteCom(0x01); //清屏
LCD1602_WriteCom(0x80); //設(shè)置數(shù)據(jù)指針起點(diǎn)
}
//----- 主函數(shù)---------
#include <reg52.h>
#include "lcd.h"
#include "iic.h"
//-----------延時(shí)用于穩(wěn)定-------------
void delay_kk(uint k)
{
while(k--);
}
//------------------------------BCD碼講解---
比如十六進(jìn)制數(shù)0x56 如果代表BCD碼,則其就是代表10進(jìn)制的56 但是在計(jì)算機(jī)里面如果用于計(jì)算他就是86(十進(jìn)制),所以后面例出BCD轉(zhuǎn)10進(jìn)制子函數(shù) PCF8563顯示的數(shù)都是BCD碼
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtml1/01/clip_image002.jpg
//-----------時(shí)間預(yù)設(shè)定值---------
void time_init()
{
iic_send_add_byte(0x02,0x50); //0秒
iic_send_add_byte(0x03,0x59); //0分鐘
iic_send_add_byte(0x04,0x23); //0小時(shí)
iic_send_add_byte(0x05,0x26); //26號
iic_send_add_byte(0x07,0x05); //5月 20世紀(jì)的
iic_send_add_byte(0x08,0x14); //2014年
}
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtml1/01/clip_image004.jpg
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtml1/01/clip_image005.jpg
//----------------PCF8563初始化-----------------
void pcf_init()
{
iic_send_add_byte(0x00,0x00); //啟動(dòng)時(shí)鐘
}
//----------------BCD轉(zhuǎn)10進(jìn)制-----------
uchar bcd_dec(uchar bat)
{
uchar temp1,temp2,tol;
temp1=bat&0x0f;
temp2=(bat&0xf0)>>4;
tol=temp2*10+temp1;
return tol;
}
//------------LCD1602顯示:年,月,日,小時(shí),分鐘,秒,
void display_time(ucharsec,min,hour,dat,moom,year)
{
LCD1602_WriteCom(0x80);
LCD1602_WriteData('_');
LCD1602_WriteData('2');
LCD1602_WriteData('0');
LCD1602_WriteData(year/10+48);
LCD1602_WriteData(year%10+48);
LCD1602_WriteData('/');
LCD1602_WriteData(moom+48);
LCD1602_WriteData('/');
LCD1602_WriteData(dat/10+48);
LCD1602_WriteData(dat%10+48);
LCD1602_WriteCom(0xc4);
LCD1602_WriteData(hour/10+48);
LCD1602_WriteData(hour%10+48);
LCD1602_WriteData(':');
LCD1602_WriteData(min/10+48);
LCD1602_WriteData(min%10+48);
LCD1602_WriteData(':');
LCD1602_WriteData(sec/10+48);
LCD1602_WriteData(sec%10+48);
}
void main()
{
ucharsec,min,hour,dat,moom,year,sec1,min1,hour1,dat1,moom1,year1; //PCF8563讀出的變量和代轉(zhuǎn)換成的十進(jìn)制變量
LCD1602_Init();
iic_send_add_byte(0x00,0x20); // 關(guān)閉時(shí)鐘
delay_kk(1000);
time_init(); //時(shí)鐘芯片初始時(shí)間設(shè)置
pcf_init();
delay_kk(1000);
while(1)
{
sec=0x7f&iic_rec_add_byte(0x02); //讀取秒
min=0x7f&iic_rec_add_byte(0x03); //讀取分鐘
hour=0x3f&iic_rec_add_byte(0x04); //讀取小時(shí)
dat=0x3f&iic_rec_add_byte(0x05); //讀取天數(shù)
moom=0x1f&iic_rec_add_byte(0x07); //讀取月
year=0xff&iic_rec_add_byte(0x08); //讀取年
sec1=bcd_dec(sec); //將讀取的BCD碼秒轉(zhuǎn)換成十進(jìn)制秒以便運(yùn)算
min1=bcd_dec(min);
hour1=bcd_dec(hour);
dat1=bcd_dec(dat);
moom1=bcd_dec(moom);
year1=bcd_dec(year);
display_time(sec1,min1,hour1,dat1,moom1,year1); //LCD1602顯示時(shí)間
}
}
|