IIC協議:
SCL必須由主機發送,在SCL=1(高電平)時,SDA下跳則"判罰"爲"起始信號",SDA上跳則"判罰"爲"停止信號P".
每個字節後應該由對方回送一個應答信號ACK做爲對方在線的標誌,非應答信號一般在所有字節的最後一個字節後。一般要由雙方協議簽定。
器件地址:即7位從機地址加1位方向(讀寫)控制。從機收到自己的地址才能發送應答信號,表示自己在線。
具體格式:D7 D6 D5 D4 D3 D2 D1 D0
1-器件類型由:D7-D4 共4位決定的。這是由半導公司生產時就已固定此類型的了,也就是說這4位已是固定的。
2-用戶自定義地址碼:D3-D1共3位。這是由用戶自己設置的,通常的作法如EEPROM這些器件是由外部IC的3個引腳所組合電平決定的(用常用的名字如A0,A1,A2)。這也就是尋址碼。所以同一IIC總線上同一型號的IC只能最多掛8片同種類芯片。
3-最低一位就是R/W位
.H文件
#ifndef _IIC_H
#define _IIC_H
//函數聲明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(bit ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
void IIC_write_date(unsigned char addr, unsigned char date);
unsigned char IIC_read_date(unsigned char addr);
void adc_init(unsigned char adcbit);
unsigned char read_adc(unsigned char addr);
#endif
.C文件
#include "STC15F2K60S2.h"
#include "intrins.h"
#include "iic.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define somenopmore {somenop;somenop;somenop;somenop;somenop;somenop; somenop; somenop;somenop;somenop;}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//總線引腳定義
sbit SDA = P2^1; /* 數據線 */
sbit SCL = P2^0; /* 時鐘線 */
//總線啓動條件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//總線停止條件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//應答位控制
void IIC_Ack(bit ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
//等待應答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通過I2C總線發送數據
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//從I2C總線上接收數據
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
void IIC_write_date(unsigned char addr, unsigned char date)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
somenopmore;
}
unsigned char IIC_read_date(unsigned char addr)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return temp;
}
void adc_init(unsigned char adcbit)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(adcbit);
IIC_WaitAck();
IIC_Stop();
somenopmore;
}
unsigned char read_adc(unsigned char addr)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Ack(1);
IIC_Stop();
return temp;
}