首页 > 编程知识 正文

iic协议ad转换,iic总线

时间:2023-05-04 10:28:56 阅读:49754 作者:2709

总结中,IIC协议概述需要IIC、集成电路、IC总线和两条导线连接拓扑,是半双工的,适用于“字节型”设备。 拓扑如下:

SDA —串行数据线

SCL —串行时钟线通信速度标准模式下为100kb/s,高速模式下为400kb/s,与总线连接的IC的最大负载容量400pf需要上拉电阻

原因:

IIC的数据线SDA (在总线空闲时要求处于高电平)处于导通泄漏状态,不能输出高电平,仅输出低电平,起到保护作用。 如果某个设备被下拉且不连接上拉电阻就被短路到电源-,则对于不明确的负载,IC不能确保很大的输出功率,如果连接上拉电阻,负载所需的功率就由电源提供。 保护IC上拉电阻参照以下报道选择IIC的上拉电阻开始信号、结束信号

SCL为高电平时,SDA从高跳至低时开始信号

在SCL为高电平时、SDA从低电平转变为高电平时开始有效信号数据

在传输有效数据时,SDA仅在SCL低时变化,在SCL高时保持不变,否则为开始结束信号响应、非响应

每当发生1字节数据时,主机都必须等待从机向主机返回响应或非响应信号,以确定是否接收到数据。 在SCL的第九个脉冲之前将SDA设置为输入,检测SDA,低为响应信号,高为非响应信号。

以下是用IO模拟的ii c# include ' myiic.h ' uint 16 _ tslaveaddr; //设备地址uint8_t SlaveAddrLen=1; //设备地址字节数uint16_t SubAddr; //片上地址uint8_t SubAddrLen=2; //片上地址字节数uint8_ tiicreadbuf [ IIC _ size ]={0}; //IIC到IICLen个数据缓存uint8_ tiicwritebuf [ IIC _ size ]={0}; 写入IICLen个数据缓存uint16_t IICLen; //IIC操作长度//IO方向上voidsda_in(void ) gpio _ inittypedefgpio _ init structure; gpio _ init structure.gpio _ pin=IIC _ sda _ pin; gpio _ init structure.gpio _ mode=gpio _ mode _ in; gpio _ init structure.gpio _ otype=gpio _ otype _ od; gpio _ init structure.gpio _ speed=gpio _ speed _ 50m Hz; gpio _ init structure.gpio _ pupd=gpio _ pupd _ no pull; gpio_init(IIC_gpio,GPIO_InitStructure ); }voidsda_out(void ) gpio _ inittypedefgpio _ init structure; gpio _ init structure.gpio _ pin=IIC _ sda _ pin; gpio _ init structure.gpio _ mode=gpio _ mode _ out; gpio _ init structure.gpio _ otype=gpio _ otype _ od; gpio _ init structure.gpio _ speed=gpio _ speed _ 50m Hz; gpio _ init structure.gpio _ pupd=gpio _ pupd _ no pull; gpio_init(IIC_gpio,GPIO_InitStructure ); //IIC//pa9-- IIC _ sc LPA 10-- IIC _ sdavoidiic _ init (void ) ) gpio _ inittypedefgpio _ init structure; RCC _ ahbperiphclockcmd (RCC _ ahbperiph _ gpioa,ENABLE );/* configure pa9 and pa10 inoutputpushpullmode */gpio _ init structure.gpio _ pin=gpio _ pin _9| gpio _ pin _ 10; gpio _ init structure.gpio _ mode=gpio _ mode _ out; gpio _ init structure.gpio _ otype=gpio _ otype _ od; gpio _ init structure.gpio _ speed=gpio _ speed _ 50m Hz; gpio _ init structure.gpio _ pupd=gpio _ pupd _ no pull; gpio_init(IIC_gpio,GPIO_InitStructure ); IIC_SCL_H; IIC_SDA_H; }voidIIC_close(void ) gpio _ inittypedefgpio _ init structure; RCC _ ahbperiphclockcmd (RCC _ ahbperiph _ gpioa,ENABLE );/* configure p a9 and p a10 inoutputpushpullmode */gpio _ init structure.g

PIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(IIC_GPIO, &GPIO_InitStructure);IIC_SCL_H;IIC_SDA_H;}//产生IIC起始信号uint8_t IIC_Start(void){SDA_OUT(); //sda线输出IIC_SDA_H; IIC_SCL_H;delay_us(5);if(!READ_SDA) return 1; //SDA线为低电平则总线忙,退出 IIC_SDA_L;//START:when CLK is high,DATA change form high to low delay_us(5);if(READ_SDA) return 1; //SDA线为高电平则总线出错,退出IIC_SCL_L;//钳住I2C总线,准备发送或接收数据 return 0;} //产生IIC停止信号void IIC_Stop(void){SDA_OUT();//sda线输出IIC_SCL_L;IIC_SDA_L;//STOP:when CLK is high DATA change form low to high delay_us(5);IIC_SCL_H; delay_us(5);IIC_SDA_H;//发送I2C总线结束信号delay_us(5); }//等待应答信号到来//返回值:1,接收应答失败// 0,接收应答成功uint8_t IIC_Wait_Ack(void){uint8_t ucErrTime=0;SDA_IN(); //SDA设置为输入 IIC_SDA_H;delay_us(1); IIC_SCL_H;delay_us(1); while(READ_SDA){ucErrTime++;delay_us(1);if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL_L;//时钟输出0 return 0; } //产生ACK应答void IIC_Ack(void){IIC_SCL_L;SDA_OUT();delay_us(3);IIC_SDA_L;delay_us(3);IIC_SCL_H;delay_us(3);IIC_SCL_L;delay_us(3);}//产生NACK应答 void IIC_NAck(void){IIC_SCL_L;SDA_OUT();delay_us(3);IIC_SDA_H;delay_us(3);IIC_SCL_H;delay_us(3);IIC_SCL_L;delay_us(3);}//IIC发送一个字节//返回从机有无应答//1,有应答//0,无应答 void IIC_Send_Byte(uint8_t txd){ uint8_t t; SDA_OUT(); IIC_SCL_L;//拉低时钟开始数据传输 for(t=0;t<8;t++) { //IIC_SDA=(txd&0x80)>>7; if(((txd&0x80)>>7)){IIC_SDA_H;} else {IIC_SDA_L;} txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL_H;delay_us(4); IIC_SCL_L;delay_us(2); } } //读1个字节,ack=0时,发送ACK,ack=1,发送nACK uint8_t IIC_Read_Byte(unsigned char ack){unsigned char i,receive=0;SDA_IN();//SDA设置为输入IIC_SCL_L; for(i=0;i<8;i++ ){ IIC_SCL_L; delay_us(4);IIC_SCL_H; receive<<=1; if(READ_SDA)receive++; delay_us(4); //delay_us(1); } if (!ack) IIC_Ack();//发送ACK else IIC_NAck(); //发送NACK return receive;}uint8_t IIC_WriteDate(uint8_t SlaveAddr,uint16_t SubAddr,uint8_t *pWriteData,uint16_t Len){ uint16_t i=0; IIC_Start(); if(SlaveAddrLen==2) { IIC_Send_Byte(((SlaveAddr&0xFF00)>>8)); if(IIC_Wait_Ack()==1) return 1; delay_us(30); } IIC_Send_Byte(SlaveAddr&0x00FE); if(IIC_Wait_Ack()==1) return 1; delay_us(30); if(SubAddrLen==2) { IIC_Send_Byte(((SubAddr&0xFF00)>>8)); if(IIC_Wait_Ack()==1) return 1; delay_us(30); } IIC_Send_Byte((SubAddr&0x00FF)); if(IIC_Wait_Ack()==1) return 1; delay_us(30); for(i=0;i<Len;i++) {IIC_Send_Byte((pWriteData[i]));if(IIC_Wait_Ack()==1) return 1; delay_us(30); } IIC_Stop(); return 0; }uint8_t IIC_ReadDate(uint8_t SlaveAddr,uint16_t SubAddr,uint8_t *pReadData,uint16_t Len){ uint8_t i=0; if(IIC_Start()==1) return 1; //Start if(SlaveAddrLen==2) { IIC_Send_Byte(((SlaveAddr&0xFF00)>>8)); if(IIC_Wait_Ack()==1) return 1; delay_us(30); //30us } IIC_Send_Byte(SlaveAddr&0x00FE); if(IIC_Wait_Ack()==1) return 1; delay_us(30); if(SubAddrLen==2) { IIC_Send_Byte(((SubAddr&0xFF00)>>8)); if(IIC_Wait_Ack()==1) return 1;delay_us(30); } IIC_Send_Byte((SubAddr&0x00FF)); if(IIC_Wait_Ack()==1) return 1;delay_us(30);IIC_Start();if(SlaveAddrLen==2){IIC_Send_Byte(((SlaveAddr&0xFF00)>>8));if(IIC_Wait_Ack()==1) return 1;delay_us(30); } IIC_Send_Byte(((SlaveAddr&0x00FE)|0x01));if(IIC_Wait_Ack()==1) return 1;delay_us(30);for(i=0;i<(Len-1);i++){ pReadData[i]=IIC_Read_Byte(0); delay_us(30);}pReadData[Len-1]=IIC_Read_Byte(1);delay_us(30);IIC_Stop(); return 0;}uint8_t IIC_StateCheck(uint8_t SlaveAddr){ if(IIC_Start()==1){IIC_Stop();return 1;}if(SlaveAddrLen==2){IIC_Send_Byte(((SlaveAddr&0xFF00)>>8));if(IIC_Wait_Ack()==1) {IIC_Stop(); return 1;}delay_us(30); } IIC_Send_Byte(SlaveAddr&0x00FE);if(IIC_Wait_Ack()==1) {IIC_Stop(); return 1;}delay_us(30); IIC_Stop(); return 0;} #ifndef __MYIIC_H#define __MYIIC_H#include "stm32f0xx.h"#include "delay.h"//PA9-->IIC_SCL PA10-->IIC_SDA #define IIC_GPIO GPIOA#define IIC_SCL_PIN GPIO_Pin_9#define IIC_SDA_PIN GPIO_Pin_10#define IIC_SIZE 128extern uint16_t SlaveAddr; //设备地址extern uint8_t SlaveAddrLen;//设备地址字节数extern uint16_t SubAddr; //片内地址extern uint8_t SubAddrLen; //片内地址字节数extern uint8_t IICReadBuf[IIC_SIZE]; //从IIC读到IICLen个数据缓存extern uint8_t IICWriteBuf[IIC_SIZE];//待写入IICLen个数据缓存extern uint16_t IICLen; //IIC操作长度//IO操作函数 IIC_SCL_H#define IIC_SCL_L GPIO_WriteBit(IIC_GPIO,IIC_SCL_PIN,(BitAction)0) //SCL#define IIC_SCL_H GPIO_WriteBit(IIC_GPIO,IIC_SCL_PIN,(BitAction)1)#define IIC_SDA_L GPIO_WriteBit(IIC_GPIO,IIC_SDA_PIN,(BitAction)0) //SDA#define IIC_SDA_H GPIO_WriteBit(IIC_GPIO,IIC_SDA_PIN,(BitAction)1)#define READ_SDA GPIO_ReadInputDataBit(IIC_GPIO, IIC_SDA_PIN) //输入SDA #define READ_SCL GPIO_ReadInputDataBit(IIC_GPIO, IIC_SCL_PIN)) //输入SCL//IIC所有操作函数void IIC_Init(void); //初始化IIC的IO口 uint8_t IIC_Start(void); //发送IIC开始信号void IIC_Stop(void); //发送IIC停止信号void IIC_Send_Byte(uint8_t 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信号uint8_t IIC_StateCheck(uint8_t SlaveAddr); uint8_t IIC_WriteDate(uint8_t SlaveAddr,uint16_t SubAddr,uint8_t *pWriteData,uint16_t Len);uint8_t IIC_ReadDate(uint8_t SlaveAddr,uint16_t SubAddr,uint8_t *pReadData,uint16_t Len);#endif

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。