软件模拟I2C(基于Microchip 24LC16B的操作函数库)

发布者:星尘之泪最新更新时间:2019-11-29 来源: eefocus关键字:软件模拟I2C  Microchip  24LC16B  函数库 手机看文章 扫描二维码
随时随地手机看文章

本文是在STM8L15x系列的芯片上,使用软件模拟的I2C来实现对24LC16B进行操作的函数库。


头文件定义:


 #ifndef _24LC16B_H

#define _24LC16B_H


#include "Hal_I2CSoft.h"


#define MAXROM_24LC16B          (2048)


extern void Hal24LC16BInit(I2CSoftConfig_t* i2cCfg);

extern u8 Hal24LC16B_ReadByte(u16 addr);

extern void Hal24LC16B_WriteByte(u16 addr, u8 data);

extern void Hal24LC16B_ReadBuf(u16 addr, u8 *buf, u16 len);

extern void Hal24LC16B_WriteBuf(u16 addr, u8 *buf, u16 len);

extern void Hal24L68B_WritePage(u16 addr, u8 *buf);


 #endif


具体操作函数:


/**

  ******************************************************************************

  * @f文件        24LC16B.c

  * @作者         huangqi

  * @版本         V1.0.0

  * @日期         2014-12-20

  * @描述         Microchip 的24LC16B的操作函数库

  ******************************************************************************

  */



#include "Hal_I2CSoft.h"

#include "24LC16B.h"



I2CSoftConfig_t *i2cCfg;


/*****************************************************************************

 * @函数名      Hal24LC16BInit

 *

 * @功能   初始化24LC16B

 *

 * @参数   i2cCfg:  I2CSoft端口信息

 *

 * @返回值  无

 *****************************************************************************/

void Hal24LC16BInit(I2CSoftConfig_t* i2cPortConfig)

{

  i2cCfg = i2cPortConfig;

  I2CSoft_Init(i2cCfg);

}


/*****************************************************************************

 * @函数名      Hal24LC16B_ReadByte

 *

 * @功能   向24LC16B读一个字节

 *

 * @参数   addr:  地址

 *

 * @返回值  读出的字节

 *****************************************************************************/


u8 Hal24LC16B_ReadByte(u16 addr)

{

  u8 tmp = 0;

  do

  {

    I2CSoft_Start(i2cCfg);

    I2CSoft_SendByte(i2cCfg, 0xA0+((addr/256)<<1));//写命令

  }

  while(I2CSoft_WaitAck(i2cCfg));

  I2CSoft_SendByte(i2cCfg, addr%256);

  I2CSoft_WaitAck(i2cCfg);


  I2CSoft_Start(i2cCfg);

  I2CSoft_SendByte(i2cCfg, 0xA0+((addr/256)<<1)+1);//写命令

  I2CSoft_WaitAck(i2cCfg);

  tmp = I2CSoft_RecvByte(i2cCfg,0);

  I2CSoft_Stop(i2cCfg);

  return tmp;

}


/*****************************************************************************

 * @函数名      Hal24LC16B_WriteByte

 *

 * @功能   向24LC16B写入一个字节

 *

 * @参数   addr:  地址

 *         data:  需要写的数据

 *

 * @返回值  无

 *****************************************************************************/


void Hal24LC16B_WriteByte(u16 addr, u8 data)

{

  do

  {

    I2CSoft_Start(i2cCfg);

    I2CSoft_SendByte(i2cCfg, 0xA0+((addr/256)<<1));//写命令

  }

  while(I2CSoft_WaitAck(i2cCfg));

  I2CSoft_SendByte(i2cCfg, addr%256);

  I2CSoft_WaitAck(i2cCfg);

  I2CSoft_SendByte(i2cCfg, data);//写命令

  I2CSoft_WaitAck(i2cCfg);

  I2CSoft_Stop(i2cCfg);

  //delay_us(3000);//必须等待EEPROM写入完成

}


