[ZLG-ARM] 【SmartArm2200】I2C的问题【Arm嵌入式系统实验教程二】

[复制链接]
 楼主| 51ti5000 发表于 2007-1-18 10:04 | 显示全部楼层 |阅读模式
周公好,<br />&nbsp;&nbsp;&nbsp;&nbsp;又来麻烦你了,最近一周一直在看I2C的相关资料和你们写的源码,也在用开发板做实验,但还是有很多问题不明白,所以这里想详细问下。<br />&nbsp;&nbsp;&nbsp;&nbsp;1,首先是这里<br />&nbsp;&nbsp;&nbsp;void&nbsp;&nbsp;__irq&nbsp;&nbsp;IRQ_I2C(void)<br />{&nbsp;&nbsp;uint8&nbsp;&nbsp;sta;<br /><br />&nbsp;&nbsp;&nbsp;sta&nbsp;=&nbsp;I2STAT;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;读出I2C状态字<br />&nbsp;&nbsp;&nbsp;switch(sta)<br />&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;case&nbsp;&nbsp;0x08:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;己发送起始条件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(1==I2C_suba_en)&nbsp;I2DAT&nbsp;=&nbsp;I2C_sla&0xFE;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;指定子地址读时,先写入地址<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;I2DAT&nbsp;=&nbsp;I2C_sla;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;否则直接发送从机地址<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0x28;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;SI=0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />Question1:为什么else后面不分情况?因为写操作时候(2==I2C_suba_en),也要写从机地址+子地址啊;2==I2C_suba_en和0==I2C_suba_en后面执行的动作肯定应该不一样啊,为什么不分情况,直接就else&nbsp;I2DAT&nbsp;=&nbsp;I2C_sla;&nbsp;...了呢??<br />&nbsp;&nbsp;&nbsp;2&nbsp;case&nbsp;&nbsp;0x18:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;已发送SLA+W,并已接收应答<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(0==I2C_suba_en)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;无子地址,则直接发送数据<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;if(I2C_num&gt0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;I2DAT&nbsp;=&nbsp;*I2C_buf++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0x28;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />Question2:无子地址应该是写了从机地址+子地址后就可以叫无子地址了;在18H这个状态子地址肯定是没有写入到从机的啊,所以应该还有子地址,所以我的疑问是怎么会在case&nbsp;18H的时候出现无子地址直接发送数据这个语句呢(就是我上面贴出来这句)??<br />&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;case&nbsp;&nbsp;0x40:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;己发送SLA+R,并已接收到应答<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(1==I2C_num)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;最后一字节,接收数据后发送非应答信号<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0x2C;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;AA=0,接收到数据后产生非应答<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;接收数据并发送应答信号<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;I2CONSET&nbsp;=&nbsp;0x04;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;AA=1,接收到数据后产生应答<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0x28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;&nbsp;0x50:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*I2C_buf++&nbsp;=&nbsp;I2DAT;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;读取数据<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(1==I2C_num)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0x2C;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;AA=0,接收到数据后产生非应答<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;I2CONSET&nbsp;=&nbsp;0x04;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;AA=1,接收到数据后产生应答<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0x28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />Question3:40H是从机已经给主机发送了应答位,在case&nbsp;40H这个语句里为什么没有象case&nbsp;50H接受数据的语句?我分析是case&nbsp;40H语句里是能够接受数据的。<br />Question4:为什么最后一字节用if(1==I2C_num)判断而不是if(0==I2C_num)??
 楼主| 51ti5000 发表于 2007-1-18 11:04 | 显示全部楼层

Question5 Question5 Question5

Question5&nbsp;&nbsp;<br />最后读取程序中的:<br />I2C_sla=sla+1;&nbsp;&nbsp;&nbsp;怎么能保证sal最低位是0呢?如果是1,加1后就变成0了啊,?????????
 楼主| 51ti5000 发表于 2007-1-18 12:55 | 显示全部楼层

顶一个吧

顶一个吧。。。。。。耐心等待
 楼主| 51ti5000 发表于 2007-1-18 15:15 | 显示全部楼层

顶一个吧。。。。。。耐心等待

顶一个吧。。。。。。耐心等待<br />
ZLGARM 发表于 2007-1-18 15:35 | 显示全部楼层

re:

1.&nbsp;在启动总线前(如IRcvByte函数),已正确设置好I2C_suba_en和I2C_sla<br />&nbsp;&nbsp;&nbsp;I2C_suba_en=0,&nbsp;读写操作要在I2C_sla正确设置(R/W位)<br />&nbsp;&nbsp;&nbsp;I2C_suba_en=1,&nbsp;要在I2C_sla正确设置R/W位为1&nbsp;(读操作)<br />&nbsp;&nbsp;&nbsp;I2C_suba_en=2,&nbsp;要在I2C_sla正确设置R/W位为0&nbsp;(读操作)<br /><br />那么,只有在I2C_suba_en=1,要对I2C_sla进行&0xFE操作(先写子地址),其它情况直接使用I2C_sla即可。<br /><br />2.&nbsp;只要发送SLA+W,就会进入0x18状态,再进行子地址/数据发送。<br />&nbsp;&nbsp;&nbsp;无子地址器件的操作:&nbsp;启动&nbsp;+&nbsp;SLA+W&nbsp;+&nbsp;数据...<br />&nbsp;&nbsp;&nbsp;有子地址器件的操作:&nbsp;启动&nbsp;+&nbsp;SAL+W&nbsp;+&nbsp;I2C_suba&nbsp;+&nbsp;数据(或重启总线)...<br /><br />3.&nbsp;发送SLA+R后,就会进入0x40,还没有接收到任何数据。<br /><br />4.&nbsp;1==I2C_num,表示还要接收1字节数据,即最后一字节。<br />&nbsp;&nbsp;&nbsp;执行I2CONCLR&nbsp;=&nbsp;0x2C才开始接收。<br /><br />5.&nbsp;在调用IRcvByte等接口函数时,用户提供的sla的R/W位必须为0,否则出错。<br />
 楼主| 51ti5000 发表于 2007-1-18 21:49 | 显示全部楼层

关于Question1

首先谢谢zlgmcu百忙中抽时间给于我的回答,对于Question2--5我现在已经理解清楚,现在对于Question1还是有问题存在,比如有子地址的器件进行写操作的化,仍然也要进行写子地址啊,所以我认为2==I2C_suba_en时候,I2DAT的这句应该I2DAT&nbsp;=&nbsp;I2C_sla&0xFE,请周公指教!
ZLGARM 发表于 2007-1-19 08:35 | 显示全部楼层

re:

2==I2C_suba_en时,已正确设置好I2C_sla的R/W位为0,就不需要&nbsp;&0xFE.&nbsp;当然,如果使用也没有关系.
 楼主| 51ti5000 发表于 2007-1-19 09:20 | 显示全部楼层

看来自己还是不会思考啊。

这么早ZLGARM就回我的问题,真是特别感谢!!大公司的人就是不一样啊!<br />看了ZLGARM最新的回答才知道自己是个不会思考的人啊,原来这个问题在ZLGARM第一次回答的时候就已经给出答案了:“在调用IRcvByte等接口函数时,用户提供的sla的R/W位必须为0,否则出错。”<br />最后还想问个问题,就是贵公司给出的这个I2C软件包根据我的分析应该是针对大多数I2C器件的,而不是仅仅针对CAT1025的,我这种理解对吗??<br />再次真心感谢!!!I&nbsp;LOVE&nbsp;THIS&nbsp;MCU!
 楼主| 51ti5000 发表于 2007-1-19 11:11 | 显示全部楼层

新问题

再次重新综合起来看整个程序的时候,又产生了一个新问题<br />为何每个CASE&nbsp;后面都要break?break的话不就跳出CASE程序了吗,直接跳到VICVectAddr0x00去了,这不就是关闭中断了吗??比如说我们想发送一连串字节,在case&nbsp;0x18时候,执行完后break那么不就跳出去了吗,也就是根本没字节写进去了啊?<br /><br />1&nbsp;主程序里面设置了I2C为向量IRQ中断<br />2&nbsp;I2C里面还设置了一个中断SI,这个SI中断是用来写数据到I2DAT的<br />&nbsp;&nbsp;**所以我的理解是有两个中断&nbsp;I2C本身是个中断,I2C里面SI还有个中断,中断这么嵌套的**<br />我想说的是&nbsp;Q1那么到底有几个中断啊?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Q2&nbsp;那个break到底是怎么会事情??越想越糊涂了。。。。。<br /><br />ZLGARM请指点迷津吧
 楼主| 51ti5000 发表于 2007-1-22 14:24 | 显示全部楼层

新问题

再次重新综合起来看整个程序的时候,又产生了一个新问题<br />为何每个CASE&nbsp;后面都要break?break的话不就跳出CASE程序了吗,直接跳到VICVectAddr0x00去了,这不就是关闭中断了吗??比如说我们想发送一连串字节,在case&nbsp;0x18时候,执行完后break那么不就跳出去了吗,也就是根本没字节写进去了啊?<br /><br />1&nbsp;主程序里面设置了I2C为向量IRQ中断<br />2&nbsp;I2C里面还设置了一个中断SI,这个SI中断是用来写数据到I2DAT的<br />&nbsp;&nbsp;**所以我的理解是有两个中断&nbsp;I2C本身是个中断,I2C里面SI还有个中断,中断这么嵌套的**<br />我想说的是&nbsp;Q1那么到底有几个中断啊?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Q2&nbsp;那个break到底是怎么会事情??越想越糊涂了。。。。。<br /><br />ZLGARM请指点迷津吧<br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

20

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部