📄 isr_i2c.c
字号:
#include <./Atmel/at89x52.h>
#include "source.h"
#define SDA_SET() (SDA=1)
#define SDA_CLR() (SDA=0)
//#define SDA_VAL() (PDDR &0x2)
#define SCL_SET() (SCL=1)
#define SCL_CLR() (SCL=0)
I2Cdesc I2c; //the device decriptor
extern void I2cFinish(I2Cdesc *I2C_pt);
unsigned int idata I2c_timer_cnt=0;
void Init_I2c_Timer(unsigned int us){//MCLK@18.432MHz
//(((MCLK/12))*(256-TH0))us
TH0=TIMER0H;//20us
TL0=TH0;
I2c_timer_cnt=us/20;
TR0=1; // let timer 0 run // TCON /
}
void Start_I2c_Timer(unsigned int us){
I2c_timer_cnt=us/20;
TL0=TH0;
TR0=1; // let timer 0 run // TCON /
}
void Stop_I2c_Timer(void){
TR0=0;
}
unsigned char SDA_VAL(void){
return SDA;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CWrite (I2Cdesc *I2C_pt, u_short loadAddress, u_char nbByte)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* : loadAddress 为I2C的输入的存储单元的地址
//* : nbByte 为要写入I2C的字节数
//* 输出变量 : 无
//* 功能 :把TxEnd中的数据的nbByte字节写到loadAddress地址
//*-----------------------------------------------------------------------------
void I2CWrite (I2Cdesc *I2C_pt, unsigned int loadAddress, unsigned int nbByte){
I2C_pt->state = NOK;
I2C_pt->operate=WRITE_BIT;
I2C_pt->Error=0;
//* initialize state
SCL_SET(); //* set SCL line
SDA_SET(); //* set SDA line
I2C_pt->I2CByte = I2C_pt->deviceAddress | WRITE_BIT ; //* get byte to transmit
I2C_pt->loadAddress = loadAddress; //* get address
I2C_pt->mode = HIGH_ADDRESS_WRITE; //* next mode
I2C_pt->nbI2CByte = nbByte; //* get number of byte to transmit
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* change interrupt handler to I2CTxSendStartSDA
I2C_pt->I2CTCHandler = I2CTxSendStartSDA;
//* Enable RC compare interrupt
Start_I2c_Timer(I2C_pt->Timer_Gap_us);//start Timer
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CRead (I2Cdesc *I2C_pt, u_short loadAddress, u_char nbByte)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* : loadAddress 为I2C的输入的存储单元的地址
//* : nbByte 为要写入I2C的字节数
//* 输出变量 : 无
//* 功能 :从loadAddress地址中读nbByted放到RxEnd中
//*-----------------------------------------------------------------------------
void I2CRead (I2Cdesc *I2C_pt, unsigned int loadAddress, unsigned int nbByte){
I2C_pt->state = NOK; //* initialize state
I2C_pt->operate=READ_BIT;
I2C_pt->Error=0;
SCL_SET(); //* set SCL line
SDA_SET(); //* set SDA line
I2C_pt->I2CByte = I2C_pt->deviceAddress | WRITE_BIT ; //* get byte to read
I2C_pt->loadAddress = loadAddress; //* get address
I2C_pt->mode = HIGH_ADDRESS_READ; //* next mode
I2C_pt->nbI2CByte = nbByte; //* get nb byte to transmit
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* change interrupt handler to I2CTxSendStartSDA
I2C_pt->I2CTCHandler = I2CTxSendStartSDA;
//* Enable RC compare interrupt
Start_I2c_Timer(I2C_pt->Timer_Gap_us);//start Timer
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CDeviceRead (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为在读字节操作时通知I2C设备,以下的操作为读操作
//*-----------------------------------------------------------------------------
void I2CDeviceRead (I2Cdesc *I2C_pt){
SDA_SET(); //* set SDA line
SCL_SET(); //* set SCL line
I2C_pt->I2CByte = I2C_pt->deviceAddress | READ_BIT; //* get byte to transmit
I2C_pt->mode = DATA_READ; //* next mode
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* change interrupt handler to I2CTxSendStartSDA
I2C_pt->I2CTCHandler = I2CTxSendStartSDA;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CDeviceRead (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为在写字节操作时通知I2C设备,以下的操作为写操作
//*-----------------------------------------------------------------------------
void I2CDeviceWrite (I2Cdesc *I2C_pt){
SDA_SET();; //* set SDA line
SCL_SET();; //* set SCL line
I2C_pt->I2CByte = I2C_pt->deviceAddress | WRITE_BIT; //* get byte to transmit
I2C_pt->mode = DATA; //* next mode
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* change interrupt handler to I2CTxSendStartSDA
I2C_pt->I2CTCHandler = I2CTxSendStartSDA;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxSendByte (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为把状态字节,数据,地址等字节写到I2C设备中
//*-----------------------------------------------------------------------------
void I2CTxSendByte (I2Cdesc *I2C_pt){
SDA_SET();; //* set SDA line
switch(I2C_pt->mode){ //* get byte to transmit
case DATA : //Writing data byte now...
I2C_pt->I2CByte = *(I2C_pt->TxEnd++);
I2C_pt->nbI2CByte--;
if(I2C_pt->nbI2CByte == 0)
I2C_pt->mode = STOP; //* next mode
break;
case HIGH_ADDRESS_WRITE : //Write high byte of address (Write operation)...
I2C_pt->I2CByte = (unsigned char)(I2C_pt->loadAddress >> 8);
I2C_pt->mode = LOW_ADDRESS_WRITE; //* next mode
break;
case LOW_ADDRESS_WRITE : //Write low byte of address (Write operation)...
I2C_pt->I2CByte = (unsigned char) I2C_pt->loadAddress;
I2C_pt->mode = DATA; //* next mode
break;
case HIGH_ADDRESS_READ : //Write high byte of address (Read operation)...
I2C_pt->I2CByte = (unsigned char) (I2C_pt->loadAddress >> 8);
I2C_pt->mode = LOW_ADDRESS_READ; //* next mode
break;
case LOW_ADDRESS_READ : //Write low byte of address (Read operation)...
I2C_pt->I2CByte = (unsigned char) I2C_pt->loadAddress;
I2C_pt->mode = DEVICE_READ; //* next mode
break;
}
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* change interrupt handler to I2CTxSendBit
I2C_pt->I2CTCHandler = I2CTxSendBit;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxSendBit (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :根据发送数据的BIT位来判断要发送什么数据在SDA线上
//*-----------------------------------------------------------------------------
void I2CTxSendBit (I2Cdesc *I2C_pt){
unsigned char bit_val;
SCL_CLR(); //* Clear SCL line
I2C_pt->countBit--; //* decrement countBit
if(I2C_pt->countBit >= 0){ //* if bit counter = 0 ...
bit_val = (I2C_pt->I2CByte >> I2C_pt->countBit) & 1; //* get bit to transfert
//* Send 0 or 1
if (bit_val){
SDA_SET(); //* Set SDA line
}
else{
SDA_CLR(); //* Clear SDA line
}
//* change interrupt handler to I2CTxSetSCL
I2C_pt->I2CTCHandler = I2CTxSetSCL;
}
else{ //All the bits has been sent...
//SDA_INPUT(); //* set SDA line as an input
//* change interrupt handler to I2CTxPrepareACK
I2C_pt->I2CTCHandler = I2CTxPrepareACK;
}
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxSendStartSDA (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为I2C的开始时序SDA的变化
//*-----------------------------------------------------------------------------
void I2CTxSendStartSDA (I2Cdesc *I2C_pt){
SDA_CLR(); //* clear SDA line
//* change interrupt handler to I2CTxSendStartSCL
I2C_pt->I2CTCHandler = I2CTxSendStartSCL;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxSendStartSDA (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为I2C的开始时序SCL的变化
//*-----------------------------------------------------------------------------
void I2CTxSendStartSCL (I2Cdesc *I2C_pt){
SCL_CLR(); //* clear SCL line
//* change interrupt handler to I2CTxSendBit
I2C_pt->I2CTCHandler = I2CTxSendBit;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxPrepareSTOP (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为I2C的发送准备停止
//*-----------------------------------------------------------------------------
void I2CTxPrepareSTOP (I2Cdesc *I2C_pt)
//* Begin
{
//* clear SDA line
SDA_CLR();
//* set SCL line
SCL_SET();
//* change interrupt handler to I2CTxSendStopSDA
I2C_pt->I2CTCHandler = I2CTxSendStopSDA;
//* End
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxSendStopSCL (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为I2C的停止时序SCL的变化
//*-----------------------------------------------------------------------------
void I2CTxSendStopSCL (I2Cdesc *I2C_pt){
SCL_SET();; //* set SCL line
//* change interrupt handler to I2CTxSendStopSDA
I2C_pt->I2CTCHandler = I2CTxSendStopSDA;
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxSendStopSDA (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为I2C的停止时序SDA的变化
//*-----------------------------------------------------------------------------
void I2CTxSendStopSDA (I2Cdesc *I2C_pt){
SDA_SET();; //Set SDA line high
I2C_pt->state = OK; //Return to "OK"(Idle) state
I2C_pt->I2CTCHandler = I2C_pt->I2cFinish; //change interrupt handler
}
//*-----------------------------------------------------------------------------
//* 函数名称 : I2CTxPrepareACK (I2Cdesc *I2C_pt)
//* Object : I2C
//* 输入参数 : <I2C_pt> = 为I2C的描述指针,其结构定义在source.h中
//* 输出变量 : 无
//* 功能 :为I2C的发送应答时序的前的准备
//*-----------------------------------------------------------------------------
void I2CTxPrepareACK (I2Cdesc *I2C_pt){
SCL_SET(); //* set SCL line
//* change interrupt handler to I2CTxWaitACK
I2C_pt->I2CTCHandler = I2CTxWaitACK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -