<th id="alkcr"><pre id="alkcr"></pre></th>

  • 打印

    [綜合信息] 【HC32L136 demo板】+軟件模擬I2C時序讀寫24C04

    [復制鏈接]
    129|2
    跳轉到指定樓層
    樓主
    今晚搞了一下軟件模擬I2C時序讀寫24C04,終于成功了。
    代碼:
    #include "gpio.h"

    /******************************************************************************
    * Local pre-processor symbols/macros ('#define')
    ******************************************************************************/

    /******************************************************************************
    * Global variable definitions (declared in header file with 'extern')
    ******************************************************************************/
    #define uchar unsigned char
    #define uint unsigned int
    /******************************************************************************
    * Local type definitions ('typedef')
    ******************************************************************************/
    stc_gpio_config_t pstcGpioCfg;
    /******************************************************************************
    * Local function prototypes ('static')
    ******************************************************************************/

    /******************************************************************************
    * Local variable definitions ('static')                                      *
    ******************************************************************************/

    /******************************************************************************
    * Local pre-processor symbols/macros ('#define')
    ******************************************************************************/



    #define SDA_0           Gpio_ClrIO(GpioPortA, GpioPin12)
    #define SDA_1           Gpio_SetIO(GpioPortA, GpioPin12)
    #define SCL_0           Gpio_ClrIO(GpioPortA, GpioPin11)
    #define SCL_1           Gpio_SetIO(GpioPortA, GpioPin11)

    #define SDA             Gpio_GetInputIO(GpioPortA, GpioPin12)

    /*****************************************************************************
    * Function implementation - global ('extern') and local ('static')
    ******************************************************************************/
    unsigned char buffer[3];

    /****************************************************************************
    * 名    稱: DelayMS()
    * 功    能: 以毫秒為單位延時,系統時鐘不配置時默認為16M(用示波器測量相當精確)
    * 入口參數: msec 延時參數,值越大,延時越久
    * 出口參數: 無
    ****************************************************************************/
    void DelayMS(uint msec)
    {
        uint i,j;

        for (i=0; i<msec; i++)
            for (j=0; j<535; j++);
    }

    void InitSDAInput(void)
    {
         ///< 端口方向配置->輸入
        pstcGpioCfg.enDir = GpioDirIn;
        ///< 端口驅動能力配置->高驅動能力
        pstcGpioCfg.enDrv = GpioDrvH;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出關閉
        pstcGpioCfg.enOD = GpioOdDisable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;


        Gpio_Init(GpioPortA, GpioPin12, &pstcGpioCfg);

    }
    void InitSDAOutputH(void)
    {
        ///< 端口方向配置->輸出
        pstcGpioCfg.enDir = GpioDirOut;
        ///< 端口驅動能力配置->高驅動能力
        pstcGpioCfg.enDrv = GpioDrvH;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出使能
        pstcGpioCfg.enOD = GpioOdEnable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;



                    Gpio_Init(GpioPortA, GpioPin12, &pstcGpioCfg);                        //SDA

    }
    void InitSDAOutputL(void)
    {
        ///< 端口方向配置->輸出
        pstcGpioCfg.enDir = GpioDirOut;
        ///< 端口驅動能力配置->高驅動能力
        pstcGpioCfg.enDrv = GpioDrvL;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出使能
        pstcGpioCfg.enOD = GpioOdEnable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;



                    Gpio_Init(GpioPortA, GpioPin12, &pstcGpioCfg);                        //SDA

    }
    //-----------------------------------------------------------------------------------------
    //函數名稱:Delay()
    //功    能:延時子程序
    //-----------------------------------------------------------------------------------------
    void Delay(unsigned char us)  //5,7,9
    {
            char i;
      while(--us)
            {
                    for(i=0;i<25;i++);  
            }
    }

    //-----------------------------------------------------------------------------------------
    //函數名稱:Delayms()
    //-----------------------------------------------------------------------------------------
    void Delayms(unsigned int ims)
    {
      unsigned int i,j;
        for(i=0;i<ims;i++)
          for(j=0;j<265;j++) { Delay(1); }
    }

    void Start()
    {
            SCL_0;
      InitSDAOutputH();
      SDA_1;
            Delay(5);
            SCL_1;
            Delay(5);
            InitSDAOutputL();
      SDA_0;
            Delay(5);
      SCL_0;
            Delay(5);
    }
           
    void Stop()
    {
            SCL_0;
            InitSDAOutputL();
      SDA_0;
            Delay(5);
      SCL_1;
            Delay(5);
            InitSDAOutputH();
      SDA_1;
            Delay(5);
    }

           
           
           
    char ACK ()
    {

      char c,i=0;
            InitSDAOutputH();
      SDA_1;
            Delay(5);
            SCL_0;
            Delay(5);
      SCL_1;
            Delay(5);
      InitSDAInput();
            Delay(5);
    //  if(SDA==1)
    //    c=1;
    //  else
    //    c=0;
            while(SDA==1)
            {
                    i++;
                    if(i>100)
                            break;
            }
    // InitSDAOutput();
            Delay(5);
      SCL_0;

      return c;

    }

    void NOACK()//·?ó|′eD?o?
    {
            InitSDAOutputH();
            SDA_1;
            SCL_0;
            Delay(5);
            SCL_1;
            Delay(5);
            SCL_0;
            Delay(5);
    }

    void SendChar(unsigned char ch)

    {

      unsigned char i;

      i=8;

      do

      {
        if(ch&0x80)
                    {
                            InitSDAOutputH();
          SDA_1;
                    }
        else
                    {
                            InitSDAOutputL();
          SDA_0;
                    }
                    Delay(5);
        SCL_1;
                    Delay(5);
        SCL_0;
                    Delay(5);
        ch<<=1;

      }while(--i!=0);

    }
    unsigned char RecChar()

    {

      unsigned char i,j;

      i=8;
      j=0;
            InitSDAInput();
      do

      {

        SCL_1;
                    Delay(5);
        j=(j<<1);
        if(SDA==1)
          j=j|1;
                    Delay(5);
        SCL_0;
                    Delay(5);
      }while(--i!=0);

      return j;

    }

    void WriteChar(unsigned int addr,unsigned char ch)

    {

      unsigned char c;

      c=((*((unsigned char *)&addr))<<1)&0x02;

      Start();

      SendChar(0xa0|c);

      ACK();

      SendChar(addr);

      ACK();

      SendChar(ch);

      ACK();
      Stop();

      for(ch=0xff;ch!=0;ch--) ;

    }

    unsigned char ReadChar(unsigned int addr)

    {

      unsigned char ch;

      ch=((*((unsigned char *)&addr))<<1)&0x02;

      Start();

      SendChar(0xa0|ch);

      ACK();

      SendChar(addr);

      ACK();

      Start();

      SendChar(0xa1|ch);

      ACK();

      ch=RecChar();
            NOACK();
      Stop();

      return ch;

    }
    /**
    ******************************************************************************
    ** \brief  Main function of project
    **
    ** \return uint32_t return value, if needed
    **
    ** This sample
    **
    ******************************************************************************/
    int32_t main(void)
    {


        ///< 打開GPIO外設時鐘門控
        Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

        ///< 端口方向配置->輸出
        pstcGpioCfg.enDir = GpioDirOut;
        ///< 端口驅動能力配置->高驅動能力
        pstcGpioCfg.enDrv = GpioDrvH;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出使能
        pstcGpioCfg.enOD = GpioOdEnable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;



                    //Gpio_Init(GpioPortA, GpioPin12, &pstcGpioCfg);                        //SDA
        Gpio_Init(GpioPortA, GpioPin11, &pstcGpioCfg);                        //SCL
                    //InitSDAOutput();
                    buffer[0]=ReadChar(0);
        Delay(100);           //延時一段時間
        WriteChar(0,0x55);
        Delayms(20);
        WriteChar(1,0xaa);
        Delayms(20);
        WriteChar(2,0x27);
        Delayms(20);
        buffer[0]=ReadChar(1);
        buffer[1]=ReadChar(2);
        buffer[2]=ReadChar(0);
        while(1)
        {
                                   
                                   
        }
    }

    效果圖:

    可是發現一個問題,PA12不好拉低,而PA11就可以。
    PA11初始化:
    ///< 打開GPIO外設時鐘門控
        Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

        ///< 端口方向配置->輸出
        pstcGpioCfg.enDir = GpioDirOut;
        ///< 端口驅動能力配置->高驅動能力
        pstcGpioCfg.enDrv = GpioDrvH;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出使能
        pstcGpioCfg.enOD = GpioOdEnable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;



                   
        Gpio_Init(GpioPortA, GpioPin11, &pstcGpioCfg);                        //SCL

    這樣可以正常拉高拉低。
    可是PA12則不行。
    我搞了一下,找了個不太好的辦法。
    拉高之前這么初始化:
    void InitSDAOutputH(void)
    {
        ///< 端口方向配置->輸出
        pstcGpioCfg.enDir = GpioDirOut;
        ///< 端口驅動能力配置->高驅動能力
        pstcGpioCfg.enDrv = GpioDrvH;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出使能
        pstcGpioCfg.enOD = GpioOdEnable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;



                    Gpio_Init(GpioPortA, GpioPin12, &pstcGpioCfg);                        //SDA

    }
    拉低之前這么初始化:

    void InitSDAOutputL(void)
    {
        ///< 端口方向配置->輸出
        pstcGpioCfg.enDir = GpioDirOut;
        ///< 端口驅動能力配置->低驅動能力
        pstcGpioCfg.enDrv = GpioDrvL;
        ///< 端口上下拉配置->無上下拉
        pstcGpioCfg.enPuPd =  GpioNoPuPd;
        ///< 端口開漏輸出配置->開漏輸出使能
        pstcGpioCfg.enOD = GpioOdEnable;
        ///< 端口輸入/輸出值寄存器總線控制模式配置->AHB
        pstcGpioCfg.enCtrlMode = GpioAHB;



                    Gpio_Init(GpioPortA, GpioPin12, &pstcGpioCfg);                        //SDA

    }

    就可以了。
    不明白為什么。
    請大神指教,謝謝!

    使用特權

    評論回復
    沙發
    | 2019-9-30 23:35 | 只看該作者
    樓主void InitSDAOutputH(void)和void InitSDAOutputL(void)是要初始化IO引腳并且初始化成高電平和低電平嗎?
    在上電后設置未輸出的時候,需要先設置輸出電平,再設置輸出方向,這樣才有初始化為指定的高電平或者低電平。
    比如調用void InitSDAOutputL(void)之前,需要設置輸出低:Gpio_ClrIO(GpioPortA, GpioPin12);或者Gpio_WriteOutputIO(GpioPortA, GpioPin12, FALSE);
    pstcGpioCfg.enDrv; //這個設置驅動能力,是指引腳上的拉電流和灌電流的能力(強驅或者弱驅能力),不是指輸出高低電平的意思。

    使用特權

    評論回復
    板凳
    | 2019-10-3 10:34 | 只看該作者
    謝謝分享!

    使用特權

    評論回復
    掃描二維碼,隨時隨地手機跟帖
    您需要登錄后才可以回帖 登錄 | 注冊

    本版積分規則

    我要發帖 投訴建議 創建版塊 申請版主

    快速回復

    您需要登錄后才可以回帖
    登錄 | 注冊
    高級模式

    論壇熱帖

    在線客服 快速回復 返回頂部 返回列表
    成人短片线上看