历史上的今天
返回首页

历史上的今天

今天是:2025年04月02日(星期三)

正在发生

2019年04月02日 | Gpio模拟i2c总线对24c02进行读写

2019-04-02 来源:eefocus

使用资料:i2c总线时序手册、24c02手册及ARM主芯片的datasheet


一、通过原理图查看i2c的sda/scl两个引脚连接到ARM主芯片的哪两个GPIO口,以我现在使用的单板为例,如下图



从此图可以看出连接的GPIO口为9_3、9_2两个引脚。


二、通过控制GPIO高低电平来模拟I2C的时序完成总线驱动


首先通过i2c时序手册可以查看到如下图的一个时序



使用gpio9_2 和gpio9_3两个引脚来模拟sda/scl的时序,核心代码如下:


Gpioi2c.c


#define SCL (1 <<3) /* GPIO 9_3 */


#define SDA (1 << 2) /* GPIO 9_2 */


#define GPIO_I2C_SDA_REG (GPIO_9_BASE + 0x10)


#define GPIO_I2C_SCL_REG (GPIO_9_BASE + 0x20)


#define GPIO_I2C_SCLSDA_REG (GPIO_0_BASE + 0x30)


#define HW_REG(reg) *((volatile unsigned int *)(reg))


/*


* I2C by GPIO simulated read data routine.


*


* @return value: a bit for read


*


*/


static unsigned char i2c_data_read(void)


{


unsigned char regvalue;


regvalue = HW_REG(GPIO_9_DIR);


regvalue &= (~SDA);


HW_REG(GPIO_9_DIR) = regvalue;


DELAY(1);


regvalue = HW_REG(GPIO_I2C_SDA_REG);


if((regvalue&SDA) != 0)


return 1;


else


return 0;


}


/*


* sends a start bit via I2C rountine.


*


*/


static void i2c_start_bit(void)


{


DELAY(1);


i2c_set(SDA | SCL);


DELAY(1);


i2c_clr(SDA);


DELAY(2);


}


/*


* sends a stop bit via I2C rountine.


*


*/


static void i2c_stop_bit(void)


{


/* clock the ack */


DELAY(1);


i2c_set(SCL);


DELAY(1);


i2c_clr(SCL);


/* actual stop bit */


DELAY(1);


i2c_clr(SDA);


DELAY(1);


i2c_set(SCL);


DELAY(1);


i2c_set(SDA);


DELAY(1);


}


/*


* sends a character over I2C rountine.


*


* @param c: character to send


*


*/


static void i2c_send_byte(unsigned char c)


{


int i;


// local_irq_disable();


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


{


DELAY(1);


i2c_clr(SCL);


DELAY(1);


if (c & (1<<(7-i)))


i2c_set(SDA);


else


i2c_clr(SDA);


DELAY(1);


i2c_set(SCL);


DELAY(1);


i2c_clr(SCL);


}


DELAY(1);


// i2c_set(SDA);


// local_irq_enable();


}


/* receives a character from I2C rountine.


*


* @return value: character received


*


*/


static unsigned char i2c_receive_byte(void)


{


int j=0;


int i;


unsigned char regvalue;


// local_irq_disable();


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


{


DELAY(1);


i2c_clr(SCL);


DELAY(2);


i2c_set(SCL);


regvalue = HW_REG(GPIO_9_DIR);


regvalue &= (~SDA);


HW_REG(GPIO_9_DIR) = regvalue;


DELAY(1);


if (i2c_data_read())


j+=(1<<(7-i));


DELAY(1);


i2c_clr(SCL);


}


// local_irq_enable();


DELAY(1);


// i2c_clr(SDA);


// DELAY(1);


return j;


}


/* receives an acknowledge from I2C rountine.


*


* @return value: 0--Ack received; 1--Nack received


*


*/


static int i2c_receive_ack(void)


{


int nack;


unsigned char regvalue;


DELAY(1);


regvalue = HW_REG(GPIO_9_DIR);


regvalue &= (~SDA);


HW_REG(GPIO_9_DIR) = regvalue;


DELAY(1);


i2c_clr(SCL);


DELAY(1);


i2c_set(SCL);


DELAY(1);


nack = i2c_data_read();


DELAY(1);


i2c_clr(SCL);


DELAY(1);


// i2c_set(SDA);


// DELAY(1);


if (nack == 0)


return 1;


return 0;


}


EXPORT_SYMBOL(gpio_i2c_read);


unsigned char gpio_i2c_read(unsigned char devaddress, unsigned char address)


{


int rxdata;


i2c_start_bit();


i2c_send_byte((unsigned char)(devaddress));


i2c_receive_ack();


i2c_send_byte(address);


i2c_receive_ack();


i2c_start_bit();


i2c_send_byte((unsigned char)(devaddress) | 1);


i2c_receive_ack();


rxdata = i2c_receive_byte();


//i2c_send_ack();


i2c_stop_bit();


return rxdata;


}


EXPORT_SYMBOL(gpio_i2c_write);


void gpio_i2c_write(unsigned char devaddress, unsigned char address, unsigned char data)


{


i2c_start_bit();


i2c_send_byte((unsigned char)(devaddress));


i2c_receive_ack();


i2c_send_byte(address);


i2c_receive_ack();


i2c_send_byte(data);


// i2c_receive_ack();//add by hyping for tw2815


i2c_stop_bit();


}


三、编写测试程序i2c_read/i2c_write工具调用gpio_i2c_write/read操作24c02的基地址,基地址通过原理图来查看地址是为0xa0-0xae(这个地址是通过24c02的手册查看)中的哪一个,测试通过后进行24c02驱动的接口编写,若不通过需要查看sda/scl两根引脚是否正常上拉,连接是否有问题等。


从上面的原理图可以看出A0-A2均为接地,所以A0-A2的值全为0,再根据24c02的手册可以查出下图的slave address,值为0xa0。

四、编写24c02接口,并完成整个驱动的调试。


推荐阅读

史海拾趣

Advanced Interconnections Corp公司的发展小趣事

随着市场竞争的加剧,AIC公司意识到品质是赢得客户信赖的关键。于是,公司加大了对生产过程的管控力度,从原材料采购到生产流程,再到产品检验,都实行了严格的质量控制。同时,AIC公司还建立了完善的售后服务体系,及时响应客户需求,解决产品使用过程中出现的问题。这些举措使AIC公司的产品赢得了客户的广泛好评,进一步巩固了市场地位。

AEC Design公司的发展小趣事
在初步获得市场认可后,AEC Design公司开始积极拓展国内外市场。通过与各大电商平台和实体零售商建立合作关系,公司的产品线逐渐覆盖更广泛的消费群体。同时,公司还积极参加各类行业展会和论坛,与业界同行交流学习,不断提升自身的品牌影响力和市场竞争力。
GaN Systems公司的发展小趣事

GAIA Converter Inc成立于1993年,总部位于法国波尔多附近的航空航天工业城,这里聚集了众多高科技企业和研究机构。公司自创立之初便专注于高可靠性和工业模块化电源解决方案的研发与生产。在成立初期,GAIA盖亚电源凭借对电力转换技术的深入理解,迅速开发出了一系列适用于航空、军事及高端工业应用的DC/DC转换器模块。这些产品凭借其卓越的性能和稳定的质量,在市场上赢得了初步认可。

Codeco Corporation Of Vermont公司的发展小趣事

在追求商业成功的同时,Codeco也积极履行企业社会责任。他们注重环保和可持续发展,在生产过程中采用环保材料和技术,减少对环境的影响。此外,Codeco还积极参与公益事业,为社会做出贡献。这些举措不仅提升了公司的社会形象,也赢得了员工和消费者的尊重与认可。


您可以根据这个框架,结合您对电子行业和Codeco Corporation Of Vermont的了解,撰写具体的故事内容。请注意,这些故事应基于事实或合理的推测,避免涉及未经证实的信息或夸大其词的描述。

天钰(FITIPOWER)公司的发展小趣事

在追求商业成功的同时,Codeco也积极履行企业社会责任。他们注重环保和可持续发展,在生产过程中采用环保材料和技术,减少对环境的影响。此外,Codeco还积极参与公益事业,为社会做出贡献。这些举措不仅提升了公司的社会形象,也赢得了员工和消费者的尊重与认可。


您可以根据这个框架,结合您对电子行业和Codeco Corporation Of Vermont的了解,撰写具体的故事内容。请注意,这些故事应基于事实或合理的推测,避免涉及未经证实的信息或夸大其词的描述。

Gigavac LLC公司的发展小趣事

在电子行业的浪潮中,Codeco Corporation Of Vermont(以下简称Codeco)由几位热衷于科技创新的工程师创立。他们看到了电子产品日益普及的趋势,决定投身这个充满机遇的领域。初创时期,资金短缺、市场竞争激烈,Codeco面临着巨大的挑战。然而,凭借着对技术的执着追求和对市场的敏锐洞察,他们成功开发出了一款具有创新性的电子产品,迅速在市场上占得一席之地。

问答坊 | AI 解惑

成都地震亲历

转载     下午2:30左右,在办公室里坐着,突然有人喊,地震了。我还没有反应过来,茫茫然站起来,看了一眼窗外,有人在往外跑。还没有等我作出反应,突然听到一种非常奇特,平生第一次听到的,很低沉,但无处不在的“轰轰”声,旋即, ...…

查看全部问答>

红外防水摄像机存在的技术问题

  关键字:红外防水摄像机   红外防水摄像机是将摄像机、防雨罩、红外LED灯等部件集成为一体的CCTV监控摄像设备。它实现夜视的基本原理是利用装备光藕CCD的普通摄像机感受红外光源的光谱特性(即可以感受可见光,也可以感受红外光),以附加的 ...…

查看全部问答>

FFT Co-Processor Reference Design

Introduction   The Fast Fourier Transform (FFT) co-processor reference design demonstrates the use of an Altera® FPGA as a high-performance digital signal processing (DSP) co-processor to the Texas Instruments TMS3 ...…

查看全部问答>

关于xdata编译问题

在KEIL中进行编译时,出错找不到“no an lvalue\"错误提示,如果将此行的代码去掉直接调用 printGB函数,编译就可以通过,小弟甚不解;期待哪位仁兄赐教; 代码原型如下: #ifndef _h12_h #define _h12_h ..... byte bymtv_osdra _at_ 0x0f0; ...…

查看全部问答>

verilog两个程序几乎一样,为什么其中一个有问题?

程序一:module    test(in1,in2,in3,in4,in5,in6,in7,in8,switch,outdata);input[3:0]    in1,in2,in3,in4,in5,in6,in7,in8;input[2:0]    switch;output[3:0]    outdata;reg[3:0]    outdata ...…

查看全部问答>

阻抗计算器

本帖最后由 dontium 于 2015-1-23 11:48 编辑 PCB走线时的阻抗计算器,很好用的。希望对大家有用哦! …

查看全部问答>

程序出现C(17): error C231: 'P': redefinition

如题,全是C(17): error C231: \'P\': redefinition之类的。。怎么处理呢,帮忙,。。附件里有一个c、3个h文件,帮我看看那哥哥姐姐们…

查看全部问答>

samba共享

本人在samba实现windows和linux系统的共享时,在windows中搜不到linux的ip地址,求大神解答?????…

查看全部问答>