2857|3

19

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

望神赐教,感激不尽 [复制链接]

3芯积分
DSP的i2c使用遇见了两个小问题,
(1) bytein(0xA0 + ((addr & 0x0300) >> 7));  //写入写控制字0xA0 为什么不直接写0xA0
(2)还有就是GPIO使用上拉方式, SCL_1( GpioCtrlRegs.GPBSET.bit.GPIO32=1; )为什么输出为高电平
程序如下:
void Eerom_Gpio_Init(void)
{
        EALLOW;
    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;                  //上拉
    GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;           // 输出端口
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;          // IO口
    GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;         // 不同步

    GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;                  //上拉
    GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;           // 输出端口
    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0;          // IO口
    GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;   // 不同步
    EDIS;
}
__inline void SDA_READ(void)
{
    EALLOW;
    GpioCtrlRegs.GPBDIR.bit.GPIO32=0;       //Input, SDA
    EDIS;
}

__inline void SDA_WRITE(void)
{
    EALLOW;
    GpioCtrlRegs.GPBDIR.bit.GPIO32=1;       //Output. SDA
    EDIS;
}




///=========================GPIO SIMULATE I2c communication=====================*/
void delay(Uint16 time)                                         //延时函数
{
    for(; time>0 ; time--)
    {
        asm(" nop");
        asm(" nop");
        asm(" nop");
        asm(" nop");
                asm(" nop");
        asm(" nop");
        asm(" nop");
        asm(" nop");
    }
}


void begintrans(void)                                       //发送START 信号
{
    SDA_W1;                                                         //SDA=1
    delay(DELAY_UNIT * 10);                         //延时
    SDA_WRITE();                                            //SDA 方向为输出到EEPROM
    delay(DELAY_UNIT * 10);                         //延时
    SCL_1;                                                          //SCL=1
    delay(DELAY_UNIT * 10);                         //延时
    SDA_W0;                                                         //SDA=0
    delay(DELAY_UNIT * 10);                                //延时
}

void stoptrans(void)                                        //发送STOP 信号
{
    SDA_WRITE();                                            //SDA方向为输出到EEPROM
    delay(DELAY_UNIT * 10);                                //延时
    SDA_W0;                                                         //SDA=0
    delay(DELAY_UNIT * 10);                         //延时
    SCL_1;                                                          //SCL=1
    delay(DELAY_UNIT * 10);                         //延时
    SDA_W1;                                                         //SDA=1
    delay(DELAY_UNIT * 10);        
}

void ack(void)                                              //等待EEPROM 的ACK 信号
{
    Uint16 d;
    Uint16  i;     
    SDA_READ();                                             //SDA方向为从EEPROM 输入
    delay(DELAY_UNIT * 2);                          //延时
    SCL_1;                                                          //SCL=1
    delay(DELAY_UNIT * 2);                                  //延时
    i = 0;              
    do
    {
        d = SDA_R;
        i++;
        delay(DELAY_UNIT);        
    }
    while((d == 1) && (i <= 500));              //等待EEPROM 输出低电平,4ms后退出循环

    if (i >= 499)
    {
        eromrw_err = 0xff;
    }
   
    i = 0;           
    SCL_0;                                                          //SCL=0
    delay(DELAY_UNIT * 2);                          //延时
}

void bytein(Uint16 ch)                                          //向EEPROM 写入一个字节
{
    Uint16 i;     
    SCL_0;                                                          //SCL=0
    delay(DELAY_UNIT * 2);                                        //延时
    SDA_WRITE();                                            //SDA方向为输出到EEPROM
    delay(DELAY_UNIT);                                          //延时
    for(i=8;i>0;i--)
    {        
        if ((ch & 0x80)== 0)
            {
            SDA_W0;                                             //数据通过SDA 串行移入EEPROM
            delay(DELAY_UNIT);                                //延时
            }
        else
            {
            SDA_W1;
            delay(DELAY_UNIT);                                //延时
            }
        SCL_1;                                                      //SCL=1
        delay(DELAY_UNIT * 2);                      //延时
        ch <<= 1;
        SCL_0;                                                      //SCL=0
        delay(DELAY_UNIT);                              //延时
    }
    ack();
}

Uint16 byteout(void)                                        //从EEPROM 输出一个字节
{
    unsigned char i;
    Uint16 ch;
    ch = 0;

    SDA_READ();                                             //SDA 的方向为从EEPROM 输出
    delay(DELAY_UNIT * 2);                                 //延时
    for(i=8;i>0;i--)
    {
        ch <<= 1;
        SCL_1;                                                      //SCL=1
        delay(DELAY_UNIT);                              //延时
        ch |= SDA_R;                                            //数据通过SDA 串行移出EEPROM
        delay(DELAY_UNIT);                                     //延时
        SCL_0;                                                      //SCL=0
        delay(DELAY_UNIT * 2);                      //延时
    }
    return(ch);
}

void writebyte(Uint16 addr,Uint16 data)         //向EEPROM 指定地址写入一个字节的数据
{
    begintrans();                                                        //开始
    bytein(0xA0 + ((addr & 0x0300) >> 7));  //写入写控制字0xA0
    bytein(addr);                                               //写入指定地址
    bytein(data);                                                      //写入待写入EEPROM 的数据
    stoptrans();                                                        //停止
    delay(8000);
}



Uint16 readbyte(Uint16 addr)                                 //从EEPROM 指定地址读取一个字节的数据
{
    Uint16 c;   
    begintrans();                                               //开始
    bytein(0xA0 + ((addr & 0x0300) >> 7));  //写入写控制字0xA0
    bytein(addr);                                               //写入指定地址
    begintrans();                                               //开始
    bytein(0xA1);                                               //写入读控制字0xA1
    c = byteout();                                              //读出EEPROM 输出的数据
    stoptrans();                                                //停止
    delay(2000);                                                //延时
    return(c);
}

最新回复

  详情 回复 发表于 2015-11-10 14:31
点赞 关注
 

回复
举报

19

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
目前我已经弄明白第一个问题了
 
 

回复

366

帖子

1

TA的资源

一粒金砂(高级)

板凳
 
GpioCtrlRegs.GPBSET.bit.GPIO32 = 1;
GpioCtrlRegs是指GPIO相关的寄存器组
GPBSET是指设置GPIO的一个寄存器
bit是指按位操作
GPIO32是说第32个IO口
=1 是说该位置位
上拉方式通常是为了给确定的电平
其实GpioCtrlRegs.GPBDAT.bit.GPIO32 = 1;也可以输出高电平
这两句都能达到相同的目的,原因就是人家内部电路决定的,手册里应该也写了

赞赏

1

查看全部赞赏

 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

4
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表