/*****************************************************************************

 * @函数名      Hal24LC16B_WriteByte

 *

 * @功能   向24LC16B写入一页(共16Byte)

 *

 * @参数   addr:  地址

 *         data:  需要写的数据

 *

 * @返回值  无

 *****************************************************************************/


void Hal24L68B_WritePage(u16 addr, u8 *buf)

{

  u8 cnt=16;

  if((addr+16)%256<16)

    return;

  do

  {

    I2CSoft_Start(i2cCfg);

    I2CSoft_SendByte(i2cCfg, 0xA0+((addr/256)<<1));//写命令

  }

  while(I2CSoft_WaitAck(i2cCfg));

  I2CSoft_SendByte(i2cCfg, addr%256);

  I2CSoft_WaitAck(i2cCfg);

  while(cnt--)

  {

    I2CSoft_SendByte(i2cCfg, *buf++);//写命令

    I2CSoft_WaitAck(i2cCfg);

  }

  I2CSoft_Stop(i2cCfg);

  //delay_us(3000);//必须等待EEPROM写入完成

}


/*****************************************************************************

 * @函数名      Hal24LC16B_ReadBuf

 *

 * @功能   向24LC16B读取数据

 *

 * @参数   addr:  地址

 *         buf:   读出的数据

 *         len:   需要读数据的长度

 *

 * @返回值  无

 *****************************************************************************/


void Hal24LC16B_ReadBuf(u16 addr, u8 *buf, u16 len)

{

  u16 i = 0;


  if((len>0)&&(addr+len)>=(MAXROM_24LC16B-1))

    return;


  do

  {

    I2CSoft_Start(i2cCfg);

    I2CSoft_SendByte(i2cCfg, 0xA0+((addr/256)<<1));//写命令

  }

  while(I2CSoft_WaitAck(i2cCfg));


  I2CSoft_SendByte(i2cCfg, addr%256);

  I2CSoft_WaitAck(i2cCfg);

  I2CSoft_Start(i2cCfg);

  I2CSoft_SendByte(i2cCfg, 0xA0+((addr/256)<<1)+1);//写命令

  I2CSoft_WaitAck(i2cCfg);


  for(i = 0; i  {

    *buf++ = I2CSoft_RecvByte(i2cCfg,1);

  }


  *buf = I2CSoft_RecvByte(i2cCfg,0);


  I2CSoft_Stop(i2cCfg);

}



/*****************************************************************************

 * @函数名      Hal24LC16B_WriteBuf

 *

 * @功能   向24LC16B写入数据

 *

 * @参数   addr:  地址

 *         buf:   需要写的数据

 *         len:   写入数据的长度

 *

 * @返回值  无

 *****************************************************************************/


void Hal24LC16B_WriteBuf(u16 addr, u8* buf, u16 len)

{

  u16 i;

  if((len>0)&&(addr+len)>=(MAXROM_24LC16B-1))

    return;

  for(i=0; i  {

    Hal24LC16B_WriteByte(addr++,*buf++);

  }

}


 


I2C软件模拟驱动:


头文件:


#ifndef _HAL_I2CSOFT_H

#define _HAL_I2CSOFT_H


#include "stm8l15x.h"


typedef struct I2CSoftConfig_t

{

  GPIO_TypeDef* SCL_Port;

  GPIO_Pin_TypeDef SCL_Pin;

  GPIO_TypeDef* SDA_Port;

  GPIO_Pin_TypeDef SDA_Pin;

}I2CSoftConfig_t;


//extern void delay_us(u16 time);

extern void I2CSoft_Init(I2CSoftConfig_t* i2cConfg);

extern void I2CSoft_Start(I2CSoftConfig_t *i2cPortConfig);

extern void I2CSoft_Stop(I2CSoftConfig_t *i2cPortConfig);

extern u8 I2CSoft_WaitAck(I2CSoftConfig_t *i2cPortConfig);

extern void I2CSoft_SendByte(I2CSoftConfig_t *i2cPortConfig, u8 sendByte);

extern u8 I2CSoft_RecvByte(I2CSoftConfig_t *i2cPortConfig, u8 ack);

#endif


 


I2C协议实现:


/**

  ******************************************************************************

  * @f文件        hal_Flash.c

  * @作者         huangqi

  * @版本         V1.0.0

  * @日期         2014-12-23

  * @描述         模拟I2C的相关操作

  ******************************************************************************

  */


#include "Hal_I2CSoft.h"



void delay_us(u32 us)

{

    for( u32 x=us;x>0;x-- )

    {

      nop();nop();nop();nop();

    }

}



void I2CSoft_Init(I2CSoftConfig_t* i2cPortConfig)

{

  GPIO_Init(i2cPortConfig->SCL_Port,i2cPortConfig->SCL_Pin,GPIO_Mode_Out_PP_Low_Slow);//GPIO_Mode_Out_OD_Low_Slow);

  GPIO_Init(i2cPortConfig->SDA_Port,i2cPortConfig->SDA_Pin,GPIO_Mode_Out_OD_Low_Slow);//GPIO_Mode_Out_OD_Low_Slow);

}


void I2CSoft_Start(I2CSoftConfig_t* i2cPortConfig)

{

//  i2cPortConfig->SDA_Port->DDR |= i2cPortConfig->SDA_Pin;

  i2cPortConfig->SDA_Port->ODR |= i2cPortConfig->SDA_Pin;

  i2cPortConfig->SCL_Port->ODR |= i2cPortConfig->SCL_Pin;

  delay_us(2);

  i2cPortConfig->SDA_Port->ODR &= ~i2cPortConfig->SDA_Pin;

  delay_us(2);

  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

}



void I2CSoft_Stop(I2CSoftConfig_t* i2cPortConfig)

{


  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

//  i2cPortConfig->SDA_Port->DDR |= i2cPortConfig->SDA_Pin;

  i2cPortConfig->SDA_Port->ODR &= ~i2cPortConfig->SDA_Pin;

  delay_us(2);

  i2cPortConfig->SCL_Port->ODR |= i2cPortConfig->SCL_Pin;

  i2cPortConfig->SDA_Port->ODR |= i2cPortConfig->SDA_Pin;

  delay_us(2);

}



u8 I2CSoft_WaitAck(I2CSoftConfig_t* i2cPortConfig)

{

  u8 ucErrTime;


//  i2cPortConfig->SDA_Port->DDR &= ~i2cPortConfig->SDA_Pin;


  i2cPortConfig->SDA_Port->ODR |= i2cPortConfig->SDA_Pin;  //开漏输出将NMOS关闭,作为输入使用

  //delay_us(2);

  i2cPortConfig->SCL_Port->ODR |= i2cPortConfig->SCL_Pin;

  delay_us(2);

  while(i2cPortConfig->SDA_Port->IDR & i2cPortConfig->SDA_Pin)

  {

    ucErrTime++;

    if(ucErrTime>250)

    {

      I2CSoft_Stop(i2cPortConfig);

      return 1;

    }

  }

  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

//  delay_us(2);

  return 0;

}



static void I2CSoft_Ack(I2CSoftConfig_t* i2cPortConfig)

{

  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

//i2cPortConfig->SDA_Port->DDR |= i2cPortConfig->SDA_Pin;

  i2cPortConfig->SDA_Port->ODR &= ~i2cPortConfig->SDA_Pin;

  delay_us(2);

  i2cPortConfig->SCL_Port->ODR |= i2cPortConfig->SCL_Pin;

  delay_us(2);

  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

}



static void I2CSoft_NoAck(I2CSoftConfig_t* i2cPortConfig)

{

  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

//  i2cPortConfig->SDA_Port->DDR |= i2cPortConfig->SDA_Pin;

  i2cPortConfig->SDA_Port->ODR |= i2cPortConfig->SDA_Pin;

  delay_us(2);

  i2cPortConfig->SCL_Port->ODR |= i2cPortConfig->SCL_Pin;

  delay_us(2);

  i2cPortConfig->SCL_Port->ODR &= ~i2cPortConfig->SCL_Pin;

[1] [2]
关键字:软件模拟I2C  Microchip  24LC16B  函数库 引用地址:软件模拟I2C(基于Microchip 24LC16B的操作函数库)

上一篇:STM8L的LCD接口详解及驱动程序
下一篇:STM8工具之IAR--调试

推荐阅读最新更新时间:2024-11-06 14:49

历经半导体整并潮后:美半导体厂微芯上季净利狂增81%
《MarketWatch》报导,美厂微控制器、模拟半导体制造商微芯 (Microchip Technology)(MCHP-US) 周二 (9 日) 公布上季财报,数据显示,微芯半导体上季营收为 9.03 亿美元,不仅是超出市场预期的 8.90 亿美元,甚至与去年同期相比,年增率更是狂涨了 61.9%。 而根据 Non- GAAP 会计准则,微芯上季净利则为 2.77 亿美元,净利年增率成长幅度更是高达 81%,而换算每股盈余 (EPS) 则为 1.16 美元,亦是超出市场预期。 微芯半导体并购大事纪: 在过去几年的半导体景气寒冬中,微芯曾多次在市场大举并购,如 2014 年二月,微芯宣布以 3.94 亿美元,收购仿真及混合 IC
[半导体设计/制造]
NASA与Microchip合作开发宇航级高性能处理器
NASA 位于南加州的喷气推进实验室选择了Microchip公司来开发一种高性能航天计算 (HPSC) 处理器,该处理器将提供至少 100 倍于当前航天计算机的计算能力。这一关键能力将推进所有类型的未来太空任务,从行星探索到月球和火星表面任务。 “这种尖端的太空飞行处理器将对我们未来的太空任务甚至地球上的技术产生巨大影响,”华盛顿 NASA 总部太空技术任务理事会技术成熟度主管 Niki Werkheiser 说。“这项工作将扩大现有航天器的能力并富裕新能力,最终几乎可以被所有未来的太空任务使用,所有这些都受益于更强大的处理器。” Microchip 将在三年内构建、设计和交付 HPSC 处理器,目标是在未来的月球和行星探
[嵌入式]
Microchip推出M码时间服务器,获美国空军批准
新的SyncServer S650 M码保护依赖GPS信号的军事通信系统、雷达和网络 来自故意干扰和欺骗GPS信号的威胁,以及对关键基础设施的网络安全风险,表明需要强大和安全的时间和频率系统,以确保设备持续的可操作性和性能。 Microchip Technology的SyncServer S650 M码时间服务器已获得洛杉矶空军基地美国空军GPS理事会的批准,可用于支持军事通信系统、雷达和网络。 M码是一种加密的军事信号,在GPS频段内广播,国会授权国防部(DOD)在敌对环境中的任务关键型应用。Microchip的SyncServer S650 M代码时间和频率服务器为关键任务电子系统和仪器的同步提供了一个安全、准确、
[网络通信]
大脑植入微芯片,未来五年人类可实现“超智能”!
  植入人脑的高科技芯片很快就能提高人类智力!目前美国西北大学神经系统科学家致力于开发微创方法“黑客”人类大脑,并挖掘更大的人类潜力。   北京时间3月7日消息,据国外媒体报道,最新研究显示,植入人类大脑的高科技芯片很快就能增强人类智力。近年来,科学家一直致力于开发微创方式侵入大脑,挖掘更大的人类潜力。   美国西北大学神经系统科学家莫兰·瑟夫(Moran Cerf)博士表示,未来5年之内最新科学技术可实现这一目标。但他警告称,这种方法也可能酝酿新的社会不平等。   瑟夫说:“高科技人脑芯片可以实现网络互连,并且能够访问维基百科网站,当我思考某些特殊想法时,人脑芯片将为我们快速提供答案。”   目前神经系统科学家和商业教授正在
[家用电子]
大脑植入<font color='red'>微芯</font>片,未来五年人类可实现“超智能”!
新型激光技术实现微型化学传感器 开拓毫米级微芯片激光检测
多数激光器只发射一种颜色的激光,即激光器发射出所有光子的波长相同。然而,也有发射更复杂光的激光器。如果激光器由许多不同频率、均匀间隔的频率分量组成,就像梳齿一样,被称为“频率梳”。频率梳是检测各种化学物质的完美工具。 维也纳技术大学(TU Wien)开发的激光系统创造出了一系列均匀间隔的频率光谱(图片来源:TU Wien) 据麦姆斯咨询报道,维也纳技术大学(Vienna University of Technology,简称TU Wien)的这种特殊类型的激光器目前被用于微小空间(毫米级化学实验室)的化学分析。有了这项正在申请专利的新技术,频率梳可实现在单个芯片上以非常简单而可靠的方式创建。这项研究已经发表于《自然·光子学》(N
[安防电子]
Microchip 推出全新单芯片maXTouch触摸屏控制器系列产品
随着汽车触摸屏显示器尺寸增大,驾驶员希望在操作时获得像手机一样的触摸体验。然而,汽车屏幕需要通过严格的头部碰撞和振动测试,因此具有较厚的盖板玻璃,这可能影响触摸屏的性能。由于屏幕尺寸增大,触摸屏更可能受到其他频率的干扰,例如调幅收音机和车辆门禁系统。所有这些因素成了设计现代汽车电容式触摸系统时面临的主要问题。为了解决这些问题,Microchip Technology Inc.(美国微芯科技公司)推出全新的单芯片 maXTouch触摸屏控制器 系列产品。 采用近3000个触摸传感节点的MXT2912TD-A和支持超过2000个节点的MXT2113TD-A可以为客户带来梦寐以求的汽车触摸屏用户体验。这些新器件基于被全球制造商
[汽车电子]
<font color='red'>Microchip</font> 推出全新单芯片maXTouch触摸屏控制器系列产品
玖胜联合京东、百度DuerOS发布瑞芯微芯片小胜机器人
4月9日下午,玖胜联合京东百度DuerOS、中国网络教育电视台国学、图灵机器人等合作伙伴,成功举办“智创家未来玖胜2018人工智能与物联网新品发布会”。采用Rockchip瑞芯微RK PX3SE芯片的多款小胜机器人系列产品首次亮相。 全新发布的几款机器人芯片平台采用瑞芯微RK PX3SE处理器。整机由亿东科技研发。产品外观采用京东joy的经典IP;内容上中国教育网络电视台国学台的权威教学资源,可根据孩子的年龄阶段定制。在人机交互方面,小胜机器人能实现人机对话、点播、中英文翻译等互动;内置360°旋转高清摄像头,具有“远程陪伴”功能。 瑞芯微RK PX3SE定位于中高端AI智能音箱产品及智能语音交互产品。是基于C
[半导体设计/制造]
Microchip 推出超低接收电流的MRF89XA收发器
整合单片机、模拟器件和闪存专利解决方案的供应商——Microchip Technology Inc.(美国微芯科技公司)在芝加哥举行的嵌入式系统大会上宣布,推出3 mA超低接收电流的新型MRF89XA收发器,可延长868、915和950 MHz Sub-GHz无线网络中电池的使用寿命。868 MHz MRF89XAM8A和915 MHz MRF89XAM9A收发模块可消除设计射频(RF)电路的复杂性和获得机构认证的成本,加速设计周期。 Sub-GHz频段有时是设计人员用于各种电池供电的无线传感器网络和计量通信的首选。除了延长电池寿命的低功耗接收电流,Microchip的MRF89XA收发器和模块还集成了一个用于长距离
[网络通信]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved