?? 24c01.c
字號:
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
//*************************************************
//將2004 年1 月25 日星期日 上午11點10分30 秒的時間寫入PCF8563
//以下在PCF8563 的CLKOUT 腳輸出1Hz 的方波
//讀出 年、月、日、星期、時、分、秒,以38400的波特率送往串口
//打開串口調試助手或其他串口調試軟件設置波特率為38400,無校驗,數據位8,停止位1
//**************************************************
#define PCF8563 0x0A //器件地址
#define MAX_BYTE_NUM 10 //一次性接受或發送字節的最大數目
//內存數據定義
unsigned char SlvAdr; //被控器地址
unsigned char SubAdr; //被控器單元地址
unsigned char ByteCnt; //傳送字節數存放單元
unsigned char BitCnt; //I2C 數據位計數器
unsigned char XmtDat [MAX_BYTE_NUM]; //發送數據緩沖區
unsigned char RcvDat [MAX_BYTE_NUM]; //接收數據緩沖區
//unsigned char Second, Minute, Hour, Weekday, Day, Month, Year, Century;
bit ERR=0; //錯誤位
//端口位定義
sbit SDA = P3^7; //模擬I2C 數據傳送位
sbit SCL = P3^6; //模擬I2C 時鐘控制狀態標志
sbit test1 = P1^0;
sbit test2 = P1^1;
void I2CSendData ();
//void Read8563();
void I2CSTA ();
void I2CSendByte (unsigned char _24C01byte);
void I2CSTOP ();
void I2CRcvData ();
unsigned char I2CRcvByte ();
void main ()
{
// 初始化設置
//以下準備送數
//將2004 年1 月25 日星期日 上午11點10分30 秒的時間寫入PCF8563
IE = 0x00;
/*
XmtDat[0] = 0x00; //啟動時鐘
XmtDat[1] = 0x1F; //設置報警及定時器中斷,定時器中斷為脈沖形式
XmtDat[2] = 0x30; //秒值(30s)
XmtDat[3] = 0x10; //分值(10min)
XmtDat[4] = 0x11; //時值(11h)
XmtDat[5] = 0x25; //日期(25號)
XmtDat[6] = 0x00; //星期(0~6代表星期日~星期六)
XmtDat[7] = 0x01; //月份(如果首字節為1代表19XX年,首字節為0代表20XX年)
XmtDat[8] = 0x04; //年份(04年,與上一字節配合,確定為2004年)
SlvAdr = PCF8563; //送被控器地址
SubAdr = 0x00; //送寫入寄存器的首字節地址,從00H 開始寫
*/ ByteCnt = 0x02; //寫七個時間信息和2 個控制命令
/* I2CSTA(); //發送I2C 總線起始條件
I2CSendByte (0xA0); //Chip selected bits=000, Write
I2CSendByte (0xA1);
I2CSendByte (0x55);
I2CSendByte (0x56);
I2CSTOP (); //發送I2C 總線停止條件 */
/*
I2CSTA();
I2CSendByte (0xA0); //Write
I2CSendByte (0x01);
I2CSTA();
I2CSendByte (0xA1); //Read
RcvDat[0] = I2CRcvByte();
I2CSTOP();
if (RcvDat[0] == 0x55) test1 = 0;
*/
SlvAdr = 0xA0;
SubAdr = 0x01;
XmtDat [0] = 0x55;
XmtDat [1] = 0x66;
I2CSendData ();
while(1){
SlvAdr = 0xA0;
SubAdr = 0x01;
I2CRcvData ();
if (RcvDat[0] == 0x55 && RcvDat[1] == 0x66){ test2 = 1; test1 = ~test1;}
}
// if (ERR == 1) test1 = ~test1;
// I2CSendData(); //送出數據
// Read8563();
}
//*******************************************************************
//以下在PCF8563 的CLKOUT 腳輸出1Hz 的方波,輸出由0DH控制
//0DH 7 6 5 4 3 2 1 0
// PE - - - - - FD1 FD0
// PE=0;CLKOUT禁止輸出并設成高阻抗
// PE=1;CLKOUT允許輸出
// FD1 FD0 輸出頻率
// 0 0 32768Hz
// 0 1 1024Hz
// 1 0 32Hz
// 1 1 1Hz
//要求輸出32768Hz,1024Hz,32Hz,1Hz的數據分別為80H,81H,82H和83H
//********************************************************************
//以下每隔1s左右讀取時間并將時間送往串口
/*;**********************************************************
;延時1s的子程序
;**********************************************************
D1S:
PUSH ACC
PUSH PSW
SETB RS0
MOV R7,#20
D11: MOV R6,#200
D12: MOV R5,#100
DJNZ R5,$
DJNZ R6,D12
DJNZ R7,D11
POP PSW
POP ACC
RET
;**********************************************************
;向串口送數的子程序
;***********************************************************
SEND:
MOV SBUF,A
SLP:
JBC TI,NEXT ;是否送完?
AJMP SLP
NEXT: RET */
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
//I2C總線的讀寫子程序 ;;
//被控器地址在SlvAdr,單元地址在SubAdr中,所發送的數據字節數在ByteCnt中 ;;
//所發送的數據在XmtDat中,所接收的數據在RcvDat中 ;;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
//************************************************************************************************
//發送數據程序
//名稱:I2CSendData
//描述:發送ByteCnt個字節給被控器
//被控器地址在SlvAdr中,單元地址在SubAdr中
//所發送數據的字節數在ByteCnt中,發送的數據在XmtDat緩沖區中
//發送數據正常返回標志ERR=0, ERR=1表示被控器無應答或損壞
//***********************************************************************************************
void I2CSendData ()
{
unsigned char i;
// SETB RS0
I2CSTA(); //發送I2C 總線起始條件
I2CSendByte (SlvAdr); //寫一個字節
// JB ERR,I2CSRN ;錯誤返回
I2CSendByte (SubAdr);
// JB ERR,I2CSRN
for (i = 0; i < ByteCnt; i ++)
{
I2CSendByte (XmtDat [i]);
// JB ERR,I2CSRN
}
I2CSTOP (); //發送I2C 總線停止條件
// if (ERR == 1) test1 = 0;
}
/*************************************************************************************************
;接收數據程序
;名稱:I2CRcvData
;描述:從被控器接收ByteCnt個字節數據
;被控器地址在SlvAdr中,單元地址在SubAdr中
;所接收數據的字節數在ByteCnt中,接收的數據在RcvDat緩沖區中
;接收數據正常返回標志ERR=0, ERR=1表示被控器無應答或損壞
;************************************************************************************************/
void I2CRcvData()
{
unsigned char i;
// SETB RS0
I2CSTA(); //發送I2C 總線起始條件
I2CSendByte (SlvAdr); //寫入器件地址
// JB ERR,I2CRRN ;錯誤返回
I2CSendByte (SubAdr); //寫入單元地址
// JB ERR,I2CRRN
I2CSTA (); //發送I2C 總線重復起始條件
SlvAdr = SlvAdr | 0x01;
I2CSendByte (SlvAdr); //再次寫入器件地址
// JB ERR,I2CRRN
for (i = 0; i < ByteCnt; i ++)
{
RcvDat [i] = I2CRcvByte ();
SDA = 0; //發送應答位
SCL = 1; //250ns后置時鐘線為高通知被控器開始接收應答位
_nop_(); //保證時鐘高周期大于4us
_nop_();
_nop_();
_nop_();
SCL = 0; //鉗住I2C 總線以便繼續接收字接數據
}
SDA = 1; //發送非應答位
SCL = 1; //250ns后置時鐘線為高通知被控器開始接收非應答位
_nop_(); //保證時鐘高周期大于4us
_nop_();
_nop_();
_nop_();
SCL = 0; //鉗住I2C 總線以便發送停止條件
SDA = 0; //
I2CSTOP ();
}
/*******************************************************************************
; 子程序
;******************************************************************************
;名稱:I2CSTA
;描述:啟動I2C 總線子程序--發送I2C 總線起始條件
;------------------------------------------------------------------------------
*/
void I2CSTA ()
{
SCL = 0;
SDA = 1; //發送起始條件的數據信號
SCL = 1; //250ns后發送起始條件的時鐘信號
_nop_(); //起始條件建立時間大于4.7us
_nop_();
_nop_();
_nop_();
_nop_();
SDA = 0; //發送起始信號
_nop_(); //起始條件鎖定時間大于4us
_nop_();
_nop_();
_nop_();
SCL = 0; //鉗住I2C 總線準備發送或接收數據
}
/*------------------------------------------------------------------------------
;名稱:I2CSTOP
;描述:停止I2C 總線子程序--發送I2C 總線停止條件
;------------------------------------------------------------------------------
*/
void I2CSTOP ()
{
SDA = 0; //發送停止條件的數據信號
SCL = 1; //250ns后發送停止條件的時鐘信號
_nop_(); //停止條件建立時間大于4us
_nop_();
_nop_();
_nop_();
_nop_();
SDA = 1; //發送I2C 總線停止信號
}
/*------------------------------------------------------------------------------
;名稱:I2CSentByte
;描述:字節數據傳送子程序--發送一個字節數據或地址給被控器
;要發送的數據在ACC中
;發送數據正常返回標志ERR=0,ERR=1表示被控器無應答或損壞.
;------------------------------------------------------------------------------
*/
void I2CSendByte (unsigned char _8563byte)
{
unsigned char i;
BitCnt = 0x08; //向VSDA線上發送1個數據字節
for ( i = BitCnt; i > 0; i --)
{
// _nop_();
SDA = (_8563byte >> (i - 1)) % 2; //發送數據位
SCL = 1; //250ns后置時鐘線為高通知被控器開始接收數據位
_nop_(); //保證時鐘高周期大于4us
_nop_();
_nop_();
_nop_();
SCL = 0; //鉗住時鐘總線準備接收下一個數據位
_nop_(); //保證時鐘低周期大于4.7us
}
_nop_();
_nop_();
SDA = 1; //8位發送完后釋放數據線準備收應答位
SCL = 1; //開始接收應答信號
// _nop_();
ERR = 0;
if (SDA == 1) ERR = 1;
SCL = 0;
}
/*------------------------------------------------------------------------------
;名稱:I2CRcvByte
;描述:字節數據接收子程序--從被控器接收一個字節數據
;接收的字節數據在ACC中
;------------------------------------------------------------------------------*/
unsigned char I2CRcvByte ()
{
unsigned char res, i;
BitCnt = 0x08; //從VSDA線上讀取1個數據字節
res = 0x00;
for (i = 0; i < BitCnt; i ++)
{
SDA = 1; //置數據線為輸入方式
SCL = 1; //置時鐘線為高使數據線上數據有效
res = (res << 1) | SDA; //接收數據存入res
SCL = 0; //接收結束鉗住總線準備下一步接收或發送(非)應答位
_nop_(); //時鐘低周期大于4.7us
}
return res;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -