搜索
bottom↓
回复: 30

用IO口模拟多组IIC协议,怎样减小代码量?

[复制链接]

出0入0汤圆

发表于 2013-5-1 20:45:45 | 显示全部楼层 |阅读模式
由于多组协议之间只有PORT.xx定义不一样,最笨的办法是所有函数都COPY一份,然后修改对应IO口。。。
还有就是在每个函数内部作切换,根据每次形参的不同来执行不同的IO口控制,思考了很久,觉得还是很复杂,有什么简便的方法么?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-5-1 21:19:19 | 显示全部楼层
你的第二个方法就可以.

出0入0汤圆

 楼主| 发表于 2013-5-1 21:41:53 | 显示全部楼层
lmserver 发表于 2013-5-1 21:19
你的第二个方法就可以.

感觉还是很复杂啊,决定使用哪个IO口的形参要层层传递到底层驱动函数去。。

出0入0汤圆

发表于 2013-5-1 22:07:01 | 显示全部楼层
一下还真想不到更好的办法.
程序空间不够么?

出0入0汤圆

发表于 2013-5-1 22:07:17 来自手机 | 显示全部楼层
I2C是总线用得着那么多端口?

出0入0汤圆

发表于 2013-5-2 10:23:09 | 显示全部楼层
tomhe666 发表于 2013-5-1 22:07
I2C是总线用得着那么多端口?

是哦,总线,可以一主机多从机啊

出0入0汤圆

发表于 2013-5-2 10:29:08 | 显示全部楼层
如果从机编了地址,那两根线就可以了啊
或者一根SCL加上N多跟SDA。

出0入0汤圆

发表于 2013-5-2 10:40:37 | 显示全部楼层
或许这种方法,比如:
BYTE I2C_RecvByte(BYTE SDA_Bit,BYTE SCL_bit)
{
    BYTE i;
    BYTE dat = 0;
    SDA = 1;                  
    for (i=0; i<8; i++)     
    {
        dat <<= 1;
        P1|=SCL _bit;              
        Delay5us();        
        if(P1&SDA_bit) dat |= 1;        
        P1&=~SCL_bit;         
        Delay5us();   
    }
    return dat;
}

其中SDA_bit和SCL_bit可以是0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80。这样每次只要调用这函数,赋值不同的端口位即可。

出0入0汤圆

 楼主| 发表于 2013-5-2 13:25:30 来自手机 | 显示全部楼层
tomhe666 发表于 2013-5-1 22:07  I2C是总线用得着那么多端口?

比如复制两个16Kbit的Eeprom,总线上只能挂一个设备吧,所以用了单独两套总线。

出0入0汤圆

 楼主| 发表于 2013-5-2 13:28:14 来自手机 | 显示全部楼层
XA144F 发表于 2013-5-2 10:29  如果从机编了地址,那两根线就可以了啊  或者一根SCL加上N多跟SDA。

IO口是够用的,只是想减小程序代码量。比如复制两个16Kbit的Eeprom,一对总线上只能挂一个设备。

出0入0汤圆

 楼主| 发表于 2013-5-2 13:29:04 来自手机 | 显示全部楼层
lmserver 发表于 2013-5-1 22:07  一下还真想不到更好的办法.  程序空间不够么?

还是谢谢!

出0入0汤圆

 楼主| 发表于 2013-5-2 13:29:49 来自手机 | 显示全部楼层
shpan_111 发表于 2013-5-2 10:23  是哦,总线,可以一主机多从机啊

谢谢!主要优化代码量。

出0入0汤圆

 楼主| 发表于 2013-5-2 13:36:22 来自手机 | 显示全部楼层
XA144F 发表于 2013-5-2 10:40  或许这种方法,比如:  BYTE I2C_RecvByte(BYTE SDA_Bit,BYTE SCL_bit)  {

嗯!也是每个函数都要增加几个形参哦,端口号不一样还不行啊。

出0入0汤圆

发表于 2013-5-2 13:48:17 | 显示全部楼层
wxty 发表于 2013-5-2 13:25
比如复制两个16Kbit的Eeprom,总线上只能挂一个设备吧,所以用了单独两套总线。 ...

你开个128字节的缓冲区,读128字节再写128字节...为什么不能挂在一个总线上?对于I2C这种慢速的总线,而且还是软件模拟的,完全看不出需要建立多个的意义啊!

出0入0汤圆

发表于 2013-5-2 13:54:50 | 显示全部楼层
wxty 发表于 2013-5-2 13:28
IO口是够用的,只是想减小程序代码量。比如复制两个16Kbit的Eeprom,一对总线上只能挂一个设备。 ...

为什么不行,你的读写同时进行?
应该也是先读,然后再写了,既然分时,就可以同时把

出0入0汤圆

 楼主| 发表于 2013-5-2 14:57:39 来自手机 | 显示全部楼层
jisaowang 发表于 2013-5-2 13:48  你开个128字节的缓冲区,读128字节再写128字节...为什么不能挂在一个总线上?对于I2C这种慢速的总线,而且还 ...

对于16Kbit容量的,引脚A0A1A2无效啊,不是吗?

出0入0汤圆

 楼主| 发表于 2013-5-2 14:59:16 来自手机 | 显示全部楼层
shpan_111 发表于 2013-5-2 13:54  为什么不行,你的读写同时进行?  应该也是先读,然后再写了,既然分时,就可以同时把 ...

A0A1A2难道不是无效的?

出0入0汤圆

发表于 2013-5-2 15:02:07 | 显示全部楼层
wxty 发表于 2013-5-2 13:28
IO口是够用的,只是想减小程序代码量。比如复制两个16Kbit的Eeprom,一对总线上只能挂一个设备。 ...

两个16K,你不如用一个32K,更好

出0入0汤圆

 楼主| 发表于 2013-5-2 15:06:42 来自手机 | 显示全部楼层
总之,硬件已经做成两对总线的了,程序空间有限什么办法可以优化代码量呢?

出0入0汤圆

 楼主| 发表于 2013-5-2 15:08:20 来自手机 | 显示全部楼层
本帖最后由 wxty 于 2013-5-2 15:09 编辑
tomhe666 发表于 2013-5-2 15:02  两个16K,你不如用一个32K,更好


是复制,一个读出另一个写入,所以。。

出0入0汤圆

发表于 2013-5-2 15:10:14 | 显示全部楼层

typedef struct
{
    u32 port;
    u32 pin;
}PortPin;
typedef struct
{
    PortPin SDA;
    PortPin SCL;
}I2C_PortPin;
#define I2C_NUM 10 //定义10个i2c接口
I2C_PortPin i2c_portpin[I2C_NUM]=
{
    {GPIOA,PIN0,GPIOB,PIN1},//I2C口0,使用PA0作为SDA,PB1作为SCL
    .......
};

u8 rw_i2c(u8 id,//新增接口id
               u8 *buff,u16 addr,u16 len,u8 rw)
{
    //使用i2c_portpin[id]操作SDA和SCL
}

出0入0汤圆

发表于 2013-5-2 15:42:59 | 显示全部楼层
wxty 发表于 2013-5-2 13:36
嗯!也是每个函数都要增加几个形参哦,端口号不一样还不行啊。

没办法,单片机的构架决定的,像STM32的话还好说,51或AVR的就惨了。

出0入0汤圆

发表于 2013-5-2 16:57:32 | 显示全部楼层
wxty 发表于 2013-5-2 14:59
A0A1A2难道不是无效的?

这样的话,就只有把pin口信息扔形参里传递了......或者你包装一个结构体,把这些信息都放结构体里,然后传递结构体指针,这样程序会比较好读,比较简洁.....

出0入0汤圆

发表于 2013-5-2 17:29:25 | 显示全部楼层
楼主想复杂了,复杂的代码,简单高效,简洁的代码却未必。

出0入0汤圆

 楼主| 发表于 2013-5-2 17:52:56 | 显示全部楼层
mhw 发表于 2013-5-2 15:10
typedef struct
{
    u32 port;

谢谢,很好的构思。
对于使用sfr或者bit关键字定义的端口寄存器得重新修改定义方式。

出0入0汤圆

 楼主| 发表于 2013-5-2 17:54:05 | 显示全部楼层
zenl0039 发表于 2013-5-2 17:29
楼主想复杂了,复杂的代码,简单高效,简洁的代码却未必。

Maybe !! 不优化的话总感觉很冗余。

出0入0汤圆

 楼主| 发表于 2013-5-3 17:13:18 来自手机 | 显示全部楼层
zenl0039 发表于 2013-5-2 17:29  楼主想复杂了,复杂的代码,简单高效,简洁的代码却未必。

神那!同样的延时函数,操作08Kbit的EEPROM测试结果:使用21楼提供的方式花了32妙太慢了,然而原来的笨办法却只用了4妙钟。。。而代码后者只小了200字节左右!或许这款单片机端口不习惯我定制的位操作方式。。。

出0入0汤圆

发表于 2013-5-6 09:34:40 | 显示全部楼层
呵呵,别激动。

首先,外部EEP就比较慢。

其次,STM32的IO做模拟I2C就必须用 位操作 才快。

这个用库的,易懂,改为用 寄存器的会更快一点,但EEP本身比较慢,改了,整体提速也不明显。

#define SCCB_CTRL_PORT         GPIOC  
#define SCCB_SCL                 GPIO_Pin_10
#define SCCB_SDA                 GPIO_Pin_11

#define SCCB_SCL_H                GPIO_SetBits  (SCCB_CTRL_PORT, SCCB_SCL)
#define SCCB_SCL_L                GPIO_ResetBits(SCCB_CTRL_PORT, SCCB_SCL)

#define SCCB_SDA_H                GPIO_SetBits  (SCCB_CTRL_PORT, SCCB_SDA)
#define SCCB_SDA_L                GPIO_ResetBits(SCCB_CTRL_PORT, SCCB_SDA)

unsigned char SCCB_Write(unsigned char DData)
{
        unsigned char j,tem;

        for(j=0;j<8;j++){
                if((DData<<j)&0x80){SCCB_SDA_H;}
                else{SCCB_SDA_L;}
                Delay_US(1);      
                SCCB_SCL_H;
                Delay_US(1);
                SCCB_SCL_L;;
                Delay_US(2);
        }
        Delay_US(5);
       
        SCCB_SDA_IN;
        Delay_US(2);
        SCCB_SCL_H;
        Delay_US(5);
        if(SCCB_SDA_rd>0)//忙或有问题
        {
                tem=0;  
        }
        else
        {
                tem=1;   //没问题继续
        }
        SCCB_SCL_L;
        Delay_US(2);       
    SCCB_SDA_OUT;

        return(tem);  
}

大概100us一个字节,就是说 1秒 写 10K 字节。

出0入0汤圆

发表于 2013-5-6 09:43:18 | 显示全部楼层
两种方法,哥都用过。
就我个人的经验,如果你的资源(主要是code资源)够的话,还是最简单的copy一份比较好。

出0入0汤圆

 楼主| 发表于 2013-5-6 14:58:11 来自手机 | 显示全部楼层
zenl0039 发表于 2013-5-6 09:34  呵呵,别激动。   首先,外部EEP就比较慢。

EEPROM允许这么快的速度?

出0入0汤圆

发表于 2013-10-5 20:30:15 | 显示全部楼层
看来我是太菜了。。。问题都没看懂。努力学习~!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-27 02:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表