C語言——IIC協議概述+PCF8591

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;
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章