.h文件

#ifndef __BSP_IIC_H__
#define __BSP_IIC_H__#include "stm32f4xx.h"
//#include "i2c_soft.h"typedef enum
{ADDR_WIDE_8  = 0,      //地址为8位宽度ADDR_WIDE_16  = 1,     //地址为16位宽度
} IIC_Addr_Type;typedef struct IIC_Type
{//属性uint32_t         RCC_SCL_APB2Periph;uint32_t         RCC_SDA_APB2Periph;GPIO_TypeDef*    GPIOx_SCL;GPIO_TypeDef*    GPIOx_SDA;uint16_t         SCL_Pin_x;uint16_t         SDA_Pin_x;//操作uint8_t (*IIC_Init)(const struct IIC_Type*);                     //IIC_Inituint8_t (*IIC_Start)(const struct IIC_Type*);                    //IIC_Startuint8_t (*IIC_Stop)(const struct IIC_Type*);                     //IIC_Stopuint8_t (*IIC_Wait_Ack)(const struct IIC_Type*);              //IIC_Wait_ack,返回wait失败或是成功uint8_t (*IIC_Ack)(const struct IIC_Type*);                      //IIC_Ack,IIC发送ACK信号uint8_t (*IIC_NAck)(const struct IIC_Type*);                     //IIC_NAck,IIC发送NACK信号uint8_t (*IIC_Send_Byte)(const struct IIC_Type*,uint8_t);        //IIC_Send_Byte,入口参数为要发送的字节uint8_t (*IIC_Read_Byte)(const struct IIC_Type*);     //IIC_Send_Byteuint8_t (*delay_us)(uint32_t);                                   //us延时
}IIC_TypeDef;// #ifndef ADDR_WIDE_8
// #define ADDR_WIDE_8    0
// #endif
// #ifndef ADDR_WIDE_16
// #define ADDR_WIDE_16   1
// #endiftypedef struct EEPROM_Type
{IIC_TypeDef      IIC;//属性uint32_t         RCC_Lock_APB2Periph; //LOCK引脚时钟GPIO_TypeDef*    GPIOx_Lock;uint16_t         Lock_Pin_x;uint8_t          addr_wide;    //ADDR_WIDE_8 - 8地址宽度;ADDR_WIDE_16 -- 16地址宽度uint8_t          device_addr;  //设备地址uint16_t         page_size;   //页大小uint32_t         max_size;    //最大字节uint8_t          (*EEProm_Init)(const struct EEPROM_Type*); //初始化IIC  uint8_t          (*EEProm_Soft_Reset)(const struct EEPROM_Type*); //EEPROM软件复位uint8_t          (*EEProm_Unlock)(const struct EEPROM_Type*);     //EEPROM解锁uint8_t          (*EEProm_Lock)(const struct EEPROM_Type*);     //EEPROM上锁uint8_t          (*EEProm_NRead)(const struct EEPROM_Type*, uint32_t, uint8_t*, uint16_t); //EEPROM读取N个字节uint8_t          (*EEProm_NWrite)(const struct EEPROM_Type*, uint32_t, uint8_t*, uint16_t); //EEPROM写入N个字节}EEPROM_Type_t;void BL24CM1A_Init(void);uint8_t BL24CM1A_Write_Data(uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length);
uint8_t BL24CM1A_Read_Data(uint32_t readaddress, uint8_t* pBuffer, uint16_t length);#endif /* __BSP_IIC_*/

.c


#include "bsp_iic.h"
#include "sys_timer.h"
#include "global_includes.h"#ifndef true
#define true     1
#endif#ifndef false
#define false    0
#endif
#define IIC_DELAY_us    5
//设置SCL电平
static void IIC_SCL(const struct IIC_Type* IIC_Type_t,int n)
{if(n == 1){GPIO_SetBits(IIC_Type_t->GPIOx_SCL, IIC_Type_t->SCL_Pin_x);}else{GPIO_ResetBits(IIC_Type_t->GPIOx_SCL, IIC_Type_t->SCL_Pin_x);}
}//设置SDA电平
static void IIC_SDA(const struct IIC_Type* IIC_Type_t,int n)
{if(n == 1){GPIO_SetBits(IIC_Type_t->GPIOx_SDA, IIC_Type_t->SDA_Pin_x);}else{GPIO_ResetBits(IIC_Type_t->GPIOx_SDA, IIC_Type_t->SDA_Pin_x);}
}
//读取SDA电平
static uint8_t READ_SDA(const struct IIC_Type* IIC_Type_t)
{return GPIO_ReadInputDataBit(IIC_Type_t->GPIOx_SDA,IIC_Type_t->SDA_Pin_x);  //读取SDA电平
}//初始化
static uint8_t IIC_Init_t(const struct IIC_Type* IIC_Type_t)
{RCC_AHB1PeriphClockCmd(IIC_Type_t->RCC_SCL_APB2Periph, ENABLE);RCC_AHB1PeriphClockCmd(IIC_Type_t->RCC_SDA_APB2Periph, ENABLE);GPIO_InitTypeDef  GPIO_InitStructure;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Pin =  IIC_Type_t->SDA_Pin_x;GPIO_Init(IIC_Type_t->GPIOx_SDA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =  IIC_Type_t->SCL_Pin_x;GPIO_Init(IIC_Type_t->GPIOx_SCL, &GPIO_InitStructure);IIC_SCL(IIC_Type_t, 1);IIC_SDA(IIC_Type_t, 1);return true;}//起始信号
static uint8_t IIC_Start_t(const struct IIC_Type* IIC_Type_t)
{IIC_SDA(IIC_Type_t, 1);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);if(!READ_SDA(IIC_Type_t)){return false;  //SDA线为低电平则总线忙,退出}IIC_SDA(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);if(READ_SDA(IIC_Type_t)){return false;  //SDA线为高电平则总线出错,退出}IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);return true;
}//停止信号
static uint8_t IIC_Stop_t(const struct IIC_Type* IIC_Type_t)
{IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SDA(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SDA(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);
}static uint8_t IIC_Wait_Ack_t(const struct IIC_Type* IIC_Type_t)
{uint8_t i;IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SDA(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);for(i = 0; i < 30; i++){if(READ_SDA(IIC_Type_t)){IIC_Type_t->delay_us(IIC_DELAY_us);}else{break;}}IIC_SCL(IIC_Type_t, 0);if(i  >=  30){IIC_Type_t->IIC_Stop(IIC_Type_t);return false;}return true;
}/**************************************************************************
*功能   :IICack
*函数名 : I2C_Ack
*输入   :iic(iic序号)
*返回   :无
**************************************************************************/
static uint8_t IIC_Ack_t(const struct IIC_Type* IIC_Type_t)
{IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SDA(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);
}/**************************************************************************
*功能   :IICnoack
*函数名 : I2C_NoAck
*输入   :iic(iic序号)
*返回   :无
**************************************************************************/
static uint8_t IIC_NAck_t(const struct IIC_Type* IIC_Type_t)
{IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SDA(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);
}static uint8_t IIC_Send_Byte_t(const struct IIC_Type* IIC_Type_t, uint8_t SendByte)
{uint8_t i = 8;while(i--){IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);if(SendByte & 0x80){IIC_SDA(IIC_Type_t, 1);}else{IIC_SDA(IIC_Type_t, 0);}SendByte <<= 1;IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);}IIC_SCL(IIC_Type_t, 0);
}static uint8_t IIC_Read_Byte_t(const struct IIC_Type* IIC_Type_t)
{uint8_t i = 8;uint8_t ReceiveByte = 0;IIC_SDA(IIC_Type_t, 1);while(i--){ReceiveByte <<= 1;IIC_SCL(IIC_Type_t, 0);IIC_Type_t->delay_us(IIC_DELAY_us);IIC_SCL(IIC_Type_t, 1);IIC_Type_t->delay_us(IIC_DELAY_us);if(READ_SDA(IIC_Type_t)){ReceiveByte |= 0x01;}}IIC_SCL(IIC_Type_t, 0);return ReceiveByte;
}static uint8_t EEProm_Unlock_t(const struct EEPROM_Type* EEPROM_Type_t)
{GPIO_ResetBits(EEPROM_Type_t->GPIOx_Lock, EEPROM_Type_t->Lock_Pin_x);
}static uint8_t EEProm_Lock_t(const struct EEPROM_Type* EEPROM_Type_t)
{GPIO_SetBits(EEPROM_Type_t->GPIOx_Lock, EEPROM_Type_t->Lock_Pin_x);
}uint8_t EEProm_Init_t(const struct EEPROM_Type* EEPROM_Type_t)
{RCC_AHB1PeriphClockCmd(EEPROM_Type_t->RCC_Lock_APB2Periph, ENABLE);GPIO_InitTypeDef  GPIO_InitStructure;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Pin =  EEPROM_Type_t->Lock_Pin_x;GPIO_Init(EEPROM_Type_t->GPIOx_Lock, &GPIO_InitStructure);EEPROM_Type_t->IIC.IIC_Init(&EEPROM_Type_t->IIC);return true;
}uint8_t EEProm_Soft_Reset_t(const struct EEPROM_Type* EEPROM_Type_t)
{IIC_SDA(&EEPROM_Type_t->IIC, 1);IIC_SCL(&EEPROM_Type_t->IIC, 1);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SDA(&EEPROM_Type_t->IIC, 0);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SCL(&EEPROM_Type_t->IIC, 0);for(uint8_t i = 0; i < 9; i++){IIC_SCL(&EEPROM_Type_t->IIC, 1);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SDA(&EEPROM_Type_t->IIC, 1);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SCL(&EEPROM_Type_t->IIC, 0);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);}IIC_SDA(&EEPROM_Type_t->IIC, 1);IIC_SCL(&EEPROM_Type_t->IIC, 1);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SDA(&EEPROM_Type_t->IIC, 0);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SCL(&EEPROM_Type_t->IIC, 0);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SDA(&EEPROM_Type_t->IIC, 0);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SCL(&EEPROM_Type_t->IIC, 1);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);IIC_SDA(&EEPROM_Type_t->IIC, 1);EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
}uint8_t EEProm_Soft_Read(const struct EEPROM_Type* EEPROM_Type_t, uint32_t ReadAddress, uint8_t* pBuffer, uint16_t length)
{uint8_t block  = 0;uint8_t addr_h = 0;uint8_t addr_l = 0;EEPROM_Type_t->EEProm_Soft_Reset(EEPROM_Type_t);if(!EEPROM_Type_t->IIC.IIC_Start(&EEPROM_Type_t->IIC)){return false;}if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16){block = ((ReadAddress >> 16) << 1);}else{block = ((ReadAddress >> 8) << 1);}addr_h = (ReadAddress >> 8);addr_l = ReadAddress;EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, EEPROM_Type_t->device_addr & 0xfe | block); //设置高起始地址+器件地址if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC)){EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return false;}if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16){EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_h);   //设置低起始地址EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC);}EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_l);   //设置低起始地址if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC)){EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return false;}EEPROM_Type_t->EEProm_Soft_Reset(EEPROM_Type_t);EEPROM_Type_t->IIC.IIC_Start(&EEPROM_Type_t->IIC);EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, EEPROM_Type_t->device_addr | 0x01 | block); //设置高起始地址+器件地址if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC)){EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return false;}while(length){*pBuffer = EEPROM_Type_t->IIC.IIC_Read_Byte(&EEPROM_Type_t->IIC);if(length == 1){EEPROM_Type_t->IIC.IIC_NAck(&EEPROM_Type_t->IIC);}else{EEPROM_Type_t->IIC.IIC_Ack(&EEPROM_Type_t->IIC);}pBuffer++;length--;}EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return true;
}uint8_t EEProm_Soft_Write(const struct EEPROM_Type* EEPROM_Type_t, uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{uint16_t i;uint8_t block  = 0;uint8_t addr_h = 0;uint8_t addr_l = 0;EEPROM_Type_t->EEProm_Soft_Reset(EEPROM_Type_t);if(!EEPROM_Type_t->IIC.IIC_Start(&EEPROM_Type_t->IIC)){return false;}if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16){block = ((WriteAddress >> 16) << 1);}else{block = ((WriteAddress >> 8) << 1);}addr_h = (WriteAddress >> 8);addr_l = WriteAddress;EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, EEPROM_Type_t->device_addr & 0xfe | block); //设置高起始地址+器件地址if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC)){EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return false;}if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16){EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_h);   //设置低起始地址EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC);}EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_l);   //设置低起始地址if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC)){EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return false;}for(i = 0; i < length; i++){EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, *pBuffer);if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC)){EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);return false;}pBuffer++;}EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);//注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms)EEPROM_Type_t->IIC.delay_us(10000);return true;
}uint8_t EEProm_Soft_Write_Data(const struct EEPROM_Type* EEPROM_Type_t, uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{uint8_t ret = false;if(((WriteAddress + length) > EEPROM_Type_t->max_size || length == 0)){return false;}uint32_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;Addr  = WriteAddress % EEPROM_Type_t->page_size;      //写入地址是开始页的第几位count = EEPROM_Type_t->page_size - Addr;     //在开始页要写入的个数EEPROM_Type_t->EEProm_Unlock(EEPROM_Type_t);if(count >= length)                                                 // 该页剩余的空间可以容下需要写入的数据量{if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, length)  ==  false) //写一页的数据{goto ret_return;}ret = true;}else{NumOfPage = (length - count) / EEPROM_Type_t->page_size;NumOfSingle = (length - count) % EEPROM_Type_t->page_size;if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, count) ==  false){goto ret_return;}WriteAddress += count;pBuffer += count;while(NumOfPage--)                                                      // 写页{if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, EEPROM_Type_t->page_size)  ==  false){goto ret_return;}WriteAddress +=  EEPROM_Type_t->page_size;pBuffer += EEPROM_Type_t->page_size;}if(NumOfSingle != 0)                                                    // 剩下的不足一页{if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, NumOfSingle)  ==  false){goto ret_return;}}ret = true;}ret_return:EEPROM_Type_t->EEProm_Lock(EEPROM_Type_t);return ret;
}uint8_t EEProm_NWrite_t(const struct EEPROM_Type* EEPROM_Type_t, uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{uint8_t i;for(i = 0; i < 3; i++){if(EEProm_Soft_Write_Data(EEPROM_Type_t, WriteAddress, pBuffer, length) ==  true){return true;}}return false;
}/****************************************************************************************
*函数名称: IIC_Soft_Read_Data
*
*函数说明: 模拟iic读数据函数
****************************************************************************************/
uint8_t EEProm_NRead_t(const struct EEPROM_Type* EEPROM_Type_t, uint32_t readaddress, uint8_t* pBuffer, uint16_t length)
{uint8_t ret = false;if(((readaddress + length) > EEPROM_Type_t->max_size || length == 0)){return false;}EEPROM_Type_t->EEProm_Unlock(EEPROM_Type_t);ret   = EEProm_Soft_Read(EEPROM_Type_t, readaddress, pBuffer, length);EEPROM_Type_t->EEProm_Lock(EEPROM_Type_t);return ret;
}uint8_t delay_us_t(uint32_t us)
{sys_timer_usDelay(us);
}EEPROM_Type_t BL24CM1A =
{.IIC = {.RCC_SCL_APB2Periph = RCC_AHB1Periph_GPIOB,.RCC_SDA_APB2Periph = RCC_AHB1Periph_GPIOB,.GPIOx_SCL = GPIOB,.GPIOx_SDA = GPIOB,.SCL_Pin_x = GPIO_Pin_4,.SDA_Pin_x = GPIO_Pin_5,.IIC_Init = IIC_Init_t,.IIC_Start = IIC_Start_t,.IIC_Stop = IIC_Stop_t,.IIC_Wait_Ack = IIC_Wait_Ack_t,.IIC_Ack = IIC_Ack_t,.IIC_NAck = IIC_NAck_t,.IIC_Send_Byte = IIC_Send_Byte_t,.IIC_Read_Byte = IIC_Read_Byte_t,.delay_us = delay_us_t,},.RCC_Lock_APB2Periph = RCC_AHB1Periph_GPIOB,.GPIOx_Lock = GPIOB,.Lock_Pin_x = GPIO_Pin_3,.addr_wide = ADDR_WIDE_16,.device_addr = 0xA0,.page_size = 128,.max_size = 131072,.EEProm_Init = EEProm_Init_t,.EEProm_Soft_Reset = EEProm_Soft_Reset_t,.EEProm_Unlock = EEProm_Unlock_t,.EEProm_Lock = EEProm_Lock_t,.EEProm_NRead = EEProm_NRead_t,.EEProm_NWrite = EEProm_NWrite_t,
};void BL24CM1A_Init(void)
{BL24CM1A.EEProm_Init(&BL24CM1A);
}uint8_t BL24CM1A_Write_Data(uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{BL24CM1A.EEProm_NWrite(&BL24CM1A, WriteAddress, pBuffer, length);
}uint8_t BL24CM1A_Read_Data(uint32_t readaddress, uint8_t* pBuffer, uint16_t length)
{BL24CM1A.EEProm_NRead(&BL24CM1A, readaddress, pBuffer, length);
}

单片机驱动—IIC驱动相关推荐

  1. 总线驱动---IIC驱动

    总线驱动-IIC驱动 文章目录 总线驱动---IIC驱动 Linux I2C体系结构 IIC-core(协议层) IIC总线驱动 IIC设备驱动 I.MX6U 的 I2C 适配器驱动分析 I2C 设备 ...

  2. Linux设备驱动 IIC驱动

    Linux 设备驱动篇之I2c设备驱动 fulinux 一.I2C驱动体系 虽然I2C硬件体系结构和协议都很容易理解,但是Linux I2C驱动体系结构却有相当的复杂度,它主要由3部分组成,即I2C设 ...

  3. IIC驱动0.96寸OLED屏幕显示(51单片机)

    这篇文章得用到IIC驱动,大家如果不会IIC通信,可以看这篇文章,也是我写的,是有关IIC通信的,有什么不理解的可以在看一下:https://blog.csdn.net/m0_58832575/art ...

  4. STC15W408AS单片机IIC驱动0.96寸OLED显示

    STC15W408AS单片机IIC驱动0.96寸OLED显示 不同页的滚动效果() 全页的滚动效果 STC15W408AS最新系统板 注意图片上的0欧姆电阻贴错了位置,应该是与GND相连的,图片上是P ...

  5. 基于51单片机的OLED驱动方式(iic通讯方式)

    基于51单片机的OLED驱动方式(iic通讯方式) 前言: 本人从事硬件开发,自学软件,因为发现在学习过程中,有很多问题对于没有项目实战经验的新手来讲太难解决了,可以说基本上是无从下手.现将自己学习过 ...

  6. MSP430杂谈--AD7745硬件IIC驱动与模拟IIC驱动

    和上一篇AD7793类似,项目中也涉及到利用AD7745读取电容值,来测环境湿度.编写了基于MSP430的AD7745的硬件IIC驱动和模拟IIC驱动,分享给大家. AD7745硬件IIC驱动完整版下 ...

  7. Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析 (iic驱动框架,i2c驱动框架)...

    转载于 : http://blog.csdn.net/zqixiao_09/article/details/50917655 关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸 ...

  8. linux下IIC驱动开发分析

    1.  IIC规范 IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备.IIC总线产生于在80年代,最初为音频和 ...

  9. STM32 驱动 GY-302 光照传感器 BH1750 模块(软件IIC与硬件IIC驱动)

    1.特别说明 ​ 要是不想看原理和过程,直接下拉找代码吧,都是测试过的,很稳定,有硬件I2C驱动的,也有软件模拟I2C驱动的,基于STM32F103系列和STM32F4系列实现,基于标准库实现,条理清 ...

最新文章

  1. 交通信号灯检测与行人过马路策略
  2. 高级特性-多线程,GUI
  3. java明星养成游戏_#IT明星不是梦#Java14不得不知的5个新功能
  4. python中xlwt的局限,Python xlwt 生成Excel和设置特定单元格不可编辑
  5. 短视频APP开发:短视频特效SDK功能火爆来袭!
  6. 打印某个user在指定时间段内做过的personalization detail
  7. Python内置模块和第三方模块
  8. Springboot是什么?Springboot详解!入门介绍
  9. jsoup爬虫技术精通_精通业务的同时保持技术的3种方法
  10. Win-MASM64汇编语言-visual studio下环境搭建
  11. Linux系统下存在大量的TIME_WAIT状态的TCP连接的解决方法
  12. CentOS 6.x通过yum安装php7.1及相关环境
  13. cad查看_天正电气CAD教程之标注实例讲解
  14. MATLAB中Yalmip工具,yalmip工具箱使用问题
  15. JavaScript-ES6新特性详解
  16. 1538G. Gift Set
  17. 保弘实业|工资低的家庭要怎么进行投资理财
  18. CMD中的用户名和自己账户名不一致
  19. C++学习笔记(六)
  20. Time-Ordered Recent Event (TORE) Volumes for Event Cameras论文笔记

热门文章

  1. 使用Visual Studio+OpenCV进行的Susan算子边缘检测及数米粒图像处理实验
  2. 反编译 APKTool 逆向助手
  3. 如何应对不间断电源(UPS)设计挑战
  4. matlab 控制硬件,自动控制原理实验教程(硬件模拟与MATLAB仿真)
  5. 中国“新一线”城市排名公布
  6. 项目范围管理计划模板
  7. 程序猿如何练习用英语讲好一个笑话?
  8. 十分钟拥有你的私人博客!使用readthedocs和mkdocs完成你的文档托管。
  9. git有本地化环境吗Linux,msysgit之Git for Windows 安装与使用教程
  10. 二分图的最小顶点覆盖 和 最大独立集 和 最大团