/******************************************************************\
** 本程序只供学习使用,未经作者许可,不得用于其它任何用途 **
** **
** 硬件平台:STM32F407VGT6 **
** 开发环境:MDK-ARM( 5.14 ) **
** **
** 作 者:Brendon Tan **
** 完成日期:2016.11.30 **
** **
** 文件名称:iic.c **
** 文件说明:模拟 IIC 驱动 **
** **
** Copyright(C) 2016-2026,@Brendon_Tan **
\******************************************************************/
/*********************** V1.0 - 2016.11.27 ***********************/
//1.支持发送一个字节数据,接收一个字节数据
//2.支持往多个连续地址发送多个数据
//3.支持从多个连续地址读取多个数据
/*********************** V1.1 - 2016.11.30 ***********************/
//4.支持对设备任一可写寄存器中数据任一位进行修改
//5.支持对设备任一可写寄存器中数据多个位进行修改
/************************* END of Record *************************/
#include "iic.h"
/* IIC Init */
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(IIC_RCC , ENABLE); //使能 IIC 时钟
GPIO_InitStructure.GPIO_Pin = IIC_SCL_Pin | IIC_SDA_Pin; //IIC对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //管脚推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //管脚频率2MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //管脚上拉
GPIO_Init(IIC_Port , &GPIO_InitStructure); //初始化IIC GPIO
IIC_SCL_H;
IIC_SDA_H;
}
/* IIC Start */
void IIC_Start(void)
{
IIC_SDA_H;
IIC_SCL_H; IIC_delay(); // SDA -- __ __
IIC_SDA_L; IIC_delay(); // SCL -- -- __
IIC_SCL_L; IIC_delay();
}
/* IIC Stop */
void IIC_Stop(void)
{
IIC_SCL_L; IIC_delay();
IIC_SDA_L; IIC_delay(); // SDA __ __ --
IIC_SCL_H; IIC_delay(); // SCL __ -- --
IIC_SDA_H; IIC_delay();
}
/* IIC Send Ack */
void IIC_Ack(void)
{
IIC_SCL_L;
IIC_SDA_L; IIC_delay();
IIC_SCL_H; IIC_delay(); // SDA __ __ __ --
IIC_SCL_L; IIC_delay(); // SCL __ -- __ __
IIC_SDA_H;
}
/* IIC Send NAck */
void IIC_NAck(void)
{
IIC_SCL_L;
IIC_SDA_H; IIC_delay(); // SDA -- -- -- --
IIC_SCL_H; IIC_delay(); // SCL __ -- __ __
IIC_SCL_L; IIC_delay();
IIC_SDA_H;
}
/* IIC Wait a Ack */
/* return: */
/* ack=1 有应答 */
/* ack=0 无应答 */
unsigned char IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
IIC_SCL_L; IIC_delay();
IIC_SDA_H; IIC_delay();
IIC_SCL_H; IIC_delay();
while(IIC_SDA_READ())
{
ucErrTime++;
if(ucErrTime > 50)
{
IIC_Stop();
return 0;
}
}
IIC_SCL_L;
IIC_delay();
return 1;
}
/* IIC Send One Byte */
void IIC_Send_Byte(unsigned char data)
{
unsigned char i;
IIC_SCL_L; IIC_delay();
for(i = 0; i < 8; i++)
{
if(data & 0x80)
{
IIC_SDA_H;
IIC_delay();
}
else
{
IIC_SDA_L;
IIC_delay();
}
IIC_SCL_H; IIC_delay();
IIC_SCL_L; IIC_delay();
data <<= 1;
if(i == 7)
{
IIC_delay();
IIC_SDA_H;
}
}
}
/* IIC Read One Byte */
/* ack=1 发送Ack */
/* ack=0 发送NAck */
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i;
unsigned char data=0;
for(i = 0; i < 8; i++)
{
data <<= 1;
IIC_SCL_L; IIC_delay();
IIC_SCL_H; IIC_delay();
if(IIC_SDA_READ())
{
data |=0x01;
}
}
IIC_SCL_L;
if(ack == 0)
{
IIC_NAck();
}
else
{
IIC_Ack();
}
return data;
}
/* A simple IIC delay */
static void IIC_delay(void)
{
unsigned char i;
for(i = 0; i < 20; i++); //i>10,才能保证通讯时序
}
/* Write One Data to Register */
/* slaveaddr: 器件地址 */
/* reg_addr: 寄存器地址 */
/* reg_data: 发送的数据 */
unsigned char IIC_Write_Data(unsigned char slaveaddr, unsigned char reg_addr, unsigned char reg_data)
{
IIC_Start();
IIC_Send_Byte(slaveaddr << 1 | IIC_WR);
if(IIC_Wait_Ack() == 0)
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg_addr);
IIC_Wait_Ack();
IIC_Send_Byte(reg_data);
IIC_Wait_Ack();
IIC_Stop();
return 0;
}
/* Write n Data to Register */
/* slaveaddr: 器件地址 */
/* reg_addr: 寄存器地址 */
/* num: 数据数量 */
/* reg_data: 发送的数据 */
unsigned char IIC_Write_nData(unsigned char slaveaddr, unsigned char reg_addr, unsigned int num, unsigned char *buf)
{
IIC_Start();
IIC_Send_Byte(slaveaddr << 1 | IIC_WR);
if(IIC_Wait_Ack() == 0)
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg_addr);
IIC_Wait_Ack();
while(num--)
{
IIC_Send_Byte(*buf);
IIC_Wait_Ack();
buf++;
}
IIC_Stop();
return 0;
}
/* Read One Data from Register */
/* slaveaddr: 器件地址 */
/* reg_addr: 寄存器地址 */
/* *reg_data: 接收的数据地址 */
unsigned char IIC_Read_Data(unsigned char slaveaddr, unsigned char reg_addr, unsigned char *reg_data)
{
IIC_Start();
IIC_Send_Byte(slaveaddr << 1 | IIC_WR);
if( IIC_Wait_Ack() == 0 )
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg_addr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(slaveaddr << 1 | IIC_RD);
IIC_Wait_Ack();
*reg_data = IIC_Read_Byte(0);
IIC_Stop();
return 0;
}
/* Read n Data from Register */
/* slaveaddr: 器件地址 */
/* reg_addr: 寄存器地址 */
/* num: 数据数量 */
/* *buf: 接收的数据地址 */
unsigned char IIC_Read_nData(unsigned char slaveaddr, unsigned char reg_addr, unsigned int num, unsigned char *buf)
{
// unsigned int i=0;
IIC_Start();
IIC_Send_Byte(slaveaddr << 1 | IIC_WR);
if( IIC_Wait_Ack() == 0 )
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg_addr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(slaveaddr << 1 | IIC_RD);
IIC_Wait_Ack();
while(num)
{
if(num == 1)
{
*buf = IIC_Read_Byte(0);
}
else
{
*buf = IIC_Read_Byte(1);
}
buf ++;
num --;
}
// for(i = 0; i < (num -1); i++)
// {
// *buf = IIC_Read_Byte(1);
// buf++;
// }
// *buf = IIC_Read_Byte(0);
IIC_Stop();
return 0;
}
/* Write One Bit Data to REG Data */
/* slaveaddr: 器件地址 */
/* reg_addr: 寄存器地址 */
/* bit_num: 位的序号(第几位) */
/* bit_data: 位的数据(位的状态) */
void IIC_Write_Bit(unsigned char slaveaddr, unsigned char reg_addr, unsigned int bit_num, unsigned char bit_data)
{
unsigned char b;
IIC_Read_Data(slaveaddr, reg_addr, &b);
b=(bit_data != 0) ? (b | (1 << bit_num)) : (b & ~(1 << bit_num));
IIC_Write_Data(slaveaddr, reg_addr, b);
}
/* Write len Bit Data to REG Data */
/* slaveaddr: 器件地址 */
/* reg_addr: 寄存器地址 */
/* bit_start: 开始位的序号(第几位)*/
/* len: 修改位的个数 */
/* bit_data: 位的数据(位的状态) */
void IIC_Write_nBit(unsigned char slaveaddr, unsigned char reg_addr ,unsigned char bit_start,unsigned int len, unsigned char bit_data)
{
unsigned char b,temp;
IIC_Read_Data(slaveaddr, reg_addr, &b);
temp= (0xFF << (bit_start + 1)) | 0xFF >> ((8 - bit_start) + len -1);
bit_data <<= (8 - len);
bit_data >>= (7 - bit_start);
b &=temp;
b |=bit_data;
IIC_Write_Data(slaveaddr, reg_addr, b);
}
/************************ END of the File *************************/
STM32 模拟 IIC 读取 MPU6050 程序实现.rar
需积分: 49 19 浏览量
2020-07-14
13:16:50
上传
评论 3
收藏 7KB RAR 举报
Brendon_Tan
- 粉丝: 8923
- 资源: 4
最新资源
- 机器学习和数据挖掘课程设计-米其林餐厅数据挖掘管理系统源码+使用文档说明.zip
- html html html展示我与ai的对化
- 数据结构课程设计-全国交通出行咨询模拟系统C语言实现源码.zip
- cef-binary-109.0.1+gcd5e37a+chromium-109.0.5414.8-windows32
- 基于C语言的全国交通咨询系统模拟源码.zip
- 正点原子HAL库 STM32F4 DMA(学习自用附源码)
- 炫酷代码雨,超级炫酷哦!!!
- 基于物联网MQTT协议的智能停车场管理系统
- POETIZE个人博客系统源码 - 最美博客
- 基于深度学习的行人检测系统源码+项目说明(YoloV3+Tensorflow).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