?? i2cclockandtms320lf2407.c
字號:
I2C串行日歷時(shí)鐘與TMS320LF2407的接口及應(yīng)用
源程序代碼:
// 該程序?qū)崿F(xiàn)對I2C總線日歷時(shí)鐘芯片PCF8583的讀寫操作
#include "register.h"
// 系統(tǒng)初始化子程序
void sysinit()
{
asm( " setc INTM "); // 關(guān)閉總中斷
asm( " clrc SXM ") ; // 抑制符號擴(kuò)展
asm( " clrc OVM ") ; // 累加器結(jié)果正常溢出
asm( " clrc CNF ") ; // B0被配置為數(shù)據(jù)空間
*SCSR1=0X81FE; // CLKIN=6M,CLKOUT=24M
*WDCR=0X0E8 ; // 不使能看門狗
*IMR=0X00; // 禁止所有中斷
*IFR=0X0FFFF; // 清除所有的中斷標(biāo)志
WSGR=0x0FFFF; // 不使能所有的等待狀態(tài)
}
// 輸入輸出口初始化子程序
void IOINIT()
{
*MCRB=*MCRB&0X0FFD7; // 配置IOPC3和IOPC5為一般的I/O口方式
*PCDATDIR=*PCDATDIR|0X02828; // 配置IOPC3和IOPC5為輸出方式,且SCL=SDA=1
}
// 軟件延時(shí)子程序
void delay()
{
int i;
for(i=0X07D;i--;) { i=i;}
}
// 啟動(dòng)I2C總線子程序
void START()
{
*PCDATDIR=*PCDATDIR|0X028; // SDA=SCL=1
delay( ); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR&0X0FFDF; // SDA=0
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
delay(); // 軟件延時(shí),以使時(shí)序匹配
}
// 發(fā)送字節(jié)子程序
void TRANSMIT(TRAN)
int TRAN;
{
int flag,sz; // 定義需要的局部變量
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
delay(); // 軟件延時(shí),以使時(shí)序匹配
for(flag=0x0080;flag!=0x00;flag=flag/2) {
sz=TRAN&flag; // 屏蔽掉不需要的位
if(sz==0) *PCDATDIR=*PCDATDIR&0X0FFDF;// 如果相應(yīng)的位為0,則SDA=0
else *PCDATDIR=*PCDATDIR|0X020;// 如果相應(yīng)的位為1,則SDA=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR|0X08; // SCL=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
delay(); // 軟件延時(shí),以使時(shí)序匹配
}
}
// 從機(jī)(即PCF8583芯片)應(yīng)答子程序。返回值為0時(shí),代表操作成功;返回值為1時(shí),代表操作失敗
int SLAVE_ACK()
{
int sz,k=0; // 定義所需要的局部變量
*PCDATDIR=*PCDATDIR|0X0020; // SDA=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR&0X0DFFF; // 設(shè)置IOPC5(SDA)為輸入
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR|0X08; // SCL=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
sz=*PCDATDIR&0X0020; // 檢測數(shù)據(jù)位
if(sz==0X0020) k=1; // 如果數(shù)據(jù)位為1,則證明失敗,則令k=1
else k=0; // 如果數(shù)據(jù)位為0,則證明成功,則保持k=0不變
*PCDATDIR=*PCDATDIR|0X2000; // 設(shè)置IOPC5(SDA)為輸出
*PCDATDIR=*PCDATDIR&0X0FFD7; // SCL=SDA=0
return(k);
}
// I2C停止子程序
void STOP()
{
*PCDATDIR=*PCDATDIR&0X0FFDF; // SDA=0
delay();
*PCDATDIR=*PCDATDIR|0X0008; // SCL=1
delay( ); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR|0X0020; // SDA=1
}
// 字節(jié)寫子程序,即向I2C器件寫1個(gè)字節(jié)的數(shù)據(jù),入口為地址BYTE_ADDR和需要寫入的字節(jié)
// 內(nèi)容T_DATA。返回值為0時(shí),代表操作成功;返回值為1時(shí),代表操作失敗
int BYTE_WR(BYTE_ADDR,T_DATA)
int BYTE_ADDR,T_DATA;
{
int k;
START(); // 啟動(dòng)I2C總線
TRANSMIT(0X0A0); // 送寫控制字
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) TRANSMIT(BYTE_ADDR); // 送出地址
if(k==0) k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) TRANSMIT(T_DATA); // 送出需要保存的數(shù)據(jù)
if(k==0) k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) STOP(); // 設(shè)置停止?fàn)顟B(tài)
return(k);
}
// 接收一個(gè)字節(jié)子程序,出口為接收到的數(shù)據(jù)R_DATA
int RECEIVE()
{
int R_DATA=0,sz,i;
*PCDATDIR=*PCDATDIR&0X0DFFF; // 設(shè)置IOPC5(SDA)為輸入
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
delay(); // 軟件延時(shí),以使時(shí)序匹配
for(i=0;i<8;i++) {
R_DATA=R_DATA<<1; // R_DATA左移一位
*PCDATDIR=*PCDATDIR|0X0008; // SCL=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
sz=*PCDATDIR&0X0020; // 取得相應(yīng)的數(shù)據(jù)位
if(sz==0) R_DATA=R_DATA&0XFFFE; // 如果數(shù)據(jù)位為0,則R_DATA最低位清0
else R_DATA=R_DATA|0x0001; // 如果數(shù)據(jù)位為1,則R_DATA最低位置1
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
delay(); // 軟件延時(shí),以使時(shí)序匹配
}
*PCDATDIR=*PCDATDIR|0X2000; // 設(shè)置IOPC5(SDA)為輸出
return(R_DATA); // 返回接收的字節(jié)
}
// 主機(jī)無應(yīng)答信號子程序
void NO_ACK()
{
*PCDATDIR=*PCDATDIR|0X0008; // SCL=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
}
// 主機(jī)應(yīng)答子程序
void MASTER_ACK()
{
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
*PCDATDIR=*PCDATDIR&0X0FFDF; // SDA=0
*PCDATDIR=*PCDATDIR|0X0008; // SCL=1
delay(); // 軟件延時(shí),以使時(shí)序匹配
*PCDATDIR=*PCDATDIR&0X0FFF7; // SCL=0
}
// 字節(jié)讀子程序,即從I2C器件讀出1個(gè)字節(jié)的數(shù)據(jù),入口為需要讀出的地址BYTE_ADDR,出口
// 為讀出的數(shù)據(jù)R_DATA,通過C語言的參數(shù)傳遞功能實(shí)現(xiàn)。返回值為0X0FFFF時(shí),表示操作失敗;
// 否則操作成功
int BYTE_RD(int BYTE_ADDR)
{
int k,R_DATA;
START(); // 啟動(dòng)I2C總線
TRANSMIT(0XA0); // 送出寫控制字,以寫入地址字節(jié)
k=SLAVE_ACK( ); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) TRANSMIT(BYTE_ADDR);// 送出需要讀出數(shù)據(jù)的地址
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) {
START( ); // 啟動(dòng)I2C總線
TRANSMIT(0XA1);
} // 送出讀控制字
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) {
R_DATA=RECEIVE(); // 接收PCF8583發(fā)出的數(shù)據(jù)
NO_ACK(); // 主機(jī)不作應(yīng)答
STOP(); // 設(shè)置停止?fàn)顟B(tài)
}
if(k==0) return(R_DATA); // 返回一個(gè)讀出的數(shù)據(jù)
else return(0X0FFFF); // 如果整個(gè)讀過程有誤,則返回0X0FFFF
}
// 連續(xù)寫子程序,入口為需要寫的起始地址ADDR,存儲需要寫入數(shù)據(jù)的數(shù)組的首地址ARRY,需要
// 寫入的數(shù)據(jù)的個(gè)數(shù)N
int CON_WR(ADDR,ARRAY,N)
int ADDR,*ARRAY,N;
{
int k;
START(); // 啟動(dòng)I2C總線
TRANSMIT(0X0A0); // 送寫控制字
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) TRANSMIT(ADDR); // 送出要寫數(shù)據(jù)的起始地址
if(k==0) k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) {
for(;N>0;N--,ARRAY++) {
TRANSMIT(*ARRAY); // 送出需要保存的數(shù)據(jù),保存在數(shù)組ARRAY中
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答,地址自動(dòng)加1
if(k==1) break;
}
}
STOP(); // 設(shè)置停止?fàn)顟B(tài)
return(k);
}
// 連續(xù)讀子程序,入口為需要讀的起始地址ADDR,存儲讀出數(shù)據(jù)的數(shù)組首地址ARRY,需要讀出的
// 數(shù)據(jù)的個(gè)數(shù)N
int CON_RD(ADDR,ARRAY,N)
int ADDR,*ARRAY,N;
{
int k,R_DATA;
START(); // 啟動(dòng)I2C總線
TRANSMIT(0XA0); // 送出寫控制字,以寫入地址字節(jié)
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) TRANSMIT(ADDR); // 送出需要讀出數(shù)據(jù)的地址
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) {
START(); // 啟動(dòng)I2C總線
TRANSMIT(0XA1);
} // 送出讀控制字
k=SLAVE_ACK(); // 從機(jī)(即PCF8583芯片)應(yīng)答
if(k==0) {
for(;N>1;N--,ARRAY++) {
R_DATA=RECEIVE(); // 接收PCF8583發(fā)出的數(shù)據(jù)
*ARRAY=R_DATA; // 讀出的數(shù)據(jù)存入數(shù)組
MASTER_ACK(); // 主機(jī)應(yīng)答,地址自動(dòng)加1
}
R_DATA=RECEIVE(); // 接收PCF8583發(fā)出的數(shù)據(jù)
*ARRAY=R_DATA; // 讀出的數(shù)據(jù)存入數(shù)組
NO_ACK(); // 主機(jī)不作應(yīng)答
STOP(); // 設(shè)置停止?fàn)顟B(tài)
}
return(k); // k=0時(shí)表示操作成功,k=1時(shí)表示操作失敗
}
// 主程序
main()
{
int k;
int R_DATA;
static int source[6]={0x0F,0x0E,0x0D,0x0C,0x0B,0x0A};
int result[6];
sysinit(); // 系統(tǒng)初始化
IOINIT(); // 輸入輸出口初始化
k=BYTE_WR(0x00,0x00); // 設(shè)置PCF8583的控制狀態(tài)寄存器,其地址為0x00,值0x00代
// 表的意義請參考相關(guān)資料,若k==0,則證明寫入成功;若k==1,
// 則證明寫入失敗
R_DATA=BYTE_RD(0x00); // 讀出地址單元0X00的值,如果讀出值為0X0FFFF,則表示讀
// 出值有誤
k=CON_WR(0x30,source,6); // 從0x30地址開始連續(xù)寫入6個(gè)數(shù)據(jù)
k=CON_RD(0x30,result,6); // 把寫入的數(shù)據(jù)連續(xù)讀出
}
// 直接返回中斷服務(wù)子程序
void interrupt nothing()
{
return;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -