I2C总线浅谈之(四)--STM8的IIC驱动文件示例
2017-09-20 11:00
357 查看
本示例提供STM8S103F核心板的IIC驱动文件源代码,亲测没有任何问题,博主使用来驱动AT24C256和电子罗盘MMC5883MA,IIC通信速率100kHz,可以调整时序延时时间。
直接贴源码:
IIC.h
IIC.c
如有任何疑问或调式发现bug,欢迎留言或私信博主。
直接贴源码:
IIC.h
#ifndef _IIC_H #define _IIC_H #include "iostm8s103F3.h" #include "type_def.h" #define IIC_SCL PC_ODR_ODR5 //设置SCL为GPIO--PC5 #define IIC_SDA PC_ODR_ODR6 //设置SDA为GPIO--PC6 #define READ_SDA PC_IDR_IDR6 //PC6引脚为输入寄存器 #define SET_SCL_OUT() {PC_DDR_DDR5=1; PC_CR1_C15 = 1; PC_CR2_C25 = 0;}//设置SCL引脚为推挽输出模式 #define SET_SDA_OUT() {PC_DDR_DDR6=1; PC_CR1_C16 = 1; PC_CR2_C26 = 0;}//设置SDA引脚为推挽输出模式 #define SET_SDA_IN() {PC_DDR_DDR6=0; PC_CR1_C16 = 0; PC_CR2_C26 = 0;}//设置SDA引脚为输入模式 //IIC所有操作函数 void IIC_Init(void); //初始化IIC的IO口 void IIC_Start(void); //发送IIC开始信号 void IIC_Stop(void); //发送IIC停止信号 void IIC_Send_Byte(unsigned char txd); //IIC发送一个字节 uint8_t IIC_Read_Byte(unsigned char ack); //IIC读取一个字节 uint8_t IIC_Wait_Ack(void); //IIC等待ACK信号 void IIC_Ack(void); //IIC发送ACK信号 void IIC_Nack(void); //IIC不发送ACK信号 #endif
IIC.c
#include "IIC.h" #include "delay.h" //初始化IIC void IIC_Init(void) { SET_SCL_OUT();//设置SCL引脚为推挽输出模式 SET_SDA_OUT();//设置SDA引脚为推挽输出模式 IIC_SCL = 1;//IIC总线SDA与SCL同时置高,总线为空闲状态 IIC_SDA = 1; } //产生IIC起始信号 void IIC_Start(void) { SET_SDA_OUT();//设置SDA引脚为推挽输出模式 IIC_SDA = 1;//开始前IIC总线SDA与SCL同时置高,总线为空闲状态,做通信准备 IIC_SCL = 1; delay_4us(); IIC_SDA = 0;//在SCL为高期间,SDA由高到低的跳变,启动信号发出 delay_4us(); IIC_SCL = 0;//SCL拉低钳住I2C总线,准备发送或接收数据 delay_2us(); } //产生IIC停止信号 void IIC_Stop(void) { SET_SDA_OUT();//设置SDA引脚为推挽输出模式 IIC_SCL = 0;//通信结束,SCL,SDA都为低。 IIC_SDA = 0; delay_4us(); IIC_SCL = 1;//将SCL置高,当SCL为高期间,SDA由低到高的跳变 IIC_SDA = 1;//发送I2C总线结束信号 delay_4us(); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 uint8_t IIC_Wait_Ack(void) { uint8_t ucErrTime = 0; IIC_SDA = 1; delay_us(); IIC_SCL = 1; delay_us(); SET_SDA_IN();//SDA设置为输入 delay_us(); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//时钟SCL输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL = 0; SET_SDA_OUT(); IIC_SDA = 0; delay_2us(); IIC_SCL = 1; delay_2us(); IIC_SCL = 0; } //不产生ACK应答 void IIC_Nack(void) { IIC_SCL = 0; SET_SDA_OUT(); IIC_SDA = 1; delay_2us(); IIC_SCL = 1; delay_2us(); IIC_SCL = 0; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(uint8_t txd) { uint8_t t; SET_SDA_OUT(); //设置SDA引脚为推挽输出模式 IIC_SCL = 0;//拉低时钟SCL开始数据传输 for(t=0;t<8;t++) { if((txd & 0x80) >> 7)//发送最高位 { IIC_SDA = 1; } else { IIC_SDA = 0; } txd <<= 1; //移位处理 delay_2us();//对特殊IC这三个延时都是必须的//6us,频率166khz IIC_SCL = 1; delay_2us(); IIC_SCL = 0; delay_2us(); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK uint8_t IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SET_SDA_IN();//SDA设置为输入 for(i = 0;i < 8;i++ ) { IIC_SCL = 0; delay_2us(); IIC_SCL = 1; receive<<=1; if(READ_SDA) { receive++; } delay_us(); } if (!ack) { IIC_Nack();//发送nACK } else { IIC_Ack(); //发送ACK } return receive; }
如有任何疑问或调式发现bug,欢迎留言或私信博主。
相关文章推荐
- I2C总线浅谈之(三)---以C语言实例分析IIC
- 浅谈 IIC I2C 总线协议
- Linux I2C子系统分析-I2C总线驱动
- 和菜鸟一起学linux总线驱动之初识i2c驱动数据传输流程
- i2c 驱动四:sysfs文件系统
- OMAP3630 Linux I2C总线驱动分析(2)
- I2C总线之(三)---以C语言理解IIC
- I2C总线驱动代码
- 用Proteus学习51单片机之I2C(IIC)总线
- Linux I2C驱动分析(一)----I2C架构和总线驱动
- Linux I2C核心、总线与设备驱动
- I2C总线之(三)---以C语言理解IIC
- Linux I2C核心、总线与设备驱动
- i2c 驱动二:devfs文件系统
- 浅谈 “驱动中的文件操作”
- Linux I2C 核心、总线、与设备驱动
- (2)LinuxI2C驱动--I2C总线
- 浅谈linux内核中的I2c驱动(2)
- Linux I2C子系统分析-I2C总线驱动
- 嵌入式系统通用驱动程序接口及其实现-I2C主机设备驱动(视频教学时的同步输入文件)