打印
[技术问答]

新唐NANO120中I2C驱动寄存器写入不了

[复制链接]
2130|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lixiang656|  楼主 | 2016-4-7 10:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在写NANO120驱动24C02的程序中,对I2C的初始化如下:
void I2C0_Init()
{
        //使能I2C0引脚       
    SYS->PA_L_MFP &= ~(SYS_PA_H_MFP_PA8_MFP_Msk | SYS_PA_H_MFP_PA9_MFP_Msk);
    SYS->PA_L_MFP |= (SYS_PA_H_MFP_PA9_MFP_I2C0_SCL | SYS_PA_H_MFP_PA8_MFP_I2C0_SDA);

        //使能I2C0时钟
         CLK_EnableModuleClock(I2C0_MODULE);

        //使能I2C
         I2C0->CON |=I2C_CON_IPEN_Msk;

         /* Enable I2C0 interrupt */
    I2C_EnableInt(I2C0);
    NVIC_EnableIRQ(I2C0_IRQn);
         DEBUGMSG("I2C0 initial over!\n");
}

然后在读写操作24C02中,对I2C的控制寄存器进行写操作,发现无法写入,以下是写入寄存器的代码:
I2C_SET_CONTROL_REG(I2C0,I2C_STA);
I2C_SET_CONTROL_REG(I2C0,I2C_SI);

请问如何解决?求大神!
沙发
lixiang656|  楼主 | 2016-4-7 10:59 | 只看该作者
感觉像是I2C的初始化没做好?求大神解答!谢谢

使用特权

评论回复
板凳
玛尼玛尼哄| | 2016-4-7 14:52 | 只看该作者
void I2C0_Init(void)
{
    /* Open I2C0 and set clock to 100k */
    I2C_Open(I2C0, 100000);

    /* Get I2C0 Bus Clock */
    printf("I2C0 clock %d Hz\n", I2C_GetBusClockFreq(I2C0));

    I2C_EnableInt(I2C0);
    NVIC_EnableIRQ(I2C0_IRQn);
}
少了open吧。

使用特权

评论回复
地板
gejigeji521| | 2016-4-7 18:05 | 只看该作者
/************************* Copyright (c) 2014 SmartMcu Team *****************************
*项目名称:ARM Cortex-M0
*描    述:I2C测试

*******************************************************************************************/

#include "SmartM_M0.h"

#define EEPROM_SLA              0xA0
#define EEPROM_WR               0x00
#define EEPROM_RD               0x01

#define I2C_CLOCK               13
#define PAGE_SIZE               8

/*****************************************
*函数名称:Timed_Write_Cycle
*输    入:无
*输    出:无
*功    能:同步的写周期
******************************************/
void Timed_Write_Cycle(void)                  
{
    while (I2STATUS != 0x18)
    {
        //启动
        I2CON |= STA;                          
        I2CON |= SI;
        while ((I2CON & SI) != SI);
        I2CON &= ((~STA) & (~SI));

                    //设备地址
        I2DAT = EEPROM_SLA | EEPROM_WR;
        I2CON |= SI;
        while ((I2CON & SI) != SI);
    }

    //停止
    I2CON |= STO;
    I2CON |= SI;
    while (I2CON & STO);
}
/*****************************************
*函数名称:I2CInit
*输    入:无
*输    出:无
*功    能:I2C初始化
******************************************/
VOID I2CInit(VOID)
{
    P3_PMD &= ~(Px4_PMD | Px5_PMD);
          P3_PMD |= (Px4_OD | Px5_OD);                       //使能I2C0引脚

    P3_MFP &= ~(P34_T0_I2CSDA | P35_T1_I2CSCL);
          P3_MFP |= (I2CSDA | I2CSCL);                                   //选择P3.4,P3.5作为I2C0功能引脚   

          APBCLK |= I2C0_CLKEN;                       //使能I2C0时钟
    I2CLK = I2C_CLOCK;                                                                

    I2CON |= ENSI;                                     //使能I2C
}
/*****************************************
*函数名称:I2CWrite
*输    入:unAddr   写地址
          pucData  写数据
                      unLength 写长度
*输    出:TRUE/FALSE
*功    能:AT24C0X写数据
******************************************/
BOOL I2CWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
    UINT32 i;

    I2CON |= STA;                                          //启动
    I2CON |= SI;                              

    while ((I2CON & SI) != SI);               

    I2CON &= ((~STA)&(~SI));                  

    if (I2STATUS != 0x08)                   
    {
                    return FALSE;
    }


    //进入读写控制操作
    I2DAT = EEPROM_SLA | EEPROM_WR;
    I2CON |= SI;
    while ((I2CON & SI) != SI);

    if (I2STATUS != 0x18)              
    {
              return FALSE;
    }

    //写地址
    I2DAT = unAddr;
    I2CON |= SI;
    while ((I2CON & SI) != SI);
    if (I2STATUS != 0x28)              
    {
              return FALSE;
    }
       
                //写数据
                for(i=0; i<unLength; i++)
                {
                                I2DAT = *(pucData+i);
                                I2CON |= SI;
                                while ((I2CON & SI) != SI);
                                if (I2STATUS != 0x28)              
                                {
                                                return FALSE;
                                }       
                }

    //停止
    I2CON |= STO;
    I2CON |= SI;
    while (I2CON & STO);               

    Timed_Write_Cycle();               
                                                                                              
          return TRUE;                                                                                                 
}

/*****************************************
*函数名称:I2CRead
*输    入:unAddr   读地址
          pucData  读数据
                      unLength 读长度
*输    出:TRUE/FALSE
*功    能:AT24C0X读数据
******************************************/
BOOL I2CRead(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
          UINT32 i;

    I2CON |= STA;                                      //启动
    I2CON |= SI;                              

    while ((I2CON & SI) != SI);                

    I2CON &= ((~STA)&(~SI));                  

    if (I2STATUS != 0x08)                   
    {
                    return FALSE;
    }


    //进入读写控制操作  
    I2DAT = EEPROM_SLA | EEPROM_WR;
    I2CON |= SI;
    while ((I2CON & SI) != SI);

    if (I2STATUS != 0x18)              
    {   
            return FALSE;
    }

          //写入读地址
    I2DAT = unAddr;
    I2CON |= SI;
    while ((I2CON & SI) != SI);
    if (I2STATUS != 0x28)              
    {
              return FALSE;
    }
       
    // 重新启动
    I2CON |= STA;         
    I2CON |= SI;                                      
    while ((I2CON & SI) != SI);                       
    I2CON &= ((~STA)&(~SI));                          

    if (I2STATUS != 0x10)                             
    {
              return FALSE;
    }

    //进入读操作  
    I2DAT = EEPROM_SLA | EEPROM_RD;
    I2CON |= SI;
    while ((I2CON & SI) != SI);            

    if (I2STATUS != 0x40)              
    {
        while (1);
    }

                //读取数据
                I2CON |= AA;

                for(i=0; i<unLength; i++)
                {
                       
                                I2CON |= SI;
                                while ((I2CON & SI) != SI);
               
                                if (I2STATUS != 0x50)              
                                {
                                                return FALSE;
                                }
               
                        *(pucData+i) = I2DAT;       
                }

    //发送NACK到AT24C02,执行断开连接操作
    I2CON &= (~AA);
    I2CON |= SI;
    while ((I2CON & SI) != SI);

    //停止
    I2CON |= STO;
    I2CON |= SI;
    while (I2CON & STO);                     

        return TRUE;

}

/****************************************
*函数名称:main
*输    入:无
*输    出:无
*功    能:函数主体
******************************************/
INT32 main(VOID)
{
          UINT32 i=1;
          UINT8  buf[32]={0};
               
          /*1.MCU频率初始化,频率为50MHz*/
          McuInit(MCU_FREQUENCY);
          /*2.串口初始化,波特率为115200bps*/
                UartInit(115200);
          /*3.I2C初始化*/
          I2CInit();
       
          printf("\r\n================================================\r\n");
          printf("\r\n                 I2C Test                     \r\n");
          printf("\r\n================================================\r\n");
       
          while(1)
                {
                          /*4.buf缓冲区置前9字节置为同一样的数据*/
                                memset(buf,i+'0',9);
                                /*5.I2C执行写操作*/
                                I2CWrite(0,buf,9);       
        /*6.打印当前状态*/                       
                                printf("写入9字节数据-%d\r\n",i);                       
                                Delayms(1000);

                                //==================================================

        /*7.buf缓冲区置前9字节置为同一样的数据*/
                                memset(buf,0,sizeof buf);               
                                /*8.I2C执行读操作*/
                                I2CRead(0,buf,9);                       
                                /*9.打印当前读取到的数据*/
                                printf("读入9字节数据:%s\r\n",buf);
                               
                                Delayms(1000);
                                /*10.i为当前写入的值*/
                                if(++i>9)
                                {
                                         i=1;
                                }                               
                       
                }
}


使用特权

评论回复
5
dentsgot| | 2016-4-7 20:32 | 只看该作者
你用示波器观察一下,看看时序是不是完全正确

使用特权

评论回复
6
capturesthe| | 2016-4-8 22:39 | 只看该作者
初始化设置中的地址设置在什么地方呢

使用特权

评论回复
7
DreamofOven| | 2016-4-11 15:16 | 只看该作者
i2c的时序和24c02的时序一致吗

使用特权

评论回复
8
Bermanrep| | 2016-4-13 21:30 | 只看该作者
我感觉是时序写的不对,要么就是时钟频率太快了

使用特权

评论回复
9
guguo8266| | 2021-8-3 14:57 | 只看该作者
我在调Nano100的iic

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

20

帖子

1

粉丝