参考代码
.C文件
模拟I2C驱动代码,只需要配置好模拟IO的读写即可。
/*********************************************************************************函数名称:void I2C_Init()**功能描述:初始化I2C1接口**入口参数:**输出:无*******************************************************************************/void IIC_Init(){GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_Out_OD_HiZ_Slow); //SDAGPIO_Init(GPIOC , GPIO_Pin_1 , GPIO_Mode_Out_OD_HiZ_Slow); //SCLIIC_SCL_HIGH();IIC_SDA_HIGH();}//产生IIC起始信号void IIC_Start(void){SDA_OUT(); //sda线输出/* IIC_SCL_LOW();delay_us(1); */IIC_SDA_HIGH();delay_us(1);IIC_SCL_HIGH();delay_us(4);//建立时间是I2C_SDA保持时间>4.7usIIC_SDA_LOW();//START:when CLK is high,DATA change form high to lowdelay_us(4);//保持时间是>4usIIC_SCL_LOW();//钳住I2C总线,准备发送或接收数据// delay_us(5);}//产生IIC停止信号void IIC_Stop(void){SDA_OUT();//sda线输出IIC_SCL_LOW();delay_us(1);IIC_SDA_LOW();//STOP:when CLK is high DATA change form low to high// IIC_SCL_HIGH();delay_us(4);//建立时间大于4.7usIIC_SCL_HIGH();delay_us(1);IIC_SDA_HIGH();//发送I2C总线结束信号delay_us(4);}//等待应答信号到来//返回值:1,接收应答失败// 0,接收应答成功u8 IIC_Wait_Ack(void){u8 ucErrTime=0;SDA_IN(); //SDA设置为输入IIC_SDA_HIGH();delay_us(1);IIC_SCL_HIGH();delay_us(1);while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();printf("device no ack\r\n");return 1;}}IIC_SCL_LOW();//时钟输出0// delay_us(5);return 0;}//产生ACK应答void IIC_Ack(void){IIC_SCL_LOW();SDA_OUT();IIC_SDA_LOW();delay_us(5);IIC_SCL_HIGH();delay_us(5);IIC_SCL_LOW();// delay_us(5);}//不产生ACK应答void IIC_NAck(void){IIC_SCL_LOW();SDA_OUT();IIC_SDA_HIGH();delay_us(5);IIC_SCL_HIGH();delay_us(5);IIC_SCL_LOW();// delay_us(5);}//IIC发送一个字节//返回从机有无应答//1,有应答//0,无应答void IIC_Send_Byte(u8 txd){u8 t;SDA_OUT();IIC_SCL_LOW(); //拉低时钟开始数据传输for (t = 0; t < 8; t++){// IIC_SDA = ((txd & 0x80) >> 7);if (txd & 0x80){IIC_SDA_HIGH();}else{IIC_SDA_LOW();}txd <<= 1;delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL_HIGH();delay_us(2);IIC_SCL_LOW();delay_us(2);}}//读1个字节,ack=1时,发送ACK,ack=0,发送nACKu8 IIC_Read_Byte(unsigned char ack){unsigned char i, receive = 0;// IIC_SCL_LOW();// IIC_SDA_LOW();SDA_IN(); //SDA设置为输入for (i = 0; i < 8; i++){// IIC_SDA_LOW();IIC_SCL_LOW();delay_us(3);IIC_SCL_HIGH();// delay_us(2);receive <<= 1;if (READ_SDA)receive|= 0x01;delay_us(3);}if (!ack)IIC_NAck(); //发送nACKelseIIC_Ack(); //发送ACKreturn receive;}
.H文件
仅包含部分代码,函数接口可视情况暴露出来即可。
#ifndef ___AT24C02_H___#define ___AT24C02_H___#include "stm8l15x.h"#define SLAVE_ADDRESS 0x90#define IRBUFSIZE 500//字节转换--1字节x2转2字节#define BUILD_UINT16(loByte, hiByte) \((u16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))//IO方向设置-------------因STM8单片机的I2C引脚为OD设计,同时故不需要设置CR1寄存器(详见数据手册及参考手册)#define SDA_IN() GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_In_FL_No_IT/* GPIO_Mode_Out_OD_HiZ_Slow */);#define SDA_OUT() GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_Out_OD_HiZ_Slow);// #define SDA_OUT() {GPIOC->DDR |= GPIO_Pin_0;GPIOC->CR1 &= (uint8_t)(~(GPIO_Pin_0)); \// GPIOC->CR2 &= (uint8_t)(~(GPIO_Pin_0));} /* Set OD Output *///IO操作函数{GPIOC->DDR &= (uint8_t)(~(GPIO_Pin_0));} /* Set Floating input No Interrupt */#define IIC_SCL_HIGH() GPIO_SetBits(GPIOC, GPIO_Pin_1);#define IIC_SCL_LOW() GPIO_ResetBits(GPIOC, GPIO_Pin_1);#define IIC_SDA_HIGH() GPIO_SetBits(GPIOC, GPIO_Pin_0);#define IIC_SDA_LOW() GPIO_ResetBits(GPIOC, GPIO_Pin_0);// STM8系列单片机可在输入或输出模式下读取IO状态------不需要改变IO的模式可读取#define READ_SDA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)
