i2c.c
来自「zigbee 飞思卡尔 音频传输 基于ucos的所有源码」· C语言 代码 · 共 559 行
C
559 行
#include "common.h"
#include "i2c.h"
#define debuf
#undef debuf
void i2c_init(void)
{
char i;
//configure the i2c pin
//set I2C module
MCF_GPIO_PASPAR = 0x05;
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_IBB) !=0 )
{
printf("IBB is set\n");
MCF_I2C_I2CR = 0x0;
MCF_I2C_I2CR = 0xa0;
i = MCF_I2C_I2DR;//dummy read of I2DR
MCF_I2C_I2SR = 0x0;
MCF_I2C_I2CR = 0x0;
}
MCF_I2C_I2FDR = 0x1f; //set a prescaler to configue the i2C clock,
//configure the FDR carefully ,don't set clock too fast.when set FDR regsiter =0x20 ,the I2C can't work.
MCF_I2C_I2AR = 0x0;//set slave address as 0
MCF_I2C_I2CR = 1<<7;//enable i2c
MCF_I2C_I2CR |= (0<<6);//set no interrupt mode
printf("fdr=%d\n",MCF_I2C_I2FDR);
printf("cr=%d\n",MCF_I2C_I2CR);
}
void i2c_generation_start(unsigned char calling_address)
{
uint32 i =0 ;
while( (MCF_I2C_I2SR & MCF_I2C_I2SR_IBB) !=0 );//wait until the bus clear
MCF_I2C_I2CR |= MCF_I2C_I2CR_MTX;//set transmit mode
MCF_I2C_I2CR |= MCF_I2C_I2CR_MSTA;//set master mode,and generate a start condition
MCF_I2C_I2DR = calling_address;//D0=R/W;
while( (MCF_I2C_I2SR & MCF_I2C_I2SR_IBB) ==0 );//if IBB is clear ,wait until it is set;
for(i = 0; i<20000; i++);//delay
}
/*
*is_sub_calling_address:0 -- don't have sub_calling_address ,so don't care sub_calling_address and sub_address_count
*/
void i2c_event(char *buf,char calling_address,unsigned int *count,char *sub_calling_address,char *sub_address_count,char is_sub_calling_address)
{
char i = 0;
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
if( (MCF_I2C_I2CR & MCF_I2C_I2CR_MSTA) ==0)//slave mode
{
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_IAL) == 1 )//arbitration lost
{
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IAL;//clear IAL
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_IAAS) == 0)//IAAS=0
{
return;
}
}
else//not arbitration lost
{
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_IAAS) == 0)//IAAS=0
{
if( (MCF_I2C_I2CR & MCF_I2C_I2CR_MTX) == 0)// receive mode
{
*buf = MCF_I2C_I2DR;
buf++;
(*count)--;
return;
}
else// transmit mode
{
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) == 0) //receive ack
{
//i2c_transmit(*buf);//transmit one byte
MCF_I2C_I2DR = *buf;
(*count)--;
buf++;
return;
}
else//no ack
{
MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX;//set receive mode
i = MCF_I2C_I2DR;//dummy read I2DR
return;
}
}
}
}
//IAAS =1
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_SRW) == 0 )//slave receive mode
{
MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX;//set receive mode
i = MCF_I2C_I2DR;//dummy read I2DR
return;
}
else//slave transmit mode
{
MCF_I2C_I2CR |= MCF_I2C_I2CR_MTX;//set transmit mode
//i2c_transmit(*buf);//transmit one byte
MCF_I2C_I2DR = *buf;
(*count)--;
buf++;
return;
}
}
else//master mode
{
if( (MCF_I2C_I2CR & MCF_I2C_I2CR_MTX) ==0 )//receive mode
{
if(*count == 1)//is last byte
{
i2c_generate_stop_signal();
}
else//not last byte
{
if(*count == 2)//is 2nd last byte to be read
{
MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK;//set TXAK=1
}
}
*buf = MCF_I2C_I2DR;
buf++;
(*count)--;
return;
}
else//transmit mode
{
if (*count == 1)//last byte
{
(*count)--;
i2c_generate_stop_signal();
return;
}
else//not last byte
{
(*count)--;
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) == 0 )//receive ack
{
if( (calling_address & 0x01) == 0)//master write
{
//i2c_transmit(*buf);//transmit one byte
MCF_I2C_I2DR = *buf;
//(*count)--;
buf++;
return;
}
else//master receive
{
if(is_sub_calling_address == 0)//no sub calling address or have transmit sub calling address
{
MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX;//set receive mode
i = MCF_I2C_I2DR;//dummy read from i2DR
return;
}
else//have sub calling address
{
//i2c_transmit(*sub_calling_address);//transmit next sub address
MCF_I2C_I2DR = *sub_calling_address;
(*sub_address_count)--;
sub_calling_address++;
if(*sub_address_count == 0)
is_sub_calling_address = 0;
return;
}
}
}
else//no ack
{
i2c_generate_stop_signal();
return;
}
}
}
}
}
void i2c_generate_repeat_start(unsigned char calling_address)
{
uint32 i=0;
MCF_I2C_I2CR |= MCF_I2C_I2CR_MTX;//set transmit mode
MCF_I2C_I2CR |= MCF_I2C_I2CR_RSTA;//generate a repeat start
MCF_I2C_I2DR = calling_address;
//while();
for(i = 0; i<20000; i++);
return;
}
void i2c_generate_stop_signal(void)
{
uint32 i = 0;
MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MSTA;//generate a stop and select a slave mode
while( (MCF_I2C_I2SR & MCF_I2C_I2SR_IBB) !=0 );//if IBB is set ,wait until it is clear;
for(i = 0; i<20000; i++);//delay
}
void isl1208_write_byte(unsigned char register_byte,unsigned char data_byte)
{
//char data[2] = {0};
unsigned char data[2];
unsigned char calling_address = 0;
unsigned char data_count = 0;
data_count = 2; //dont include the address of device,but include the register address
data[0] = register_byte;
data[1] = data_byte;
//printf("%d\n",data[1]);
//start and write address
//void i2c_generation_start(char calling_address)
calling_address = isl1208_address & 0xFE;
printf("start write\n");
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
i2c_generation_start(calling_address);//address and write direction
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//write register address
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) == 0 )//receive ack
{
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//i2c_transmit(*buf);//transmit one byte
MCF_I2C_I2DR = data[0];
//for debug
//#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
//#endif
}
else//no ack
{
i2c_generate_stop_signal();
printf("isl1208 write byte data[0] wrong!\n");
}
//write data byte
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) == 0 )//receive ack
{
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//i2c_transmit(*buf);//transmit one byte
MCF_I2C_I2DR = data[1];
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
}
else//no ack
{
i2c_generate_stop_signal();
printf("isl1208 write byte data[1] wrong!\n");
}
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//generat stop
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
i2c_generate_stop_signal();
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
return;
}
char isl1208_read_byte(unsigned char register_byte)
{
uint32 i = 0;
unsigned char data = 0;
unsigned char calling_address = 0;
unsigned char data_count = 0;
data_count = 1; //don't include the address of device,but include the register address
data = register_byte;
//start and write address
//void i2c_generation_start(char calling_address)
calling_address = isl1208_address & 0xFE;
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK;//set TXAK=0
i2c_generation_start(calling_address);//address and write direction
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//write register address
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
if( (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) == 0 )//receive ack
{
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//i2c_transmit(*buf);//transmit one byte
MCF_I2C_I2DR = data;
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
}
else//no ack
{
i2c_generate_stop_signal();
printf("read byte wrong!\n");
}
//repeat start and device address
calling_address = isl1208_address|0x1;//set read direction
///for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
i2c_generate_repeat_start(calling_address);
//for debug
//printf("address=%d",calling_address);
MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK;//set TXAK=1
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX;//set receive mode
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
data = MCF_I2C_I2DR;//dummy read from i2DR
//printf("data=%d",data);
for(i = 0; i < 20000;i++);
//MCF_I2C_I2DR;
//read a data
///for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
data = MCF_I2C_I2DR;
//printf("\ndata1=%d\n",data);
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
//printf("data_f=%d",data);
//MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK;//set TXAK=1
while ( (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) == 0);//wait IFF
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;//clear IIF
i2c_generate_stop_signal();//generate stop
//for debug
#ifdef debuf
printf("%x\n",MCF_I2C_I2CR);
#endif
return data;
}
/*****************************************************************
*ucos-ii test task for FlexCAN
*******************************************************************/
OS_STK AppTaskI2cIsl1208Stk[256];
void AppTaskI2cIsl1208 (void * pdata)
{
unsigned char i = 0;
unsigned char data = 0;
i2c_init();//init the i2c
//void isl1208_write_byte(char register_byte,char data_byte)
//set WRTC,XTOSCB,ARST
isl1208_write_byte(0x07,0x90);//set sr register
printf("write sr= \n");
i = isl1208_read_byte(0x07);
printf("%d\n",i);
printf("start write INT register\n");
isl1208_write_byte(0x08,0x10);//set INT register ,forbiden the int and output frequency
printf("write int = ");
i = isl1208_read_byte(0x08);
printf("%d\n",i);
isl1208_write_byte(isl1208_rtc_sc,0x01);
isl1208_write_byte(isl1208_rtc_mn,0x02);
isl1208_write_byte(isl1208_rtc_hr,0x93);//set 24hours
isl1208_write_byte(isl1208_rtc_dt,0x04);
isl1208_write_byte(isl1208_rtc_mo,0x05);
isl1208_write_byte(isl1208_rtc_yr,0x06);
isl1208_write_byte(isl1208_rtc_dw,0x06);
while (1)
{
//char isl1208_read_byte(char register_byte)
data = isl1208_read_byte(6);
printf("星期");
printf("%d: ",data+1);
data = isl1208_read_byte(5);
printf("公元");
if(data<10)
printf("200%d: ",data);
else
printf("20%d:",data);
data = isl1208_read_byte(4);
printf("%d:",data);
printf("月");
data = isl1208_read_byte(3);
printf("%d",(data&0xF0)>>4);
printf("%d:",(data&0x0f));
printf("日:");
data = isl1208_read_byte(2);
if((data&0x80) ==0)//12 hours format
{
if((data&0x20)==0)
{
printf("%d",(data&0xF0)>>4);
printf("%d",(data&0x0f));
}
else
{
data = ((data&0x10)>>4)*10 + (data&0x0f) + 12;
printf("%d",data);
}
}
else//24 hours format
{
printf("%d",(data&0x30)>>4);
printf("%d",(data&0x0f));
}
printf("时(24小时制)");
data = isl1208_read_byte(1);
printf("%d",(data&0xF0)>>4);
printf("%d",(data&0x0f));
printf("分");
data = isl1208_read_byte(0);
printf("%d",(data&0xF0)>>4);
printf("%d",(data&0x0f));
printf("秒");
printf("\n");
OSTimeDly(60);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?