?? i2c.c
字號(hào):
#include <reg52.h> // 引用標(biāo)準(zhǔn)庫的頭文件
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA = P1^0; // 串行數(shù)據(jù)
sbit SCL = P1^1; // 串行時(shí)鐘
uchar idata SLAdd; // 從器件地址
uchar idata sbuf[8]; // 數(shù)據(jù)發(fā)送緩沖區(qū)
uchar idata rbuf[8]; // 數(shù)據(jù)接收緩沖區(qū)
bit bdata NACK; // 器件壞或錯(cuò)誤標(biāo)志位
bit bdata nackFlag; // 非應(yīng)答標(biāo)志位
//#endif
/*****************************************/
//#include "I2C.h"
/* 延時(shí)約5微秒,對(duì)于12M時(shí)鐘 */
//uchar idata *High,*Low;
//*High=0x00;
//*Low=0x00;
void delay5us()
{
uint i;
for (i=0;i<5;i++)
_nop_();
}
/* 起始條件子函數(shù) */
void start(void)
{
SDA = 1; // 啟動(dòng)I2C總線
SCL = 1;
delay5us();
SDA = 0;
delay5us();
SCL = 0;
}
/* 停止條件子函數(shù) */
void stop(void)
{
SDA = 0; // 停止I2C總線數(shù)據(jù)傳送
SCL = 1;
delay5us();
SDA = 1;
delay5us();
SCL = 0;
}
/* 發(fā)送應(yīng)答子函數(shù) */
void ack(void)
{
SDA = 0; // 發(fā)送應(yīng)答位
SCL = 1;
delay5us();
// SDA = 1;
SCL = 0;
}
/* 發(fā)送非應(yīng)答子函數(shù) */
void n_ack(void)
{
SDA = 1; // 發(fā)送非應(yīng)答位
SCL = 1;
delay5us();
SDA = 0;
SCL = 0;
}
/* 應(yīng)答位檢查子函數(shù) */
void checkack(void)
{
SDA = 1; // 應(yīng)答位檢查(將p1.0設(shè)置成輸入,必須先向端口寫1)
SCL = 1;
nackFlag = 0;
// while(SDA);
if(SDA == 1) // 若SDA=1表明非應(yīng)答,置位非應(yīng)答標(biāo)志F0
nackFlag = 1;
SCL = 0;
}
/* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)子函數(shù) */
void sendbyte(uchar idata *ch)
{
uchar idata n = 8;
uchar idata temp;
temp = *ch;
while(n--)
{
if((temp&0x80) == 0x80) // 若要發(fā)送的數(shù)據(jù)最高位為1則發(fā)送位1
{
SDA = 1; // 傳送位1
SCL = 1;
delay5us();
// SDA = 0;
SCL = 0;
}
else
{
SDA = 0; // 否則傳送位0
SCL = 1;
delay5us();
SCL = 0;
}
temp = temp<<1; // 數(shù)據(jù)左移一位
}
}
/* 接收一字節(jié)子程序 */
void recbyte(uchar idata *ch)
{
uchar idata n=8; // 從SDA線上讀取一位數(shù)據(jù)字節(jié),共8位
uchar idata temp = 0;
while(n--)
{
SDA = 1;
SCL = 1;
temp = temp<<1; // 左移一位
if(SDA == 1)
temp = temp|0x01; // 若接收到的位為1,則數(shù)據(jù)的最后一位置1
else
temp = temp&0xfe; // 否則數(shù)據(jù)的最后一位置0
SCL=0;
}
*ch = temp;
}
/* 發(fā)送n字節(jié)數(shù)據(jù)子程序 */
void sendnbyte(uchar idata *sla, uchar n)
{
uchar idata *p;
uchar idata *High,*Low;
*High=0x00;
*Low=0x00;
start(); // 發(fā)送啟動(dòng)信號(hào)
sendbyte(sla); // 發(fā)送從器件地址字節(jié)
checkack(); // 檢查應(yīng)答位
if(nackFlag == 1) //****
{
NACK = 1;
return; // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位NACK
}
sendbyte(High);
checkack();
if(nackFlag == 1) //************
{
NACK = 1;
return; // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位NACK
}
sendbyte(Low);
checkack();
if(nackFlag == 1) //********************
{
NACK = 1;
return; // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位NACK
}
p = sbuf;
while(n--)
{
sendbyte(p);
checkack(); // 檢查應(yīng)答位
if (nackFlag == 1)
{
NACK=1;
return; // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位NACK
}
p++;
}
stop(); // 全部發(fā)完則停止
}
/* 接收n字節(jié)數(shù)據(jù)子程序 */
void recnbyte(uchar idata *sla, uchar n)
{
uchar idata *p;
uchar idata *High1,*Low1;
*High1=0x00;
*Low1=0x00;
start(); // 發(fā)送啟動(dòng)信號(hào)
sendbyte(sla); // 發(fā)送從器件地址字節(jié)
checkack(); // 檢查應(yīng)答位
if(nackFlag == 1)
{
NACK = 1;
return;
}
sendbyte(High1);
checkack(); // 檢查應(yīng)答位
if(nackFlag == 1)
{
NACK = 1;
return;
}
sendbyte(Low1);
checkack(); // 檢查應(yīng)答位
if(nackFlag == 1)
{
NACK = 1;
return;
}
start();
*sla=*sla+1;
sendbyte(sla);
checkack(); // 檢查應(yīng)答位
if(nackFlag == 1)
{
NACK = 1;
return;
}
p = rbuf; // 接收字節(jié)存放在rbuf中
while(n--)
{
recbyte (p);
ack(); // 收到一個(gè)字節(jié)后發(fā)送一個(gè)應(yīng)答位
p++;
}
n_ack(); // 收到最后一個(gè)字節(jié)后發(fā)送一個(gè)非應(yīng)答位
stop();
}
/* 主函數(shù),模擬實(shí)現(xiàn)I2C總線的數(shù)據(jù)收發(fā) */
void main(void)
{
uchar i,numbyte;
uint j;
numbyte = 8;
/* 需發(fā)送的8字節(jié)數(shù)據(jù) */
for (i=0;i<numbyte;i++)
sbuf[i] = i+0x22;
SLAdd = 0xA0; // 從器件地址
sendnbyte(&SLAdd,numbyte); // 向從器件發(fā)送存放在sbuf中的8字節(jié)數(shù)據(jù)
for (j=0;j<10000;j++);
recnbyte(&SLAdd,numbyte); // 由從器件接收8字節(jié)數(shù)據(jù),存放在rbuf中
while(1);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -