当前位置: 首页 > news >正文

STM32:IIC详解

文章目录

  • 1.IIC历史
  • 2.IIC优劣势
  • 3.IIC时序
    • 3.1 初始化IIC
    • 3.2 产生IIC起始信号
    • 3.3 产生IIC停止信号
    • 3.4 等待ACK
    • 3.5 产生ACK / 不产生ACK
    • 3.6 IIC发送一个字节
    • 3.7 IIC读取一个字节
    • 3.8 IIC发送多字节
    • 3.9 IIC读取多字节
  • 4 IIC问题
    • 4.1 STM32 HAL库的IIC设备地址没有左移

1.IIC历史

IIC (Inter-Integrated Circuit), 通常发音为: I-squared-C,是多主、多从、分组交换、单工的串行总线,通常用于处理器或微控制器与低速外围器件的短距离通信连接。这个通信协议是由(NXP半导体的前生)飞利浦公司发明,并在2006年开始,I2C协议的实施不要许可费,但仍要收取I2C从机分配地址的费用。

IIC 协议规范英文版(NXP):https://www.nxp.com/docs/en/user-guide/UM10204.pdf

2.IIC优劣势

优点:硬件资源节约,协议设计精巧,易用,多用与传输命令等,使用广泛易移植。
缺点:传输速率较慢。

3.IIC时序

3.1 初始化IIC

//初始化IIC
void PCA9557_Init(void)
{					     RCC->APB2ENR |= 1<<4;//先使能外设IO PORTC时钟 							 GPIOC->CRH &= 0XFFFF00FF;//PC10/11 推挽输出GPIOC->CRH |= 0X00003300;	   GPIOC->ODR |= 1<<10;     //PC10 输出高GPIOC->ODR |= 1<<11;     //PC11 输出高
}

3.2 产生IIC起始信号

//产生IIC起始信号
void PCA9557_Start(void)
{PCA9557_SDA_OUT(); //sda线输出PCA9557_SDA=1;PCA9557_SCL=1;delay_us(4);PCA9557_SDA=0;//START:when CLK is high,DATA change form high to lowdelay_us(4);PCA9557_SCL=0;//钳住I2C总线,准备发送或接收数据
}

3.3 产生IIC停止信号

//产生IIC停止信号
void PCA9557_Stop(void)
{PCA9557_SDA_OUT();//sda线输出PCA9557_SCL=0;PCA9557_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);PCA9557_SCL=1;PCA9557_SDA=1;//发送I2C总线结束信号delay_us(4);
}

3.4 等待ACK

//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
uint8_t PCA9557_Wait_Ack(void)
{uint8_t ucErrTime=0;PCA9557_SDA_IN(); //SDA设置为输入PCA9557_SDA=1;delay_us(1);PCA9557_SCL=1;delay_us(1);while(PCA9557_READ_SDA){ucErrTime++;if(ucErrTime>250){PCA9557_Stop();return 1;}}PCA9557_SCL=0;//时钟输出0return 0;
}

3.5 产生ACK / 不产生ACK

//产生ACK应答
void PCA9557_ACK(void)
{PCA9557_SCL=0;PCA9557_SDA_OUT();PCA9557_SDA=0;delay_us(2);PCA9557_SCL=1;delay_us(2);PCA9557_SCL=0;
}//不产生ACK应答
void PCA9557_NAck(void)
{PCA9557_SCL=0;PCA9557_SDA_OUT();PCA9557_SDA=1;delay_us(2);PCA9557_SCL=1;delay_us(2);PCA9557_SCL=0;
}

3.6 IIC发送一个字节

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
uint8_t PCA9557_Send_Byte(uint8_t txd)
{uint8_t t;PCA9557_SDA_OUT();PCA9557_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){if (txd&0x80) PCA9557_SDA = 1;else PCA9557_SDA = 0;txd<<=1;delay_us(2); //对TEA5767这三个延时都是必须的PCA9557_SCL=1;delay_us(2);PCA9557_SCL=0;delay_us(2);}t=PCA9557_Wait_Ack();  //这里固定只要写字节就需要等待应答return (t);
}

3.7 IIC读取一个字节

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
uint8_t PCA9557_Read_Byte(uint8_t ack)
{uint8_t i,receive=0;PCA9557_SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){PCA9557_SCL=0;delay_us(2);PCA9557_SCL=1;receive<<=1;if(PCA9557_READ_SDA)receive |= 1;delay_us(1);}if (!ack)PCA9557_NAck();//发送nACKelsePCA9557_ACK(); //发送ACKreturn receive;
}

3.8 IIC发送多字节

uint8_t PCA9557Write(uint8_t addr, uint8_t len, uint8_t *pData)
{uint8_t i;PCA9557_Start();if(PCA9557_Send_Byte(PCA9557_ADDR_WRITE)==1){PCA9557_Stop();return 0;}if(PCA9557_Send_Byte(addr)==1){PCA9557_Stop();return 0;}for(i = 0; i < len; i++){if(PCA9557_Send_Byte(pData[i])==1){PCA9557_Stop();return 0;}}PCA9557_Stop();return 1;
}

3.9 IIC读取多字节

uint8_t PCA9557Read(uint8_t addr,uint8_t len,uint8_t *pData)
{uint8_t i;PCA9557_Start();if(PCA9557_Send_Byte(PCA9557_ADDR_WRITE)==1){PCA9557_Stop();return 0;}if(PCA9557_Send_Byte(addr)==1){PCA9557_Stop();return 0;}PCA9557_Start();if(PCA9557_Send_Byte(PCA9557_ADDR_READ)==1){PCA9557_Stop();return 0;}for(i=0; i<len-1; i++){pData[i] = PCA9557_Read_Byte(1);}pData[len-1] = PCA9557_Read_Byte(0);PCA9557_Stop();return 1;
}

4 IIC问题

4.1 STM32 HAL库的IIC设备地址没有左移

#define I2C_7BIT_ADD_WRITE(__ADDRESS__)                    ((uint8_t)((__ADDRESS__) & (uint8_t)(~I2C_OAR1_ADD0)))
#define I2C_7BIT_ADD_READ(__ADDRESS__)                     ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))

底层中并没有把设备的地址左移,而是直接把最低位改为“0”或“1”,需要自己把器件地址的左移了一位。

	stat = HAL_I2C_Mem_Read(&hi2c1,(PCA9557_I2C_BUS_ADDR << 1),PCA9557_INPUT_REG,1,&io_statu,1,0xFF);if(stat != 0 ){LOG_INFO("io %d Read Error STAT %d\r\n",io,stat);}

http://www.mrgr.cn/news/65423.html

相关文章:

  • 探索数据结构:数组与链表
  • SVN 提交操作
  • Servlet和JSP入门详解
  • 【推动技术创新】CPU与FPGA/GPU/AI/DSP强强联合的主板定制方案
  • C++ --- 指针的使用(如何理解指针?指针的细节你又了解多少?)
  • 数据结构之顺序表(C语言)
  • 【C++类和对象篇】类和对象的六大默认成员函数——构造,析构,拷贝构造,赋值重载,普通对象取地址重载,const对象取地址重载
  • Aurora 64b/66bIP核学习
  • 开发者的黄金时代:原生鸿蒙应用市场的全生命周期服务
  • 2024版红娘金媒10.3婚恋相亲系统源码小程序(亲测)
  • transformers 框架使用详解,bert-base-chinese
  • 第4章 Linux必备命令
  • QT 如何使QLabel的文字垂直显示
  • 微服务系列一:基础拆分实践
  • 什么是pipeline?
  • favicon是什么文件?如何制作网站ico图标?
  • 《安全软件开发框架(SSDF) 1.1:降低软件漏洞风险的建议》解读(四)
  • Fish Agent:多语言 Voice-to-Voice 开源语音模型;Runway 推出摄像机运镜功能丨 RTE 开发者日报
  • NVR管理平台EasyNVR多个NVR同时管理:高效管理分散视频资源的全能解决方案
  • 2024年下半软考准考证打印通知及打印说明!
  • 星河计划——北京同仁堂科技发展集团第三终端学术交流研讨会成功举办
  • 一个git相关的cve:CVE-2024-32002
  • 使用 asyncio.run_coroutine_threadsafe 在 Python 中处理异步操作
  • 如何更改Android studio的项目存储路径
  • 北斗有源终端|智能5G单北斗终端|单兵|单北斗|手持机
  • 智算中心建设热潮涌动 AI服务器赋能加速