/************************************************************************************
* Copyright (c), 2006-2007, C8051F网络
* All rights reserved.
*
* Http: www.c8051f.com
* Email: mite@vip.qq.com
*
* File name: iic.c
* Project : C8051F330ST
* Processor: C8051F330
* Compiler : Keil C51 Compiler
*
* author: glacier
* QQ: 252858144
* date: 2009.02.12
*
* Description: 本文件是IIC总线硬件驱动程序文件;
*
* Others: none;
*
* Function List:
* 1. void IICA_Read(unsigned char id, unsigned char addr, unsigned char *p, unsigned int len)
* 2. void IICA_Write(unsigned char id, unsigned char addr, unsigned char *p, unsigned int len)
*
*************************************************************************************/
/************************************************************************************/
// 引用外部头文件
#include "..\source\c8051f330.h"
#include "..\source\const.h"
#include "..\source\iic.h"
#include "..\source\delay.h"
/************************************************************************************/
/************************************************************************************
// 常量及全局变量定义
*************************************************************************************/
#define IIC_WRITE 0 // WRITE direction bit
#define IIC_READ 1 // READ direction bit
sbit SDA = P1^0;
sbit SCL = P1^1;
/************************************************************************************
//
// IIC总线硬件驱动程序
//
*************************************************************************************/
/***********************************************************************************
* Function: iic_start;
*
* Description: iic通信起始函数;
*
* Input: none;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void iic_start(void)
{
SDA = 1;
Delay_us(2);
SCL = 1;
Delay_us(2);
SDA = 0;
Delay_us(2);
}
/***********************************************************************************
* Function: iic_stop;
*
* Description: iic通信停止函数;
*
* Input: none;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void iic_stop(void)
{
SDA = 0;
Delay_us(2);
SCL = 1;
Delay_us(2);
SDA =1;
}
/***********************************************************************************
* Function: iic_ack;
*
* Description: 发送ACK信号函数;
*
* Input: none;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void iic_ack(void)
{
SCL = 0;
SDA = 0;
Delay_us(2);
SCL = 1;
Delay_us(2);
SCL = 0;
Delay_us(1);
SDA = 1;
}
/***********************************************************************************
* Function: read_ack;
*
* Description: 读取从器件ACK信号函数;
*
* Input: none;
*
* Output: none;
*
* Return: 返回TRUE,地址或数据字节已发送收到ACK,否则没收到;
*
* Note: none;
************************************************************************************/
bool read_ack(void)
{
bool flag;
SCL = 0;
Delay_us(2);
SDA = 1;
SCL = 1;
Delay_us(2);
flag = SDA;
SCL = 0;
return flag;
}
/***********************************************************************************
* Function: iic_nack;
*
* Description: 发送NACK信号函数;
*
* Input: none;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void iic_nack()
{
SDA = 1;
Delay_us(2);
SCL = 1;
Delay_us(2);
SCL = 0;
}
/***********************************************************************************
* Function: get_byte;
*
* Description: 读取字节数据函数;
*
* Input: none;
*
* Output: none;
*
* Return: 字节数据;
*
* Note: none;
************************************************************************************/
unsigned char get_byte(void) //输入一个字节
{
unsigned char dd;
int i;
dd=0;
SDA = 1;
for (i=0;i<8;i++)
{
SCL = 0;
Delay_us(3);
SCL = 1;
Delay_us(1);
dd<<=1;
if (SDA)
dd|=0x01;
}
SCL = 0;
return(dd);
}
/***********************************************************************************
* Function: out_byte;
*
* Description: 输出字节数据函数;
*
* Input: 字节数据;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void out_byte(unsigned char dd) //输出一个字节
{
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 0;
Delay_us(0);
SDA = (dd & 0x80)>>7;
Delay_us(2);
SCL = 1;
Delay_us(3);
dd <<= 1;
}
SCL = 0;
}
/***********************************************************************************
* Function: iic_write_addr;
*
* Description: 向IIC器件写入地址数据函数;
*
* Input: addr,器件地址;data_addr,数据地址;
*
* Output: none;
*
* Return: 写入成功;
*
* Note: none;
************************************************************************************/
bool iic_write_addr(unsigned char addr,unsigned char data_addr)
{
iic_start();
out_byte(addr);
read_ack();
out_byte(data_addr);
read_ack();
return TRUE;
}
/***********************************************************************************
* Function: IICA_Write;
*
* Description: IIC总线写数据函数;
*
* Input: id,IIC器件识别地址, addr,写数据的起始地址; *p, 写入数据存储的地址指针;len,要写入数据长度;
*
* Output: none;
*
* Return: none;
*
* Note: 只支持AT24C01/02/04/08/16或地址是8位的器件;
************************************************************************************/
void IICA_Write(unsigned char id, unsigned char addr, unsigned char *p, unsigned int len)
{
int i;
bit EA_SAVE = EA;
EA = 0;
iic_write_addr(id|IIC_WRITE,addr);
for (i=0;i<len;i++)
{
out_byte(*p++);
read_ack();
}
iic_stop();
Delay_us(10000);
EA = EA_SAVE;
}
/***********************************************************************************
* Function: IICA_Read;
*
* Description: IIC总线读数据函数;
*
* Input: id,IIC器件识别地址, addr,读数据的起始地址; *p, 读出数据存储的地址指针;len,要读出数据长度;
*
* Output: none;
*
* Return: none;
*
* Note: 只支持AT24C01/02/04/08/16或地址是8位的器件;
************************************************************************************/
void IICA_Read(unsigned char id, unsigned char addr, unsigned char *p, unsigned int len)
{
int i;
bit EA_SAVE = EA;
EA = 0;
iic_write_addr(id|IIC_WRITE,addr);
iic_start();
out_byte(id|IIC_READ);
read_ack();
for (i=0;i<len;i++)
{
*p++ = get_byte();
if (i!=(len-1))
iic_ack();
}
iic_nack();
iic_stop();
EA = EA_SAVE;
}
/********************