I2C_24C64驱动程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*******************************××*****************************************************************************/
/* led controller for M051 series */
/************************************************************************************************************××*/
#include "I2C.H"
#include "M05X_header.h"
#define PCLK (48000000UL)
volatile uint8 I2C_buf_t;
volatile uint16 I2C_address ;
volatile uint8 I2C_dat_t ;
volatile uint8 I2C_SOP_NUM;
volatile uint8 I2C_end ;
volatile uint8 read_or_send ;
volatile uint8 *I2C_ptr ;
volatile uint8 Device_addr ;
void I2C0_IRQHandler(void)
{
uint32 status;
status = I2C->STATUS;
if (I2C->TOC.TIF)
{
I2C->TOC.TIF = 1; /* Clear TIF */
I2C_end = 2;
}
else
{
switch (status)
{
case 0x08: /* START has been transmitted */
I2C_buf_t ++;
if(I2C_buf_t == 1) {
I2C->DATA = Device_addr | I2C_write; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
break;
case 0x10: /*A repeated START has been transmitted. */
I2C->DATA = Device_addr | I2C_read ; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
break;
case 0x18: /*?????????? ACK ? */
case 0x28: /*?????????? ACK ? */
I2C_buf_t ++;
if(Device_addr == 0xa0)
{
if(I2C_buf_t == 2) {
I2C->DATA = I2C_address/256; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
else if(I2C_buf_t == 3) {
I2C->DATA = I2C_address%256; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
else {
if(read_or_send == 1) {
I2C->CON.STA = 1; /* I2C ????? */
I2C->CON.STO = 0; /* I2C */
}
else {
if(I2C_dat_t < I2C_SOP_NUM) {
I2C->DATA = *I2C_ptr ++; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
else {
I2C->DATA = *I2C_ptr ++; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 1; /* I2C */
I2C_end = 1;
}
I2C_dat_t ++;
}
}
}
else if(Device_addr == 0xa6)
{
if(I2C_buf_t == 2) {
I2C->DATA = I2C_address%256; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
else {
if(read_or_send == 1) {
I2C->CON.STA = 1; /* I2C ????? */
I2C->CON.STO = 0; /* I2C */
}
else {
if(I2C_dat_t < I2C_SOP_NUM) {
I2C->DATA = *I2C_ptr ++; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
else {
I2C->DATA = *I2C_ptr ++; /* ??? */
I2C->CO
N.STA = 0; /* I2C */
I2C->CON.STO = 1; /* I2C */
I2C_end = 1;
}
I2C_dat_t ++;
}
}
}
break;
case 0x40: /*SLA+R has been transmitted */
if(I2C_SOP_NUM > 1)
I2C->CON.AA = 1; /* ?????? */
else
I2C->CON.AA = 0; /* ?????? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
break;
case 0x50: /*receive a data and a ACK bit */
I2C_dat_t ++;
if(I2C_dat_t >= I2C_SOP_NUM) { /* I2C???????? */
*I2C_ptr ++ = I2C->DATA ;
I2C->CON.AA = 0; /* ?????? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
else {
*I2C_ptr ++ = I2C->DATA ;
I2C->CON.AA = 1; /* ?????? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
}
break;
case 0x58: /*receive a data and back a ACK bit */
*I2C_ptr = I2C->DATA ;
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 1; /* I2C */
I2C_end = 1;
break;
case 0x20: /* ???SLA+W,?????? */
case 0x30: /* ???I2DAT????,?????? */
case 0x38: /* ?SLA +R/W?????????? */
case 0x48: /* ???SLA+R,?????? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
break;
default:
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 0; /* I2C */
break;
}
}
I2C->CON.SI = 1; /* I2C */
}
void init_I2C(void) {
SYS -> P3_MFP.MFP4_T0_SDA = 0;
SYS -> P3_MFP.MFP5_T1_SCL = 0;
SYS -> P3_MFP.ALT4_T0_SDA = 1;
SYS -> P3_MFP.ALT5_T1_SCL = 1;
SYSCLK->APBCLK.I2C_EN = 1; /* I2C ???? */
SYS->IPRSTC2.I2C_RST = 1; /* I2C????? */
SYS->IPRSTC2.I2C_RST = 0; /* I2C ?? ???? */
I2C->CON.ENSI = 1; /* I2C ????? */
I2C->CLK = PCLK/(4*I2C_CLK) - 1; /* I2C ??? */
I2C->CON.EI = 1; /* I2C ????? */
NVIC->ISER[0] = (1 << ((uint32_t)(I2C0_IRQn) & 0x1F)); /* enable interrupt */
NVIC_SetPriority(I2C0_IRQn, 6) ;
I2C->TOC.DIV4 = 1; /* ?????????4 */
// I2C->TOC.ENTI = 1; /* ??????/?? */
}
void I2C_START(uint8 sum_dat) {
I2C_buf_t = 0;
I2C_dat_t = 0;
I2C_SOP_NUM = sum_dat;
I2C_end = 0;
I2C->CON.STA = 1; /* I2C ????? */
I2C->CON.STO = 0; /* I2C */
I2C->CON.SI = 1; /* I2C */
}
void i2c_Read(uint16 addr_dat,uint8 sum_dat,uint8 *ptr,uint8 WR_flag) {
uint32 i2c_timer = 0;
ptr ++;
i2c_start:I2C_ptr = ptr ;
I2C_address = addr_dat ;
read_or_send = WR_flag;
Device_addr = 0xa0;
I2C_START(sum_dat) ;
while(1) {
if(I2C_end == 1)
break;
i2c_timer ++;
if(i2c_timer == 2000) {
I2C->CON.ENSI = 0;
I2C->CON.ENSI = 1;
init_I2C();
goto i2c_start;
}
else if(i2c_timer >= 10000)
break;
}
}
void i2c_one_byte(uint16 addr_dat,uint8 sum_dat,uint8 *ptr,uint8 WR_flag) {
uint32 i2c_timer = 0;
i2c_b_start:I2C_ptr = ptr ;
I2C_address = addr_dat ;
read_or_send = WR_flag;
Device_addr = 0xa0;
I2C_START(sum_dat) ;
while(1) {
if(I2C_end == 1)
break;
i2c_timer ++;
if(i2c_timer == 2000) {
I2C->CON.ENSI = 0;
I2C->CON.ENSI = 1;
init_I2C();
goto i2c_b_start;
}
else if(i2c_timer >= 10000)
break;
}
}
uint8 ADXL345_i2c_Read(uint16 addr_dat,uint8 sum_dat,uint8 *ptr,uint8 WR_flag) {
uint32 i2c_timer = 0;
ptr ++;
i2c_start:I2C_ptr = ptr ;
I2C_address = addr_dat ;
read_or_send = WR_flag;
Device_addr = 0xa6;
I2C_START(sum_dat) ;
while(1) {
if(I2C_end == 1)
return 0;
i2c_timer ++;
if(i2c_timer == 2000) {
I2C->CON.ENSI = 0;
I2C->CON.ENSI = 1;
init_I2C();
goto i2c_start;
}
else if(i2c_timer >= 10000)
return 1;
}
}
uint8 ADXL345_i2c_one_byte(uint16 addr_dat,uint8 sum_dat,uint8 *ptr,uint8 WR_flag) {
uint32 i2c_timer = 0;
i2c_b_start:I2C_ptr = ptr ;
I2C_address = addr_dat ;
read_or_send = WR_flag;
Device_addr = 0xa6;
I2C_START(sum_dat) ;
while(1) {
if(I2C_end == 1)
return 0;
i2c_timer ++;
if(i2c_timer == 2000) {
I2C->CON.ENSI = 0;
I2C->CON.ENSI = 1;
init_I2C();
goto i2c_b_start;
}
else if(i2c_timer >= 10000)
return 1;
}
}
uint8 Read_Adxl345_ID(void) {
uint8 adxl_buf[2] ;
if(ADXL345_i2c_one_byte(0,1,adxl_buf,1) == 1)
{
return 1;
}
else
{
if(adxl_buf[0] == 0xE5)
return 0;
else
return 1;
}
}
void init_adxl345(void) {
uint8_t adxl_buf[2] ;
adxl_buf[0] = 0x0B;
ADXL345_i2c_one_byte(DATA_FORMAT,1,adxl_buf,0); //低点评中断输出,13位分辨率,右对齐,16G量程
adxl_buf[0] = 0x08;
ADXL345_i2c_one_byte(BW_RATE,1,adxl_buf,0); //数据输出速度为100HZ
adxl_buf[0] = 0x08;
ADXL345_i2c_one_byte(POWER_CTL,1,adxl_buf,0); //DATA READY中断开启
adxl_buf[0] = 0x01;
ADXL345_i2c_one_byte(THRESH_ACT,1,adxl_buf,0); //检测的活动的值为187.5mg时产生中断
adxl_buf[0] = 0x60;
ADXL345_i2c_one_byte(ACT_INACT_CTL,1,adxl_buf,0); //使能X,Y,Z三轴的Activity和Inactivity功能
adxl_buf[0] = 0x80;
ADXL345_i2c_one_byte(INT_ENABLE,1,adxl_buf,0);
adxl_buf[0] = 0x00;
ADXL345_i2c_one_byte(OFSX,1,adxl_buf,0);
adxl_buf[0] = 0x00;
ADXL345_i2c_one_byte(OFSY,1,adxl_buf,0);
adxl_buf[0] = 0x05;
ADXL345_i2c_one_byte(OFSZ,1,adxl_buf,0);
adxl_buf[0] = 0xff;
ADXL345_i2c_one_byte(INT_MAP,1,adxl_buf,0); //配置到中断引脚1上
}