不多说了,直接上代码,注释都成这样了
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: void IIC_Init(void)
*¹¦¡¡¡¡ÄÜ: ³õʼ»¯I2C¶ÔÓ¦µÄ½Ó¿ÚÒý½Å¡£
*******************************************************************************/
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //ʹÄÜPB¶Ë¿ÚʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //¶Ë¿ÚÅäÖÃ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M
GPIO_Init(GPIOB, &GPIO_InitStructure); //¸ù¾ÝÉ趨²ÎÊý³õʼ»¯GPIO
}
int IIC_Start(void)
{
SDA_OUT(); //sdaÏßÊä³ö
IIC_SDA=1;
if(!READ_SDA)return 0;
IIC_SCL=1;
delay_us(1);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
if(READ_SDA)return 0;
delay_us(1);
IIC_SCL=0;//ǯסI2C×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý
return 1;
}
void IIC_Stop(void)
{
SDA_OUT();//sdaÏßÊä³ö
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(1);
IIC_SCL=1;
IIC_SDA=1;//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
delay_us(1);
}
int IIC_Wait_Ack(void)//µÈ´ýÓ¦´ð
{
u8 ucErrTime=0;
SDA_IN(); //SDAÉèÖÃΪÊäÈë
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>50)
{
IIC_Stop();
return 0;
}
delay_us(1);
}
IIC_SCL=0;//ʱÖÓÊä³ö0
return 1;
}
void IIC_Ack(void) //²úÉúÓ¦´ð
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(1);
IIC_SCL=1;
delay_us(1);
IIC_SCL=0;
}
void IIC_NAck(void)// ²úÉúNACKÓ¦´ð
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
IIC_SCL=0;
}
void IIC_Send_Byte(u8 txd)// IIC·¢ËÍÒ»¸ö×Ö½Ú
{
u8 t;
SDA_OUT();
IIC_SCL=0;//ÀµÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
IIC_SCL=0;
delay_us(1);
}
}
int i2cWrite(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *data)
{
int i;
if (!IIC_Start())
return 1;
IIC_Send_Byte(addr << 1 );
if (!IIC_Wait_Ack()) {
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);
IIC_Wait_Ack();
for (i = 0; i < len; i++) {
IIC_Send_Byte(data[i]);
if (!IIC_Wait_Ack()) {
IIC_Stop();
return 0;
}
}
IIC_Stop();
return 0;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data)
*¹¦¡¡¡¡ÄÜ:
*******************************************************************************/
int i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
{
if (!IIC_Start())
return 1;
IIC_Send_Byte(addr << 1);
if (!IIC_Wait_Ack()) {
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte((addr << 1)+1);
IIC_Wait_Ack();
while (len) {
if (len == 1)
*buf = IIC_Read_Byte(0);
else
*buf = IIC_Read_Byte(1);
buf++;
len--;
}
IIC_Stop();
return 0;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: u8 IIC_Read_Byte(unsigned char ack)
*¹¦¡¡¡¡ÄÜ: //¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK
*******************************************************************************/
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDAÉèÖÃΪÊäÈë
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(2);
}
if (ack)
IIC_Ack(); //·¢ËÍACK
else
IIC_NAck();//·¢ËÍnACK
return receive;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr)
*¹¦¡¡¡¡ÄÜ: ¶ÁÈ¡Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷µÄÒ»¸öÖµ
ÊäÈë I2C_Addr Ä¿±êÉ豸µØÖ·
addr ¼Ä´æÆ÷µØÖ·
·µ»Ø ¶Á³öÀ´µÄÖµ
*******************************************************************************/
unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr)
{
unsigned char res=0;
IIC_Start();
IIC_Send_Byte(I2C_Addr); //·¢ËÍдÃüÁî
res++;
IIC_Wait_Ack();
IIC_Send_Byte(addr); res++; //·¢Ë͵ØÖ·
IIC_Wait_Ack();
//IIC_Stop();//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ
IIC_Start();
IIC_Send_Byte(I2C_Addr+1); res++; //½øÈë½ÓÊÕģʽ
IIC_Wait_Ack();
res=IIC_Read_Byte(0);
IIC_Stop();//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ
return res;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data)
*¹¦¡¡¡¡ÄÜ: ¶ÁÈ¡Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷µÄ length¸öÖµ
ÊäÈë dev Ä¿±êÉ豸µØÖ·
reg ¼Ä´æÆ÷µØÖ·
length Òª¶ÁµÄ×Ö½ÚÊý
*data ¶Á³öµÄÊý¾Ý½«Òª´æ·ÅµÄÖ¸Õë
·µ»Ø ¶Á³öÀ´µÄ×Ö½ÚÊýÁ¿
*******************************************************************************/
u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data){
u8 count = 0;
IIC_Start();
IIC_Send_Byte(dev); //·¢ËÍдÃüÁî
IIC_Wait_Ack();
IIC_Send_Byte(reg); //·¢Ë͵ØÖ·
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(dev+1); //½øÈë½ÓÊÕģʽ
IIC_Wait_Ack();
for(count=0;count<length;count++){
if(count!=length-1)data[count]=IIC_Read_Byte(1); //´øACKµÄ¶ÁÊý¾Ý
else data[count]=IIC_Read_Byte(0); //×îºóÒ»¸ö×Ö½ÚNACK
}
IIC_Stop();//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ
return count;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data)
*¹¦¡¡¡¡ÄÜ: ½«¶à¸ö×Ö½ÚдÈëÖ¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷
ÊäÈë dev Ä¿±êÉ豸µØÖ·
reg ¼Ä´æÆ÷µØÖ·
length ҪдµÄ×Ö½ÚÊý
*data ½«ÒªÐ´µÄÊý¾ÝµÄÊ×µØÖ·
·µ»Ø ·µ»ØÊÇ·ñ³É¹¦
*******************************************************************************/
u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data){
u8 count = 0;
IIC_Start();
IIC_Send_Byte(dev); //·¢ËÍдÃüÁî
IIC_Wait_Ack();
IIC_Send_Byte(reg); //·¢Ë͵ØÖ·
IIC_Wait_Ack();
for(count=0;count<length;count++){
IIC_Send_Byte(data[count]);
IIC_Wait_Ack();
}
IIC_Stop();//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ
return 1; //status == 0;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: u8 IICreadByte(u8 dev, u8 reg, u8 *data)
*¹¦¡¡¡¡ÄÜ: ¶ÁÈ¡Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷µÄÒ»¸öÖµ
ÊäÈë dev Ä¿±êÉ豸µØÖ·
reg ¼Ä´æÆ÷µØÖ·
*data ¶Á³öµÄÊý¾Ý½«Òª´æ·ÅµÄµØÖ·
·µ»Ø 1
*******************************************************************************/
u8 IICreadByte(u8 dev, u8 reg, u8 *data){
*data=I2C_ReadOneByte(dev, reg);
return 1;
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data)
*¹¦¡¡¡¡ÄÜ: дÈëÖ¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷Ò»¸ö×Ö½Ú
ÊäÈë dev Ä¿±êÉ豸µØÖ·
reg ¼Ä´æÆ÷µØÖ·
data ½«ÒªÐ´ÈëµÄ×Ö½Ú
·µ»Ø 1
*******************************************************************************/
unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data){
return IICwriteBytes(dev, reg, 1, &data);
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)
*¹¦¡¡¡¡ÄÜ: ¶Á ÐÞ¸Ä Ð´ Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷Ò»¸ö×Ö½Ú ÖеĶà¸öλ
ÊäÈë dev Ä¿±êÉ豸µØÖ·
reg ¼Ä´æÆ÷µØÖ·
bitStart Ä¿±ê×Ö½ÚµÄÆðʼλ
length 볤¶È
data ´æ·Å¸Ä±äÄ¿±ê×Ö½ÚλµÄÖµ
·µ»Ø ³É¹¦ Ϊ1
ʧ°ÜΪ0
*******************************************************************************/
u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)
{
u8 b;
if (IICreadByte(dev, reg, &b) != 0) {
u8 mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);
data <<= (8 - length);
data >>= (7 - bitStart);
b &= mask;
b |= data;
return IICwriteByte(dev, reg, b);
} else {
return 0;
}
}
/**************************ʵÏÖº¯Êý********************************************
*º¯ÊýÔÐÍ: u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data)
*¹¦¡¡¡¡ÄÜ: ¶Á ÐÞ¸Ä Ð´ Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷Ò»¸ö×Ö½Ú ÖеÄ1¸öλ
ÊäÈë dev Ä¿±êÉ豸µØÖ·
reg ¼Ä´æÆ÷µØÖ·
bitNum ÒªÐÞ¸ÄÄ¿±ê×Ö½ÚµÄbitNumλ
data Ϊ0 ʱ£¬Ä¿±ê뽫±»Çå0 ·ñÔò½«±»ÖÃλ
·µ»Ø ³É¹¦ Ϊ1
ʧ°ÜΪ0
*******************************************************************************/
u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data){
u8 b;
IICreadByte(dev, reg, &b);
b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
return IICwriteByte(dev, reg, b);
}
//IO¿Ú²Ù×÷ºê¶¨Òå
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO¿ÚµØÖ·Ó³Éä
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //Êä³ö
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //ÊäÈë
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //Êä³ö
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //ÊäÈë
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //Êä³ö
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //ÊäÈë
//IO·½ÏòÉèÖÃ
#define SDA_IN() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=8<<4;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=3<<4;}
//IO²Ù×÷º¯Êý
#define IIC_SCL PBout(8) //SCL
#define IIC_SDA PBout(9) //SDA
#define READ_SDA PBin(9) //ÊäÈëSDA