找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

[NUC] NUC126的I2C功能

[复制链接]
跳转到指定楼层
楼主
匿名  发表于 2018-7-27 10:05:26 回帖奖励 |倒序浏览 |阅读模式
我使用NUC126的範例程式
執行I2C.C所提供的library
對一個byte位址進行寫入及讀取
在讀取時會產生錯誤
是哪裡沒處理好呢?


               g_u8DeviceAddr = 0x50;
                u16DataAddr = 0x0010
       
                ret_code = I2C_WriteByteTwoRegs(I2C0, g_u8DeviceAddr, u16DataAddr,  32) ;
                if( ret_code == 0 )
                          printf("One byte write Pass.....\n");
                else
                          printf("One byte write Failed..%d...\n",ret_code);
               
                g_u8DeviceAddr = 0x50;
                u16DataAddr = 0x0010 ;
                ret_code = I2C_ReadByteTwoRegs(I2C0, g_u8DeviceAddr, u16DataAddr) ;
                if( ret_code == 32 )
                          printf("One byte read Pass.....\n");
                else
                          printf("One byte read Failed....%d\n",ret_code);


-----------------------------------------------------------
執行結果
One byte write Pass.....
One byte read Failed....0


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
回复

使用道具

沙发
匿名  发表于 2018-7-30 13:50:58
I2C_ReadByteTwoRegs應該債你自已寫的吧。
貼上來看看
回复 支持 反对

使用道具

板凳
匿名  发表于 2018-7-31 08:37:41
在新唐所提供的Library裡
C:\Nuvoton\BSP Library\NUC126_Series_BSP_CMSIS_v3.00.002\Library\StdDriver\src\i2c.c

/**
  * @brief      Specify two bytes register address and write multi bytes to Slave
  *
  * @param[in]  *i2c            Point to I2C peripheral
  * @param[in]  u8SlaveAddr     Access Slave address(7-bit)
  * @param[in]  u16DataAddr     Specify a address (2 bytes) of data write to
  * @param[in]  *data           Pointer to array to write data to Slave
  * @param[in]  u32wLen         How many bytes need to write to Slave
  *
  * @return     A length of how many bytes have been transmitted.
  *
  * @details    The function is used for I2C Master specify a byte address that multi data write to in Slave.
  *
  */

uint32_t I2C_WriteMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const uint8_t *data, uint32_t u32wLen)
{
    uint8_t u8Xfering = 1, u8Err = 0, u8Addr = 1, u8Ctrl = 0;
    uint32_t u32txLen = 0;
   
    I2C_START(i2c);                                                         /* Send START */
    while(u8Xfering && (u8Err == 0))
    {
        I2C_WAIT_READY(i2c);
        switch(I2C_GET_STATUS(i2c))
        {
            case 0x08:
                I2C_SET_DATA(i2c, (u8SlaveAddr << 1 | 0x00));               /* Write SLA+W to Register I2CDAT */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */                 
                break;
            case 0x18:                                                      /* Slave Address ACK */
                I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF00) >> 8);    /* Write Hi byte address of register */
                break;
            case 0x20:                                                      /* Slave Address NACK */
            case 0x30:                                                      /* Master transmit data NACK */               
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;               
                break;  
            case 0x28:
                if(u8Addr)
                {
                    I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF));       /* Write Lo byte address of register */
                    u8Addr = 0;
                }
                else if((u32txLen < u32wLen) && (u8Addr == 0))
                    I2C_SET_DATA(i2c, data[u32txLen++]);                           /* Write data to Register I2CDAT*/
                else
                {
                    u8Ctrl = I2C_CTL_STO_SI;                              /* Clear SI and send STOP */
                    u8Xfering = 0;
                }                 
                break;
            case 0x38:                                                      /* Arbitration Lost */
            default:                                                        /* Unknow status */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */                  
                u8Err = 1;
                break;
        }
        I2C_SET_CONTROL_REG(i2c, u8Ctrl);                                   /* Write controlbit to I2C_CTL register */
    }
    return u32txLen;                                                        /* Return bytes length that have been transmitted */
}

/**
  * @brief      Specify two bytes register address and read multi bytes from Slave
  *
  * @param[in]  *i2c            Point to I2C peripheral
  * @param[in]  u8SlaveAddr     Access Slave address(7-bit)
  * @param[in]  u16DataAddr     Specify a address (2 bytes) of data read from
  * @param[out] *rdata          Point to array to store data from Slave
  * @param[in]  u32rLen         How many bytes need to read from Slave
  *
  * @return     A length of how many bytes have been received
  *
  * @details    The function is used for I2C Master specify two bytes address that multi data bytes read from Slave.
  *
  *
  */
uint32_t I2C_ReadMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t *rdata, uint32_t u32rLen)
{
    uint8_t u8Xfering = 1, u8Err = 0, u8Addr = 1, u8Ctrl = 0;
    uint32_t u32rxLen = 0;
  
    I2C_START(i2c);                                                         /* Send START */
    while(u8Xfering && (u8Err == 0))
    {
        I2C_WAIT_READY(i2c);
        switch(I2C_GET_STATUS(i2c))
        {
            case 0x08:
                I2C_SET_DATA(i2c, (u8SlaveAddr << 1 | 0x00));               /* Write SLA+W to Register I2CDAT */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */                 
                break;
            case 0x18:                                                      /* Slave Address ACK */
                I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF00) >> 8);    /* Write Hi byte address of register */
                break;
            case 0x20:                                                      /* Slave Address NACK */
            case 0x30:                                                      /* Master transmit data NACK */               
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;               
                break;               
            case 0x28:
                if(u8Addr)
                {
                    I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF));       /* Write Lo byte address of register */
                    u8Addr = 0;                 
                }
                else
                    u8Ctrl = I2C_CTL_STA_SI;                              /* Clear SI and send repeat START */
                break;
            case 0x10:               
                I2C_SET_DATA(i2c, ((u8SlaveAddr << 1) | 0x01));             /* Write SLA+R to Register I2CDAT */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */            
                break;
            case 0x40:                                                      /* Slave Address ACK */
                u8Ctrl = I2C_CTL_SI_AA;                                   /* Clear SI and set ACK */
                break;
            case 0x48:                                                      /* Slave Address NACK */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;               
                break;            
            case 0x50:
                rdata[u32rxLen++] = (unsigned char) I2C_GET_DATA(i2c);      /* Receive Data */
                if(u32rxLen<(u32rLen-1))
                    u8Ctrl = I2C_CTL_SI_AA;                               /* Clear SI and set ACK */
                else
                    u8Ctrl = I2C_CTL_SI;                                  /* Clear SI */
                break;              
            case 0x58:
                rdata[u32rxLen++] = (unsigned char) I2C_GET_DATA(i2c);      /* Receive Data */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */
                u8Xfering = 0;
                break;
            case 0x38:                                                      /* Arbitration Lost */
            default:                                                        /* Unknow status */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */                  
                u8Err = 1;
                break;               
        }
        I2C_SET_CONTROL_REG(i2c, u8Ctrl);                                   /* Write controlbit to I2C_CTL register */
    }
    return u32rxLen;                                                        /* Return bytes length that have been received */
}
回复 支持 反对

使用道具

地板
匿名  发表于 2018-7-31 08:42:15
貼錯了,應該在這2個副程式

/**
  * @brief      Specify two bytes register address and Write a byte to Slave
  *
  * @param[in]  *i2c            Point to I2C peripheral
  * @param[in]  u8SlaveAddr     Access Slave address(7-bit)
  * @param[in]  u16DataAddr     Specify a address (2 byte) of data write to
  * @param[in]  data            Write a byte data to Slave
  *
  * @retval     0               Write data success
  * @retval     1               Write data fail, or bus occurs error events
  *
  * @details    The function is used for I2C Master specify two bytes address that data write to in Slave.
  *
  */

uint8_t I2C_WriteByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const uint8_t data)
{
    uint8_t u8Xfering = 1, u8Err = 0, u8Addr = 1, u8Ctrl = 0;
    uint32_t u32txLen = 0;
  
    I2C_START(i2c);                                                         /* Send START */
    while(u8Xfering && (u8Err == 0))
    {
        I2C_WAIT_READY(i2c);
        switch(I2C_GET_STATUS(i2c))
        {
            case 0x08:
                I2C_SET_DATA(i2c, (u8SlaveAddr << 1 | 0x00));               /* Write SLA+W to Register I2CDAT */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */
                break;
            case 0x18:                                                      /* Slave Address ACK */
                I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF00) >> 8);    /* Write Hi byte address of register */
                break;
            case 0x20:                                                      /* Slave Address NACK */
            case 0x30:                                                      /* Master transmit data NACK */               
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;               
                break;              
            case 0x28:
                if(u8Addr)
                {
                    I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF));       /* Write Lo byte address of register */
                    u8Addr = 0;
                }
                else if((u32txLen < 1) && (u8Addr == 0))
                {
                    I2C_SET_DATA(i2c, data);
                    u32txLen++;
                }
                else
                {
                    u8Ctrl = I2C_CTL_STO_SI;                              /* Clear SI and send STOP */
                    u8Xfering = 0;
                }
                break;
            case 0x38:                                                      /* Arbitration Lost */
            default:                                                        /* Unknow status */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */                  
                u8Err = 1;
                break;
        }
        I2C_SET_CONTROL_REG(i2c, u8Ctrl);                                   /* Write controlbit to I2C_CTL register */  
    }
    return (u8Err | u8Xfering);                                             /* return (Success)/(Fail) status */
}


/**
  * @brief      Specify two bytes register address and read a byte from Slave
  *
  * @param[in]  *i2c            Point to I2C peripheral
  * @param[in]  u8SlaveAddr     Access Slave address(7-bit)
  * @param[in]  u16DataAddr     Specify a address(2 byte) of data read from
  *
  * @return     Read a byte data from Slave
  *
  * @details    The function is used for I2C Master specify two bytes address that a data byte read from Slave.
  *
  *
  */
uint8_t I2C_ReadByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr)
{
    uint8_t u8Xfering = 1, u8Err = 0, rdata = 0, u8Addr = 1, u8Ctrl = 0;

    I2C_START(i2c);                                                         /* Send START */
    while(u8Xfering && (u8Err == 0))
    {
        I2C_WAIT_READY(i2c);      
        switch(I2C_GET_STATUS(i2c))
        {
            case 0x08:
                I2C_SET_DATA(i2c, (u8SlaveAddr << 1 | 0x00));               /* Write SLA+W to Register I2CDAT */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */                  
                break;
            case 0x18:                                                      /* Slave Address ACK */
                I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF00) >> 8);    /* Write Hi byte address of register */
                break;
            case 0x20:                                                      /* Slave Address NACK */
            case 0x30:                                                      /* Master transmit data NACK */               
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;               
                break;               
            case 0x28:
                if(u8Addr)
                {
                    I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF));       /* Write Lo byte address of register */
                    u8Addr = 0;
                }
                else            
                    u8Ctrl = I2C_CTL_STA_SI;                              /* Clear SI and send repeat START */
                break;
            case 0x10:           
                I2C_SET_DATA(i2c, ((u8SlaveAddr << 1) | 0x01));             /* Write SLA+R to Register I2CDAT */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */                  
                break;
            case 0x40:                                                      /* Slave Address ACK */
                u8Ctrl = I2C_CTL_SI;                                      /* Clear SI */
                break;
            case 0x48:                                                      /* Slave Address NACK */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;               
                break;            
            case 0x58:
                rdata = (unsigned char) I2C_GET_DATA(i2c);                  /* Receive Data */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */
                u8Xfering = 0;
                break;
            case 0x38:                                                      /* Arbitration Lost */
            default:                                                        /* Unknow status */
                u8Ctrl = I2C_CTL_STO_SI;                                  /* Clear SI and send STOP */               
                u8Err = 1;
                break;
        }
        I2C_SET_CONTROL_REG(i2c, u8Ctrl);                                   /* Write controlbit to I2C_CTL register */
    }
    if(u8Err)
        rdata = 0;                                                          /* If occurs error, return 0 */   
    return rdata;                                                           /* Return read data */
}


回复 支持 反对

使用道具

5#
匿名  发表于 2018-7-31 09:12:24
你连接的元器件是那一颗,规格书贴上来看一下。
回复 支持 反对

使用道具

6#
匿名  发表于 2018-7-31 09:37:14
連接的元件是24LC64

所使用的環境是
去新唐上課所發的電路板
NuTiny-SDK-NUC126
以及
NuTiny-SDK-M0564-Daughter Board V1.0

回复 支持 反对

使用道具

7#
匿名  发表于 2018-7-31 15:56:05
在bsp裡面有個sample code
\NUC126Series_BSP_CMSIS_v3.00.003\NUC126BSPv3.00.003\SampleCode\StdDriver\I2C_EEPROM\KEIL
先看看是可以跑通過。
回复 支持 反对

使用道具

8#
匿名  发表于 2018-7-31 17:07:45
測試一下,write跟讀的時侯,中間要插個delay.太快eeprom反應不及
/**************************************************************************//**
* @file     main.c
* @version  V3.00
* $Revision: 2 $
* $Date: 16/10/25 4:29p $
* @brief    Show how to use I2C interface to access EEPROM.
* @note
* Copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "NUC126.h"

#define PLLCTL_SETTING  CLK_PLLCTL_72MHz_HXT
#define PLL_CLOCK       72000000


/*---------------------------------------------------------------------------------------------------------*/
/* Global variables                                                                                        */
/*---------------------------------------------------------------------------------------------------------*/



void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC 22.1184MHz clock */
    CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

    /* Waiting for Internal RC clock ready */
    CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

    /* Enable external XTAL 12MHz clock */
    CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

    /* Waiting for external XTAL clock ready */
    CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Enable I2C0 module clock */
    CLK_EnableModuleClock(I2C0_MODULE);

    /* Select UART module clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));


    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set PD multi-function pins for UART0 RXD and TXD */
    SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD0MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk);
    SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD0MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_UART0_TXD);

    /* Set PD multi-function pins for I2C0 SDA and SCL */
    SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD4MFP_Msk | SYS_GPD_MFPL_PD5MFP_Msk);
    SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD4MFP_I2C0_SDA | SYS_GPD_MFPL_PD5MFP_I2C0_SCL);
}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}



void I2C0_Init(void)
{
    /* Open I2C module and set bus clock */
    I2C_Open(I2C0, 100000);

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


}
volatile uint8_t g_u8DeviceAddr;
volatile uint32_t ret_code;
volatile uint16_t u16DataAddr;
/*---------------------------------------------------------------------------------------------------------*/
/*  Main Function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();


    printf("I2C0_SDA(PD.4), I2C0_SCL(PD.5)\n");

    /* Init I2C0 to access EEPROM */
    I2C0_Init();
g_u8DeviceAddr = 0x50;
u16DataAddr = 0x0010;
I2C_WriteByteTwoRegs(I2C0, g_u8DeviceAddr, u16DataAddr,  0xaa) ;
CLK_SysTickDelay(20000);
ret_code=I2C_ReadByteTwoRegs(I2C0, g_u8DeviceAddr, u16DataAddr) ;

    while(1);
}



回复 支持 反对

使用道具

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU