stm8模拟IIC与硬件IIC区别
展开全部IIC就两条线,IIC有自己的一套协议。
随便举个协议的例子,比如一根高,另一根由高到低时算启动;一根高,另一根由低到高算结束。
也就是说IIC只认两根线的高低电平。
硬件方式就是你往一个寄存器写“1”,它就开启IIC。
而模拟IIC则要用IO口去拉高或拉低IO口。
...
求MCS
归一化模拟I2C总线软件包(C51)/****************************************************************************** I2C.H 标准80C51模拟I2C总线程序头文件******************************************************************************/#ifndef I2C_H#define I2C_H//定义I2C操作模式#define I2C_RECV 0 /* 接收模式 */#define I2C_SEND 1 /* 发送模式 */#define I2C_SrRECV 2 /* 带Sr接收 *///I2C总线初始化void I2C_Init();/******************************************************************************函数:void I2C_On()功能:启动I2C总线收发数据返回:0-正常,1-异常(无应答)说明:参数Mode是操作模式,决定I2C总线收发格式。
常见的收发格式有3种,具体如下: 0-接收模式,格式:S | SLA+R | Data... | P 1-发送模式,格式:S | SLA+W | Addr | Data... | P 2-带Sr接收,格式:S | SLA+W | Addr | Sr | SLA+R | Data... | P******************************************************************************/bit I2C_On( unsigned char Mode, //操作模式 unsigned char SLA, //从机地址 unsigned char Addr, //子地址 unsigned char *Buf, //数据缓冲区 unsigned char Size //数据长度);#endif //I2C_H/****************************************************************************** I2C.C 标准80C51模拟I2C总线程序(主模式,通用)******************************************************************************/#i nclude #i nclude "I2C.H"//模拟I2C总线的管脚定义sbit I2C_SCL = P1^6; //定义I2C总线时钟信号sbit I2C_SDA = P1^7; //定义I2C总线数据信号/******************************************************************************函数:I2C_Delay()功能:模拟I2C总线延时说明:请根据具体情况调整延时值******************************************************************************/void I2C_Delay(){ unsigned char t; t = 10; while ( --t != 0 ); //延时2*t个机器周期}/******************************************************************************函数:I2C_Init()功能:I2C总线初始化,使总线处于空闲状态说明:在main()函数的开始处,应当执行一次本函数******************************************************************************/void I2C_Init(){ I2C_SCL = 1; I2C_Delay(); I2C_SDA = 1; I2C_Delay();}/******************************************************************************函数:I2C_Start()功能:产生I2C总线的起始条件说明:SCL处于高电平期间,当SDA出现下降沿时启动I2C总线 本函数也用来产生重复起始条件******************************************************************************/void I2C_Start(){ I2C_SDA = 1; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); I2C_SDA = 0; I2C_Delay(); I2C_SCL = 0; I2C_Delay();}/******************************************************************************函数:I2C_Write()功能:向I2C总线写1个字节的数据参数:dat是要写到总线上的数据******************************************************************************/void I2C_Write(unsigned char dat){ unsigned char t = 8; do { I2C_SDA = (bit)(dat & 0x80); dat <<= 1; I2C_SCL = 1; I2C_Delay(); I2C_SCL = 0; I2C_Delay(); } while ( --t != 0 );}/******************************************************************************函数:I2C_Read()功能:从从机读取1个字节的数据返回:读取的1个字节数据******************************************************************************/unsigned char I2C_Read(){ unsigned char dat; unsigned char t = 8; I2C_SDA = 1; //在读取数据之前,要把SDA拉高,使之处于输入状态 do { I2C_SCL = 1; I2C_Delay(); dat <<= 1; if ( I2C_SDA ) dat++; I2C_SCL = 0; I2C_Delay(); } while ( --t != 0 ); return dat;}/******************************************************************************函数:I2C_GetAck()功能:读取从机应答位(应答或非应答),用于判断:从机是否成功接收主机数据返回:0-从机应答 1-从机非应答说明:从机在收到每一个字节后都要产生应答位,主机如果收到非应答则应当终止传输******************************************************************************/bit I2C_GetAck(){ bit Ack; I2C_SDA = 1; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); Ack = I2C_SDA; I2C_SCL = 0; I2C_Delay(); return Ack;}/******************************************************************************函数:I2C_PutAck()功能:主机产生应答位(应答或非应答),用于通知从机:主机是否成功接收从机数据参数:Ack = 0:主机应答 Ack = 1:主机非应答说明:主机在收到每一个字节后都要产生应答,在收到最后一个字节时,应当产生非应答******************************************************************************/void I2C_PutAck(bit Ack){ I2C_SDA = Ack; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); I2C_SCL = 0; I2C_Delay();}/******************************************************************************函数:I2C_Stop()功能:产生I2C总线的停止条件说明:SCL处于高电平期间,当SDA出现上升沿时停止I2C总线******************************************************************************/void I2C_Stop(){ I2C...
单片机iic程序不懂给分析下啊
展开全部 贴个程序给你看看,,,单片机没有I2C总线接口,只能靠软件模拟/*程序的I2C从器件地址为1010,片选地址为000*/#include #include #define uchar unsigned char#define uint unsigned intsbit SDA=P1^7;sbit SCL=P1^6;void Delay(uint us){ for(us;us>0;us--);}void start_iic() // 启动I2C总线{ SDA=1; // 发送起始条件数据信号,启动时, SCL=1; // 必需使数据线、时钟信号线处于高电平(空闲态) Delay(10); // 使用I2C总线必需考虑保持时间和建立时间,故延时 SDA=0; //产生下降沿,发送起始信号 Delay(10); SCL=0; }void stop_iic() { SDA=0; //为产生上跳沿做准备 SCL=1; //打开时钟线 Delay(10); SDA=1; //产生停止信号(上跳沿有效) Delay(10); SCL=0; //时钟线恢复无效态//}void ack_iic() { SDA=0; // 接受器件发送应答信号 SCL=1; Delay(10); SCL=0; SDA=1; //应答信号低电平有效,故需将其重新置高电平}void nack_iic() { SDA=1; //主器件发非应答信号,通知AT24C08不再发送数据 SCL=1; Delay(10); SCL=0; SDA=0; //非应答信号高电平有效,故需将其重新置低电平}Write_byte(uchar c) { uchar i; for(i=0;i<8;i++) { if(c&0x80)SDA=1; else SDA=0; SCL=1; Delay(10); SCL=0; //因为当时钟线有效是,数据线必须保持稳定的电平, c=c<<1; //要改变SDA电平,应先将SCL拉低 } SDA=1; //释放I2C总线,准备接受应答信号 SCL=1; Delay(10); if(SDA==1)F0=0; //没有接到应答位 else F0=1; SCL=0;}uchar Read_byte() { uchar i; uchar r=0; SDA=1; //置数据线为输入方式 for(i=0;i<8;i++) { r=r<<1; SCL=1; Delay(10); //保证一定的电平保持时间 if(SDA==1)r++; //从高位开始,一位一位的读 SCL=0; } return r;}main(){ uchar slave=0xa0; //I2C总线从器件地址(注意:硬件电路的接法要是片选地址为0,否则不能工作) uchar Rslave=slave+1; //主器件发送读控制字字节 uchar addre=0x20; // 指定的写数据地址 uchar wbuf=0x23; //将要写进addre的数据 uchar rbuf; //存放读出的数据的临时变量 start_iic(); //产生起始信号 Write_byte(slave); //发送从器件地址 if(F0==0)return 0; //检查应答位 Write_byte(addre); //发送目的地址 if(F0==0)return 0; Write_byte(wbuf); //发送8为数据 if(F0==0)return 0; stop_iic(); //停止信号 /*8位的数据发送完毕*/ Delay(1000); start_iic(); Write_byte(slave); if(F0==0)return 0; Write_byte(addre); if(F0==0)return 0; start_iic(); //再次产生起始信号,不能少 Write_byte(Rslave); //送读控制字 if(F0==0)return 0; rbuf=Read_byte(); //读出指定单元的内容 nack_iic(); //非应答信号 stop_iic(); /*8位的数据读取完毕*/ TMOD=0x20; //串口调试 TL1=0xfd; TH1=0xfd; SCON=0x40; PCON=0x00; TR1=1; while(1) { SBUF=rbuf; //放入缓冲 while(TI==0); TI=0; Delay(10000); }}
我设计了一个IIC从机模块(fpga),请问我想要测试其正确性,模拟主...
你遇到的这个问题,在FPGA开发中叫做写TESTBENCH,更详细点就是设计测试向量,这是FPGA开发中必不可少的环节。
至于你想要测试的这个I2C的模块,别无他法,只有自己写测试向量。
--怎么写? VHDL/VERILOG 两种语言都行,在testbench中加入你的测试向量. I2C协议怎么规定的,你的测试向量就怎么写。
比如什么时候SCL拉高,什么时候SDA接受ACQ信号等等。
。
--用什么测? 很多软件都可以仿真,推荐MODELSIM,好用并且现在应用面广,很多公司里就用这个。
好了,希望能帮到你。
也希望你看了以后采纳下我的答案,好歹我这么认真的打字~~PS:那个思路.rar是骗人的。
。
如何解决I2C器件死锁的问题?
展开全部 正常情况下,I2C总线协议能够保证总线正常的读写操作。
但是在某些异常情况下会导致I2C总线锁死。
例如主控制器突然复位、或者I2C总线上存在干扰、或者电源异常等都可能导致I2C总线锁死。
在I2C主设备进行读写操作的过程中,主设备在开始信号后控制SCL产生8个时钟脉冲。
然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平 如果这个时候主设备异常复位,SCL就会被释放为高电平。
此时,如果从设备没有复位,就会继续I2C的应答,将SDA拉为低电平,直到SCL变为低电平,才会结束应答信号。
而对于I2C主设备来说,复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。
这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进入一种死锁状态。
同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。
广州致远电子ARM核心板使用IIC设备时,遇到总线死锁是如何让总线死锁恢复呢,常用方法如下:(1) 尽量选用带复位输人的I2C从器件,从I2C总线死锁产生的原因可以发现I2C总线死锁的一个必要条件是主设备复位了而从设备没有复位。
如果从设备选用带复位输入的芯片,将主从设备的复位信号连接在一起,当外部产生复位事件时,主从设备同时复位,这样就不会发生I2C总线死锁现象了。
这种方法的缺点也是显而易见的,首先,大部分I2C从器件都没有复位输入,器件选型受到了很大的限制;其次,这种对于主设备集成看门狗引起的复位也没有效果。
(2) 将所有的从I2C设备的电源连接在一起,通过M0S管连接到主电源,而MOS管的导通关断由I2C主设备来实现一般来说,I2C主设备都是具有运算单元的处理器。
控制功能可以通过处理器的GPIO来实现。
每次主设备复位时,运行程序控制GPIO关断MOS,使从设备失去电源。
然后延时一段时间后再导通MOS管,给从设备上电,从而达到让从设备强制复位的效果。
这种方法能弥补第一种方法的不足,但是会增加电源设计的复杂性,影响Layout设计时电源的完整性; 同时还需要更改处理器的底层boot代码,影响底层软件的通用性和可移植性。
(3) 在I2C从设备设计看门狗的功能。
当I2C从设备检测到自身处于应答状态或者低电平输出超过指定时间时,看门狗动作,复位I2C从设备。
这种情况下不用增加额外的硬件设计,但是要求I2C从设备具有可编程功能,比较适合从设备是单片机或CPLD的情况。
(4) 在I2C主设备中增加I2C总线恢复程序。
每次I2C主设备复位后,如果检测到SDA数据线被拉低,则控制I2C 中的SCL时钟线产生9个时钟脉冲(针对8位数据的情况),这样I2C从设备就可以完成被挂起的读操作,从死锁状态中恢复过来。
这种方法有很大的局限性,因为大部分主设备的I2C模块由内置的硬件电路来实现。
软件并不能够直接控制SCL信号模拟产生需要时钟脉冲。
使用此种方法可以使用IO模拟I2C,SCL时钟易控制。
(5) 在I2C总线上增加一个额外的总线恢复设备,这个设备监视I2C总线。
当设备检测到SDA信号被拉低超过指定时间时,就在SCL总线上产生9个时钟脉冲,使I2C从设备完成读操作,从死锁状态上恢复出来。
总线恢复设备需要有具有编程功能,一般可以用单片机或CPLD实现这一功能。
(6) 在I2C上串人一个具有死锁恢复的I2C缓冲器。
STM32中硬件IIC运行时候,老是停在下面这里,是主模式选择失败,...
展开全部 多个Arduino传感器同时工作分为以下几种情况:1、传感器输出量为单线高低电平或模拟电压。
这种传感器,供电完成后,只通过1个管脚向外输出高低电平或模拟电压。
如光电开关、光强度传感器、电位器等,这样的传感器使用最简单,只要你的单片机管脚资源足够,你可以一次连接多个。
2、传感器输出为数据 这种传感器,通常把采集到的信息,按照一定的通信接口和协议向外输出,例如温度传感器18B20(单总线)、GPS(TTL 232串口)、加速度计(I2C)等等,如果需要连接多个这样的传感器,则需要考虑MCU的处理能力和通信接口的资源。
一般来说Arduino都能够实现以上接口,但很多是通过软件和库实现的软接口,所以要考虑处理器的能力。
在Arduino IDE里有很多例程,可以帮助你快速实现以上接口。
...
用按键精灵写一些对某个软件模拟手工点击的操作是属于违法吗
展开全部 1、首先确认你的I2C的速率,软件模拟的话就与MCLK直接相关了,自然单片机的速率下降就会正常;如果是硬件I2C的话需要看时钟来源是不是MCLK并作修改。
2、看你的电路并没有进行上拉也就是SDA和SCL需要接4.7K或者10K的电阻至VCC即可。
3、如果你的I2C是等待延时的话建议修改delay参数或者使用返回ACK查询方式。
4、有问题随时hi我,可以给你传一份调试通过的代码!...
转载请注明出处51数据库 » 软件模拟iic的写操作
人生如戏丨全靠演技丶污黄