历史上的今天
返回首页

历史上的今天

今天是:2024年08月24日(星期六)

2019年08月24日 | 51单片机 软件模拟IIC

2019-08-24 来源:eefocus

/*==========================================================================


名称:IIC协议


内容:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改


(本例是1us机器周期,即晶振频率要小于12MHZ)


============================================================================*/


#include


#include "iic.h"


bit ack;


/*=================================================


启动总线


==================================================*/


void iic_start()


{


SDA = 1; //发送起始条件的数据信号


SCL = 1;


delay_us(1); //起始条件建立时间大于4.7us,延时


SDA = 0; //发送起始信号


delay_us(1); //起始条件锁定时间大于4μ


SCL = 0; //钳住I2C总线,准备发送或接收数据


}


/*=================================================


结束总线


==================================================*/


void iic_stop()


{


SDA = 0; //发送结束条件的数据信号


SCL = 1;


delay_us(1); //结束条件建立时间大于4μ


SDA = 1; //发送I2C总线结束信号


delay_us(1);


SCL = 0;


}


/*=====================================================================


发送一个字节数据


函数原型: bit iic_send_byte(unsigned char byte);


功能: 将数据byte发送出去,可以是地址,也可以是数据,发完后等待应答,并对


此状态位进行操作.(不应答或非应答都使ack=0 假)


发送数据正常,ack=1; ack=0表示被控器无应答或损坏。


======================================================================*/


bit iic_send_byte(unsigned char byte)


{


unsigned char i;


for(i = 0; i < 8; i++) //要传送的数据长度为8位


{


SDA = byte & 0x80; //判断发送位


SCL = 1; //置时钟线为高,通知被控器开始接收数据位


delay_us(1); //保证时钟高电平周期大于4μ


SCL = 0;


byte <<= 1;


}


SCL = 1;


SDA = 1; //8位发送完后释放数据线,准备接收应答位


delay_us(1);


if(0 == SDA) //判断是否接收到应答信号


{


ack = 1;


}


else


{


ack = 0;


}


SCL = 0;


return ack;


}


/*===================================================================================


接受一个字节数据


函数原型: unsigned char iic_receive_byte();


功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数。


====================================================================================*/


unsigned char iic_receive_byte()


{


unsigned char i;


unsigned char a;


unsigned char temp = 0;


SDA = 1; //置数据线为输入方式


for(i = 0; i < 8; i++)


{


SCL = 0; //置时钟线为低,准备接收数据位


delay_us(1); //时钟低电平周期大于4.7us


SCL = 1; //置时钟线为高使数据线上数据有效


if(SDA)


{


a = 1;


}


else


{


a = 0;


}


temp |= (a << (7 - i)); //读数据位,接收的数据位放入retc中


delay_us(1);


}


SCL = 0;


return temp;


}


/*===============================================================


应答子函数


================================================================*/


void iic_ack()


{


SDA = 0;


SCL = 1;


delay_us(1); //时钟低电平周期大于4μ


SCL = 0; //清时钟线,钳住I2C总线以便继续接收


}


/*================================================================


非应答子函数


=================================================================*/


void iic_noack()


{


SDA = 1;


SCL = 1;


delay_us(1); //时钟低电平周期大于4μ


SCL = 0; //清时钟线,钳住I2C总线以便继续接收


}


/*===========================================================================================


向有子地址器件发送多字节数据函数


函数原型: bit iic_send_str(unsigned char sla, unsigned char suba, unsigned char *str, unsigned char len);


功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程。


从器件地址sla,子地址suba,发送内容是str指向的内容,发送len个字节。


如果返回1表示操作成功,否则操作有误。


注意:使用前必须已结束总线。


=============================================================================================*/


bit iic_send_str(unsigned char sla, unsigned char suba, unsigned char *str, unsigned char len)


{


unsigned char i;


iic_start(); //启动总线


iic_send_byte(sla); //发送器件地址


if(0 == ack)


{


return ERR;


}


iic_send_byte(suba); //发送器件子地址


if(0 == ack)


{


return ERR;


}


for(i = 0; i < len; i++)


{


iic_send_byte(*str); //发送数据


delay_us(1); //必须延时等待芯片内部自动处理数据完毕


if(0 == ack)


{


return ERR;


}


str++;


}


iic_stop(); //结束总线


return SUCC;


}


/*===========================================================================================


向有子地址器件读取多字节数据函数


函数原型: bit iic_receive_str(unsigned char sla, unsigned char suba, unsigned char *str, unsigned char len);


功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程。


从器件地址sla,子地址suba,读出的内容放入str指向的存储区,读len个字节。


如果返回1表示操作成功,否则操作有误。


注意:使用前必须已结束总线。


=============================================================================================*/


bit iic_receive_str(unsigned char sla, unsigned char suba, unsigned char *str, unsigned char len)


{


unsigned char i;


iic_start(); //启动总线


iic_send_byte(sla); //发送器件地址


if(0 == ack)


{


return ERR;


}


iic_send_byte(suba); //发送器件子地址


if(0 == ack)


{


return ERR;


}


iic_start();


iic_send_byte(sla + 1);


if(0 == ack)


{


return ERR;


}


for(i = 0; i < len - 1; i++)


{


*str = iic_receive_byte(); //发送数据


iic_ack(); //发送就答位


str++;


}


*str = iic_receive_byte();


iic_noack(); //发送非应位


iic_stop(); //结束总线


return SUCC;


}

推荐阅读

史海拾趣

CTS [CTS Corporation]公司的发展小趣事

CTS Corporation的创始人在1896年创立了这家公司,当时的主要业务是设计并生产高品质的电话产品。随着电话技术的普及和通信行业的快速发展,CTS凭借其出色的产品质量和创新的设计理念,逐渐在电话市场中占据了一席之地。公司的创始人凭借其敏锐的商业洞察力和不懈的努力,为CTS奠定了坚实的基础。

HP(Keysight)公司的发展小趣事

在追求商业成功的同时,CTS也高度重视可持续发展和社会责任。公司致力于推动绿色生产和环保理念,采用环保材料和节能技术,减少对环境的影响。此外,CTS还积极参与社会公益活动,回馈社会,为社区的繁荣和发展贡献力量。

这些故事框架仅是对CTS Corporation公司可能的发展历程的一种推测和概述,具体的细节和内容需要根据实际情况进行补充和完善。希望这些框架能够为您撰写具体的发展故事提供一些灵感和帮助。

B&F Fastener Supply公司的发展小趣事

B&F Fastener Supply公司在上世纪末成立之初,就瞄准了快速发展的电子行业,意识到紧固件和电子元器件的供应将成为行业发展的关键。公司迅速调整战略,开始专注于电子工业用紧固件的研发和销售。通过与多家电子制造厂商建立合作关系,B&F逐渐在电子紧固件市场占据了一席之地。

Continental公司的发展小趣事

随着技术的不断进步和市场的不断变化,大陆集团也在不断调整其业务架构。在新的架构中,大陆集团将业务领域划分为三个部分:自主驾驶和安全、车联网和信息、以及橡胶技术(包括轮胎业务和康迪泰克)。这一调整使得大陆集团能够更好地应对市场变化和技术挑战。同时,大陆集团还通过收购和兼并等方式不断扩大其业务范围和技术实力。

Datapro International Inc公司的发展小趣事

随着全球化的加速和市场竞争的加剧,Datapro International Inc公司开始加快国际化发展的步伐。他们积极拓展海外市场,并在全球范围内建立了完善的销售和服务网络。

在国际化发展的过程中,Datapro International Inc公司遇到了许多挑战和困难。然而,他们凭借坚定的信念和不懈的努力,成功克服了这些困难。他们深入了解当地市场和文化背景,并根据市场需求和客户需求不断调整产品和服务策略。这些努力使得Datapro International Inc公司在海外市场取得了显著的成果。

Eurotech公司的发展小趣事

随着全球对环保问题的日益关注,Eurofarad公司也积极响应这一趋势。公司注重环保理念在产品设计和生产过程中的应用,努力减少对环境的影响。同时,公司还积极推动可持续发展战略,通过优化生产流程和采用环保材料等方式,降低能源消耗和废弃物排放。这些努力不仅符合了社会的期望,也为公司的长期发展提供了有力保障。

问答坊 | AI 解惑

锁相环的spice建模和仿真

不错的文章,大家看下…

查看全部问答>

新手询问下设备的问题

由于工作的需要,现在学搞无线遥控的发射与接收. 开发这类产品,需要哪些设备?对设备有些什么要求? 象频谱仪要多少G才够?等等... 哦,我主要搞315M433M这类的,请大虾们帮我推荐下设备,功能够用,实用,价格相当的,,, 谢谢了哟…

查看全部问答>

wince上电自启动,如何不出现桌面,直接出现我的程序界面?

我现在用注册表的方式,让我的程序(窗口程序)在gwes,explore之后启动。这样会先出现桌面2,3秒再出现我的程序。 如果希望不出现桌面,要怎么做。…

查看全部问答>

寻开发视频信号控制系统

运行环境:安防监控系统(视频信号控制) 主要设备:电脑(采集卡)+摄象机 传输方式:视频信号线缆(75-5)同轴线 要求:1 对前端设备进行视频信号控制(可以接收信号控制单片机) 2主控系统 是电脑作为信号命令主机(可以利用485   ...…

查看全部问答>

高分寻求一个技术方案

    现在有这样一个项目:要求开发一个桌面图形交互系统,要求安装在pc上的windows xp和嵌入式的vxWorks环境下均能运行。现在为找跨平台的界面库犯愁!我想到的有两个技术方案:     方案一:使用QT.     7月30日Q ...…

查看全部问答>

Linux下串口设置问题 急!!

我在Linux下编写了一段串口程序,进行数据收发,程序如下: #include #include #include #include #include #include #include #include #include #include #include char xCal_crc(char *ptr,int len); int fd; #defin ...…

查看全部问答>

wince sd卡 驱动的问题,原来是好的,我改动之后不行了,前辈们看下。

我之前做wince的128M sdram的支持的时候 由于对OEMAddressTable做了修改,后面的地址集体后移了,所以在初始化硬件的时候,将没有启用cache时候的高端地址也做了偏移,现在sdram好了 别的外设都正常,唯独sd不能识别。 我看到sd的地址定义就是个 ...…

查看全部问答>

Windows SDIO总线驱动的log

大家好。 我现在在开发一个SDIO设备,想实现为一个SDIO设备,而不是SD memory。 当我把它插到运行Windows XP的PC上时,Windows把它认成了一个磁盘。当我 试图查看该磁盘的属性时,没有任何属性显示出来。 我猜想应该是设备的硬件或者固件有问题 ...…

查看全部问答>

全自动声控频闪灯

本帖最后由 jameswangsynnex 于 2015-3-3 20:02 编辑 …

查看全部问答>

用过MAX038做信号源的请进!求助,谢谢。

MAX038的频率是接第5个脚的电容值乘以第10个管脚的输入电流。 因此可以通过接入第五个管脚的电容来选择不同的频段。 现在我用模拟开关CD4051来切换不同的电容,发现根本就不行。(可能是导通电阻太大导致的) 所以我换成了继电器的,发现波形还 ...…

查看全部问答>