打印
[DemoCode下载]

MG51 I2C使用方法

[复制链接]
391|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huahuagg|  楼主 | 2023-12-16 17:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* SPDX-License-Identifier: Apache-2.0                                                                     */
/* Copyright(c) 2023 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/


//***********************************************************************************************************
//  File Function: MG51 I2C master mode demo code, the Slave address = 0xA4
//
//   ____________            _____________
//  |            |   SDA    |             |
//  |            |<-------->|             |
//  |            |          |             |
//  |MG51(M)     |          | MG51(S)     |
//  |(I2C_Master)|          | (I2C_Slave) |
//  |            |   SCL    |             |
//  |            |--------->|             |
//  |____________|          |_____________|
//
//  The protocol of I2C is master: start -> write 10 byte(ACK) ->stop -> start ->read 10 byte(ACK) -> stop
//  Setting break point in I2C slave to check time out function
//***********************************************************************************************************


#include "MG51.H"


#define I2C_CLOCK                 14
#define I2C_SLAVE_ADDRESS         0xA4
#define I2C_WR                    0
#define I2C_RD                    1

#define LOOP_SIZE                 10
BIT   i2cErrorFlag=0;


void I2C_ISR(void) interrupt 6
{
   if (I2TOC&SET_BIT0)
      while(1);                     /* When into this loop means I2C transmit time out */
}
//========================================================================================================
void Init_I2C(void)
{
    P13_OPENDRAIN_MODE;          // Modify SCL pin to Open drain mode. don't forget the pull high resister in circuit
    P14_OPENDRAIN_MODE;          // Modify SDA pin to Open drain mode. don't forget the pull high resister in circuit

    P13_ST_ENABLE;
    P14_ST_ENABLE;

    /* Set I2C clock rate */
    I2CLK = I2C_CLOCK;
   /* Enable I2C time out divier as clock base is Fsys/4, the time out is about 4ms when Fsys = 16MHz */
    set_I2TOC_DIV;
    clr_I2TOC_I2TOF;
   /* Enable I2C intterupt for I2C time out */
    set_EIE_EI2C;                               //enable I2C interrupt by setting IE1 bit 0
    set_IE_EA;

    /* Enable I2C */
    set_I2CON_I2CEN;
}
//========================================================================================================
void I2C_Error(void)
{
    while (1);
}
//========================================================================================================

//--------------------------------------------------------------------------------------------
//----  Page Write----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
void I2C_Write_Process(UINT8 u8DAT)
{
    unsigned char  u8Count;

    set_I2TOC_I2TOCEN;                           /* Enable I2C time out */

    /* Write Step1 */
    set_I2CON_STA;                              /* Send Start bit to I2C EEPROM */
    clr_I2CON_SI;
    while (!SI);                                /*Check SI set or not  */
    if (I2STAT != 0x08)                         /*Check status value after every step   */
    {
        i2cErrorFlag=1;
        goto I2CWRSTOP;
    }
   
    /* Write Step2 */
    clr_I2CON_STA;                              /*STA=0*/
    I2DAT = (I2C_SLAVE_ADDRESS | I2C_WR);
    clr_I2CON_SI;
    while (!SI);                                /*Check SI set or not */
    if (I2STAT != 0x18)
    {
        i2cErrorFlag=1;
        goto I2CWRSTOP;
    }

    /* Write Step3 */
    for (u8Count = 0; u8Count < LOOP_SIZE; u8Count++)
    {
        I2DAT = u8DAT;
        clr_I2CON_SI;
        while (!SI);                            /*Check SI set or not*/
        if (I2STAT != 0x28)
        {
            i2cErrorFlag=1;
            goto I2CWRSTOP;
        }
        u8DAT = ~u8DAT;
    }

    /* Write Step4 */
    I2CWRSTOP:
    set_I2CON_STO;
    clr_I2CON_SI;
    while (STO);                                /* Check STOP signal */
    if  (i2cErrorFlag)
    {
      printf ("\n I2C write error !");
    }
  }
  
//--------------------------------------------------------------------------------------------
//----  Page Read ----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
void I2C_Read_Process(UINT8 u8DAT)
{
    unsigned char  u8Count;
    /* Read Step1 */
    set_I2CON_STA;
    clr_I2CON_SI;         
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x08)                         //Check status value after every step
    {
        i2cErrorFlag=1;
        goto I2CRDSTOP;
    }

    /* Step13 */
    clr_I2CON_STA;                                    //STA needs to be cleared after START codition is generated
    I2DAT = (I2C_SLAVE_ADDRESS | I2C_RD);
    clr_I2CON_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x40)              
    {
        i2cErrorFlag=1;
        goto I2CRDSTOP;
    }
   
    /* Step14 */
    for (u8Count = 0; u8Count <LOOP_SIZE; u8Count++)
    {
        set_I2CON_AA;
        clr_I2CON_SI;        
        while (!SI);                            //Check SI set or not
        if (I2STAT != 0x50)
        {
            i2cErrorFlag=1;
            goto I2CRDSTOP;
        }
        if (I2DAT != u8DAT)
        {
            i2cErrorFlag=1;
            goto I2CRDSTOP;
        }
        u8DAT = ~u8DAT;
    }
   
    /* Step15 */
    clr_I2CON_AA;
    clr_I2CON_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x58)
    {
        i2cErrorFlag=1;
        goto I2CRDSTOP;
    }

    /* Step16 */
    I2CRDSTOP:
    set_I2CON_STO;
    clr_I2CON_SI;
    while (STO);                                /* Check STOP signal */
    {
      printf ("\n I2C read error !");
    }
}
//========================================================================================================
void main(void)
{
    /* UART0 settting for printf function */
    MODIFY_HIRC(HIRC_24);
    Enable_UART0_VCOM_printf_24M_115200();
    printf ("\n Test start ...");

    Init_I2C();                                 /* initial I2C circuit  */
    I2C_Write_Process(0x55);                    /* I2C Master will send 10 byte 0x55,0xAA,.... to slave */
    I2C_Read_Process(0x55);

    while (1);
/* =================== */
}



使用特权

评论回复
沙发
21mengnan| | 2023-12-17 11:35 | 只看该作者
clr_I2CON_SI 这个SI是什么。

使用特权

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

本版积分规则

139

主题

1254

帖子

2

粉丝