?? i2c.c
字號:
/*****************************************/
/* Copyright (c) 2005, 通信工程學院 */
/* All rights reserved. */
/* 作 者:戴 佳 */
/*****************************************/
#include "I2C.h"
/* 延時約5微秒,對于12M時鐘 */
void delay5us()
{
uint i;
for (i=0;i<5;i++)
_nop_();
}
/* 起始條件子函數 */
void start(void)
{
SDA = 1; // 啟動I2C總線
SCL = 1;
delay5us();
SDA = 0;
delay5us();
SCL = 0;
}
/* 停止條件子函數 */
void stop(void)
{
SDA = 0; // 停止I2C總線數據傳送
SCL = 1;
delay5us();
SDA = 1;
delay5us();
SCL = 0;
}
/* 發送應答子函數 */
void ack(void)
{
SDA = 0; // 發送應答位
SCL = 1;
delay5us();
SDA = 1;
SCL = 0;
}
/* 發送非應答子函數 */
void n_ack(void)
{
SDA = 1; // 發送非應答位
SCL = 1;
delay5us();
SDA = 0;
SCL = 0;
}
/* 應答位檢查子函數 */
void checkack(void)
{
SDA = 1; // 應答位檢查(將p1.0設置成輸入,必須先向端口寫1)
SCL = 1;
nackFlag = 0;
if(SDA == 1) // 若SDA=1表明非應答,置位非應答標志F0
nackFlag = 1;
SCL = 0;
}
/* 發送一個字節數據子函數 */
void sendbyte(uchar idata *ch)
{
uchar idata n = 8;
uchar idata temp;
temp = *ch;
while(n--)
{
if((temp&0x80) == 0x80) // 若要發送的數據最高位為1則發送位1
{
SDA = 1; // 傳送位1
SCL = 1;
delay5us();
SDA = 0;
SCL = 0;
}
else
{
SDA = 0; // 否則傳送位0
SCL = 1;
delay5us();
SCL = 0;
}
temp = temp<<1; // 數據左移一位
}
}
/* 接收一字節子程序 */
void recbyte(uchar idata *ch)
{
uchar idata n=8; // 從SDA線上讀取一位數據字節,共8位
uchar idata temp = 0;
while(n--)
{
SDA = 1;
SCL = 1;
temp = temp<<1; // 左移一位
if(SDA == 1)
temp = temp|0x01; // 若接收到的位為1,則數據的最后一位置1
else
temp = temp&0xfe; // 否則數據的最后一位置0
SCL=0;
}
*ch = temp;
}
/* 發送n字節數據子程序 */
void sendnbyte(uchar idata *sla, uchar n)
{
uchar idata *p;
start(); // 發送啟動信號
sendbyte(sla); // 發送從器件地址字節
checkack(); // 檢查應答位
if(F0 == 1)
{
NACK = 1;
return; // 若非應答表明器件錯誤或已壞,置錯誤標志位NACK
}
p = sbuf;
while(n--)
{
sendbyte(p);
checkack(); // 檢查應答位
if (nackFlag == 1)
{
NACK=1;
return; // 若非應答表明器件錯誤或已壞,置錯誤標志位NACK
}
p++;
}
stop(); // 全部發完則停止
}
/* 接收n字節數據子程序 */
void recnbyte(uchar idata *sla, uchar n)
{
uchar idata *p;
start(); // 發送啟動信號
sendbyte(sla); // 發送從器件地址字節
checkack(); // 檢查應答位
if(nackFlag == 1)
{
NACK = 1;
return;
}
p = rbuf; // 接收字節存放在rbuf中
while(n--)
{
recbyte (p);
ack(); // 收到一個字節后發送一個應答位
p++;
}
n_ack(); // 收到最后一個字節后發送一個非應答位
stop();
}
/* 主函數,模擬實現I2C總線的數據收發 */
void main(void)
{
uchar i,numbyte;
numbyte = 8;
/* 需發送的8字節數據 */
for (i=0;i<numbyte;i++)
sbuf[i] = i+0x11;
SLAdd = 0x58; // 從器件地址
sendnbyte(&SLAdd,numbyte); // 向從器件發送存放在sbuf中的8字節數據
for (i=0;i<10000;i++)
delay5us();
recnbyte(&SLAdd,numbyte); // 由從器件接收8字節數據,存放在rbuf中
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -