xld0932 发表于 2022-7-29 15:07

【国民技术低功耗系列N32L43x测评】08.软硬件I2C驱动1.5寸16色灰度OLED显示

<p><span style="color:#e74c3c;"><strong>概述</strong></span></p>

<p>国民N32L43x系列MCU带有2路硬件I2C接口,它提供多主机功能,控制所有I2C总线特定的时序、协议、仲裁和定时。支持多种通信模式(最高支持1MHz),支持DMA操作,同时与SMBus2.0兼容。主要功能描述如下:</p>

<p align="justify" style="">多主机功能:该模块既可做主设备也可做从设备;</p>

<ul>
        <li align="justify" style="">I2C主设备功能;</li>
        <li align="justify" style="">产生时钟;</li>
        <li align="justify" style="">产生起始和停止信号;</li>
        <li align="justify" style="">I2C从设备功能</li>
        <li align="justify" style="">可编程的地址检测;</li>
        <li align="justify" style="">I2C接口支持7位或10位寻址,7位从模式时支持双从地址响应能力;</li>
        <li align="justify" style="">停止位检测;</li>
        <li align="justify" style="">产生和检测7位/10位地址和广播呼叫;</li>
        <li align="justify" style="">支持不同的通讯速度;</li>
</ul>

<ol>
        <li>标准速度(高达100 kHz);</li>
        <li>快速(高达400 kHz);</li>
        <li>快速+(高达1MHz);</li>
</ol>

<ul>
        <li align="justify" style="">状态标志:</li>
</ul>

<ol>
        <li align="justify" style="">发送器/接收器模式标志;</li>
        <li align="justify" style="">字节发送结束标志;</li>
        <li align="justify" style="">I2C总线忙标志;</li>
</ol>

<ul>
        <li align="justify" style="">错误标志:</li>
</ul>

<ol>
        <li align="justify" style="">主模式时的仲裁丢失;</li>
        <li align="justify" style="">地址/数据传输后的应答(ACK)错误;</li>
        <li align="justify" style="">检测到错误的起始或停止条件;</li>
        <li align="justify" style="">禁止拉长时钟功能时的上溢或下溢;</li>
</ol>

<ul>
        <li align="justify" style="">2个中断向量:</li>
</ul>

<ol>
        <li align="justify" style="">1个中断用于地址/数据通讯成功;</li>
        <li align="justify" style="">1个中断用于错误;</li>
</ol>

<ul>
        <li align="justify" style="">可选的拉长时钟功能</li>
        <li align="justify" style="">单字节缓冲器的DMA;</li>
        <li align="justify" style="">可配置的PEC(信息包错误检测)的产生或校验</li>
        <li align="justify" style="">发送模式中PEC值可以作为最后一个字节传输</li>
        <li align="justify" style="">用于最后一个接收字节的PEC错误校验</li>
        <li align="justify" style="">兼容SMBus 2.0</li>
</ul>

<ol>
        <li align="justify" style="">25 ms时钟低超时延时</li>
        <li align="justify" style="">10 ms主设备累积时钟低扩展时间</li>
        <li align="justify" style="">25 ms从设备累积时钟低扩展时间</li>
        <li align="justify" style="">带ACK控制的硬件PEC产生/校验</li>
        <li align="justify" style="">支持地址分辨协议(ARP)</li>
</ol>

<ul>
        <li align="justify" style="">兼容SMBus</li>
</ul>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style=""><strong><span style="color:#e74c3c;">16灰OLED</span></strong></p>

<p align="justify" style="">一般OLED都是单色显示的,一个0.96寸128*64像素的OLED,一个像素只需要1位来表示,其显存也就1024字节,能过I2C的400kbps的通讯速率很容易就达到流畅的效果;但对于16灰的OLED来说,一个像素需要有4位来表示,本文中用到的1.5寸16灰OLED其像素达到128*128,这样显存就需要8KB的空间,如果还使用400kbps的速率来刷新显示的话,就会明显感觉到卡顿/不流畅。正好国民N32L43x系列MCU的硬件I2C支持快速+模式,通讯速率可以达到1MHz,完全满足这款OLED的显示刷新需求。</p>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style=""><span style="color:#e74c3c;"><strong>代码实现</strong></span></p>

<pre>
<code class="language-cpp">/* Define to prevent recursive inclusion -------------------------------------*/
#define __OLED_C__


/* Includes ------------------------------------------------------------------*/
#include "OLED.h"


#if ENABLE_OLED


/* Private typedef -----------------------------------------------------------*/


/* Private define ------------------------------------------------------------*/
#define sI2C_SCL_PORTGPIOB
#define sI2C_SCL_PIN   GPIO_PIN_8

#define sI2C_SDA_PORTGPIOB
#define sI2C_SDA_PIN   GPIO_PIN_9


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/


/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/


/*******************************************************************************
* @brief * @param      
* @retval      
* @attention *******************************************************************************/
void sI2C_Delay(uint32_t t)
{
    while(t--);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void sI2C_Init(void)
{
    GPIO_InitType GPIO_InitStructure;

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);

    GPIO_InitStruct(&amp;GPIO_InitStructure);
    GPIO_InitStructure.Pin            = GPIO_PIN_8 | GPIO_PIN_9;
    GPIO_InitStructure.GPIO_Current   = GPIO_DC_12mA;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pull      = GPIO_Pull_Up;          
    GPIO_InitPeripheral(GPIOB, &amp;GPIO_InitStructure);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void sI2C_SDA_IN(void)
{
    GPIO_InitType GPIO_InitStructure;

    GPIO_InitStruct(&amp;GPIO_InitStructure);
    GPIO_InitStructure.Pin            = GPIO_PIN_9;
    GPIO_InitStructure.GPIO_Current   = GPIO_DC_12mA;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_Input;
    GPIO_InitStructure.GPIO_Pull      = GPIO_Pull_Up;          
    GPIO_InitPeripheral(GPIOB, &amp;GPIO_InitStructure);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void sI2C_SDA_OUT(void)
{
    GPIO_InitType GPIO_InitStructure;

    GPIO_InitStruct(&amp;GPIO_InitStructure);
    GPIO_InitStructure.Pin            = GPIO_PIN_9;
    GPIO_InitStructure.GPIO_Current   = GPIO_DC_12mA;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pull      = GPIO_Pull_Up;          
    GPIO_InitPeripheral(GPIOB, &amp;GPIO_InitStructure);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void sI2C_START(void)
{
    sI2C_SDA_OUT();
    GPIO_WriteBit(sI2C_SDA_PORT, sI2C_SDA_PIN, Bit_SET);    sI2C_Delay(10);
    GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_SET);    sI2C_Delay(10);
    GPIO_WriteBit(sI2C_SDA_PORT, sI2C_SDA_PIN, Bit_RESET);sI2C_Delay(10);
    GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_RESET);sI2C_Delay(10);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void sI2C_STOP(void)
{
    sI2C_SDA_OUT();
    GPIO_WriteBit(sI2C_SDA_PORT, sI2C_SDA_PIN, Bit_RESET);sI2C_Delay(10);
    GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_SET);    sI2C_Delay(10);
    GPIO_WriteBit(sI2C_SDA_PORT, sI2C_SDA_PIN, Bit_SET);    sI2C_Delay(10);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
uint8_t sI2C_WaitACK(void)
{
    uint32_t Timeout = 0;

    GPIO_WriteBit(sI2C_SDA_PORT, sI2C_SDA_PIN, Bit_SET);    /* 释放总线 */

    sI2C_SDA_IN();
    sI2C_Delay(5);

    GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_SET);    sI2C_Delay(5);

    while(GPIO_ReadInputDataBit(sI2C_SDA_PORT,sI2C_SDA_PIN))
    {
      if(Timeout++ &gt; 250)
      {
            sI2C_STOP(); return 1;
      }
    }

    GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_RESET);sI2C_Delay(5);

    return 0;
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void sI2C_SendData(uint8_t Data)
{
    sI2C_SDA_OUT();
    GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_RESET);

    for(uint8_t i = 0; i &lt; 8; i++)
    {
      if(Data &amp; (0x80 &gt;&gt; i))
      {
            GPIO_WriteBit(sI2C_SDA_PORT, sI2C_SDA_PIN, Bit_SET);
      }
      else
      {
            GPIO_WriteBit(sI2C_SDA_PORT,sI2C_SDA_PIN, Bit_RESET);
      }

      sI2C_Delay(5);

      GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_SET);    sI2C_Delay(5);
      GPIO_WriteBit(sI2C_SCL_PORT, sI2C_SCL_PIN, Bit_RESET);sI2C_Delay(5);
    }
}


#define USE_H_I2C   0


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_InitI2C(void)
{
#if USE_H_I2C
    GPIO_InitType GPIO_InitStructure;
    I2C_InitTypeI2C1_InitStructure;

    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C1,ENABLE);

    I2C_DeInit(I2C1);

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_AFIO,ENABLE);

    /*PB8 -- SCL; PB9 -- SDA*/
    GPIO_InitStruct(&amp;GPIO_InitStructure);
    GPIO_InitStructure.Pin            = GPIO_PIN_8 | GPIO_PIN_9;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
    GPIO_InitStructure.GPIO_Pull      = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF4_I2C1;
    GPIO_InitPeripheral(GPIOB, &amp;GPIO_InitStructure);

    I2C_InitStruct(&amp;I2C1_InitStructure);
    I2C1_InitStructure.ClkSpeed    = 100000;
    I2C1_InitStructure.BusMode   = I2C_BUSMODE_I2C;
    I2C1_InitStructure.FmDutyCycle = I2C_FMDUTYCYCLE_2;
    I2C1_InitStructure.OwnAddr1    = 0xFF;
    I2C1_InitStructure.AckEnable   = I2C_ACKEN;
    I2C1_InitStructure.AddrMode    = I2C_ADDR_MODE_7BIT;
    I2C_Init(I2C1, &amp;I2C1_InitStructure);

    I2C_Enable(I2C1, ENABLE);
#else
    sI2C_Init();
#endif
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_WriteCMD(uint8_t Data)
{
#if USE_H_I2C
    while(I2C_GetFlag(I2C1, I2C_FLAG_BUSY));

    I2C_GenerateStart(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_MODE_FLAG));

    I2C_SendAddr7bit(I2C1, 0x78, I2C_DIRECTION_SEND);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_TXMODE_FLAG));

    I2C_SendData(I2C1, 0x00);
    while (!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));

    I2C_SendData(I2C1, Data);
    while (!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));

    I2C_GenerateStop(I2C1, ENABLE);
#else
        sI2C_START();

        sI2C_SendData(0x78);
        sI2C_WaitACK();

        sI2C_SendData(0x00);
        sI2C_WaitACK();

        sI2C_SendData(Data);
        sI2C_WaitACK();

        sI2C_STOP();
#endif
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_WriteDAT(uint8_t Data)
{
#if USE_H_I2C
    while(I2C_GetFlag(I2C1, I2C_FLAG_BUSY));

    I2C_GenerateStart(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_MODE_FLAG));

    I2C_SendAddr7bit(I2C1, 0x78, I2C_DIRECTION_SEND);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_TXMODE_FLAG));

    I2C_SendData(I2C1, 0x40);
    while (!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));

    I2C_SendData(I2C1, Data);
    while (!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));

    I2C_GenerateStop(I2C1, ENABLE);
#else
        sI2C_START();

        sI2C_SendData(0x78);
        sI2C_WaitACK();

        sI2C_SendData(0x40);
        sI2C_WaitACK();

        sI2C_SendData(Data);
        sI2C_WaitACK();

        sI2C_STOP();
#endif
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_WriteBuffer(const uint8_t *Buffer, uint32_t Length)
{
#if USE_H_I2C
    while(I2C_GetFlag(I2C1, I2C_FLAG_BUSY));

    I2C_GenerateStart(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_MODE_FLAG));         // EV5

    I2C_SendAddr7bit(I2C1, 0x78, I2C_DIRECTION_SEND);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_TXMODE_FLAG));       // EV6

    I2C_SendData(I2C1, 0x40);
    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDING));      // EV8

    while(Length--)
    {
      I2C_SendData(I2C1, *Buffer++);
      while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDING));// EV8
    }

    while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));       // EV8-2

    I2C_GenerateStop(I2C1, ENABLE);
#else
    sI2C_START();

    sI2C_SendData(0x78);
    sI2C_WaitACK();

    sI2C_SendData(0x40);
    sI2C_WaitACK();

    while(Length--)
    {
      sI2C_SendData(*Buffer++);
      sI2C_WaitACK();
    }

    sI2C_STOP();
#endif
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_InitCFG(void)
{
    OLED_WriteCMD(0xAE);//关闭显示
       
        OLED_WriteCMD(0x15);//设置列地址
        OLED_WriteCMD(0x00);//起始地址00
        OLED_WriteCMD(0x3F);//结束列地址3F对应127列,每8列一组
       
        OLED_WriteCMD(0x75);//设置行地址
        OLED_WriteCMD(0x00);        //起始0
        OLED_WriteCMD(0x7F);        //结束127
       
        OLED_WriteCMD(0x81);//对比度设置
    OLED_WriteCMD(0x80);//1~255;默认0x7F (亮度设置,越大越亮)
       
        OLED_WriteCMD(0xA0);//显存映射
        OLED_WriteCMD(0x51);
       
        OLED_WriteCMD(0xA1);//显示起始行地址
        OLED_WriteCMD(0x00);
       
        OLED_WriteCMD(0xA2);//显示偏移
        OLED_WriteCMD(0x00);
       
        OLED_WriteCMD(0xA4);//正常显示模式
       
        OLED_WriteCMD(0xA8);//设置MUX 比率 16-128
        OLED_WriteCMD(0x7F);
       
        OLED_WriteCMD(0xB1);// Set phase length
        OLED_WriteCMD(0xF1);
       
        OLED_WriteCMD(0xB3); // Set Display Clock Divide Ratio/Oscillator Frequency
        OLED_WriteCMD(0x00); // 80Hz:0xc1 90Hz:0xe1 100Hz:0x00 110Hz:0x30 // 120Hz:0x50 130Hz:0x70
       
        OLED_WriteCMD(0xAB);
        OLED_WriteCMD(0x01);// set vdd internal
       
        OLED_WriteCMD(0xB6); // Set second pre-charge period
        OLED_WriteCMD(0x0F);
       
        OLED_WriteCMD(0xBE);// set VCOMH
        OLED_WriteCMD(0x0F);
       
        OLED_WriteCMD(0xBC);// set pre_charge voltage/VCOMH
        OLED_WriteCMD(0x08);
       
        OLED_WriteCMD(0xD5);// second precharge and VSL
        OLED_WriteCMD(0x62);
       
        OLED_WriteCMD(0xFD);// Unlock/Lock OLED driver IC MCU interface from entering command
        OLED_WriteCMD(0x12);
       
        OLED_WriteCMD(0xAF);//开启显示
}

/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_SetWindow(uint8_t StartX, uint8_t StartY, uint8_t EndX, uint8_t EndY)
{
    OLED_WriteCMD(0x15);
    OLED_WriteCMD(StartX/2);
    OLED_WriteCMD(EndX/2-1);

    OLED_WriteCMD(0x75);
    OLED_WriteCMD(StartY);
    OLED_WriteCMD(EndY-1);
}

/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_Clear(uint8_t Data)
{
    OLED_SetWindow(0, 0, 128, 128);

    for(uint32_t i = 0; i &lt; OLED_HEIGHT*OLED_WIDTH/2; i++)
    {
      OLED_WriteDAT(Data);
    }
}

/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_Init(void)
{
    OLED_InitI2C();

    OLED_InitCFG();

    OLED_Clear(0xFF);

    OLED_SetWindow(0, 0, 128, 128);
    OLED_WriteBuffer(gImage_AAA, sizeof(gImage_AAA));
}</code></pre>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style=""><span style="color:#e74c3c;"><strong>显示效果</strong></span></p>

<p align="justify" style=""></p>

<p align="justify" style="">&nbsp;</p>

<p align="justify" style=""><strong><span style="color:#e74c3c;">问题反馈</span></strong></p>

<p style="">上述代码中分别使用软硬件两种I2C驱动方式来驱动OLED显示屏,对于软件驱动方式来说,执行所消耗的资源肯定比硬件I2C要多不少,但它可以成功驱动OLED显示,这说明对于OLED的参数配置以及刷新显示这部分的上层功能代码是没有问题的。但通过硬件I2C的方式来驱动显示时,并没有成功,期间尝试通过软件去修改I2C的通讯速率、在硬件上通过焊接不同阻值的上拉电阻,硬件I2C一直没有通讯成功过,通过在线单步DEBUG调试,发现在发送一些数据后,就会卡在产生START信号的等待状态,如下图所示;如果有条件,希望原厂可以一起来调试一下,看一下到底是什么问题导致的这个现象。</p>

<p style=""></p>

xld0932 发表于 2022-7-29 15:10

<p>参考了多个网友驱动0.96寸OLED的I2C配置和驱动部分,对于0.96寸I2C接口的OLED来说,操作都没有问题,但在这款1.5寸的16灰OLED上硬件I2C就是通不了&hellip;&hellip;</p>

<p><img height="51" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/cry2.gif" width="66" /></p>

wangerxian 发表于 2022-7-29 16:25

xld0932 发表于 2022-7-29 15:10
参考了多个网友驱动0.96寸OLED的I2C配置和驱动部分,对于0.96寸I2C接口的OLED来说,操作都没有问题,但在这 ...

<p>用逻辑分析仪抓一下硬件IIC的波形,说不定就能找到问题了。</p>

nmg 发表于 2022-8-1 18:12

xld0932 发表于 2022-7-29 15:10
参考了多个网友驱动0.96寸OLED的I2C配置和驱动部分,对于0.96寸I2C接口的OLED来说,操作都没有问题,但在这 ...

<p><img height="52" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/pleased.gif" width="48" />问题不突出,差点给你漏掉</p>

<p>以后可以考虑问题直接在题目里显示出来</p>

805721366 发表于 2022-8-1 20:14

<p>把OLED_WriteCMD中</p>

<p>I2C_SendData(I2C1,&nbsp;0x00);</p>

<p>while&nbsp;(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));</p>

<p>和OLED_WriteDAT中</p>

<p>I2C_SendData(I2C1,&nbsp;0x40);</p>

<p>while&nbsp;(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_DATA_SENDED));</p>

<p>这两句的I2C_EVT_MASTER_DATA_SENDED改为I2C_EVT_MASTER_DATA_SENDING试试</p>

沧桑小草 发表于 2022-8-1 22:48

<p>建议参考下5楼的意见,另外用示波器看下具体波形,才能知道卡在哪个步骤。国民技术资料链接下载:ftp://58.250.18.138(复制该链接然后用文件资源管理器打开)</p>

xld0932 发表于 2022-8-2 08:48

805721366 发表于 2022-8-1 20:14
把OLED_WriteCMD中

I2C_SendData(I2C1,&nbsp;0x00);

while&nbsp;(!I2C_CheckEvent(I2C1, I2C_EVT_MAS ...

<p>在发帖前就试过了&hellip;&hellip;</p>

<p><img height="28" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/expressionless-face_1f611.png" width="28" /></p>

xld0932 发表于 2022-8-2 08:49

沧桑小草 发表于 2022-8-1 22:48
建议参考下5楼的意见,另外用示波器看下具体波形,才能知道卡在哪个步骤。国民技术资料链接下载:ftp://58. ...

<p>就是参考的官方资料和例程&hellip;&hellip;</p>

xld0932 发表于 2022-8-2 08:50

wangerxian 发表于 2022-7-29 16:25
用逻辑分析仪抓一下硬件IIC的波形,说不定就能找到问题了。

<p>测试工具暂时不在手边&hellip;&hellip;</p>

littleshrimp 发表于 2022-8-8 15:31

<p>检查一下总线上的波形看看是不是和预期的一至,这种情况看代码好像没什么问题,在执行I2C_GenerateStart(I2C1, ENABLE);后MSMODE应该被系统置1,卡在&nbsp; &nbsp; while (!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_MODE_FLAG))可能是由ARLOST导致的,具体还得从波形上来看。</p>

<p> &nbsp;</p>

<p> &nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

xld0932 发表于 2022-8-8 15:43

littleshrimp 发表于 2022-8-8 15:31
检查一下总线上的波形看看是不是和预期的一至,这种情况看代码好像没什么问题,在执行I2C_GenerateStart(I2 ...

<p>的确在单步调试的时候,有卡到这里的情况;怎么解决呢?我也看到网友发了OLED通过软硬件I2C和SPI来驱动的程序,我也测试过,我这边通过硬件I2C来驱动0.96寸的OLED也没问题,但就是驱动这个1.5寸的OLED会卡住;对于I2C的参数配置也都尝试修改过,也没解决问题;手上暂时没有逻辑分析仪,抓取不了波形来看&hellip;&hellip;</p>

littleshrimp 发表于 2022-8-8 15:52

xld0932 发表于 2022-8-8 15:43
的确在单步调试的时候,有卡到这里的情况;怎么解决呢?我也看到网友发了OLED通过软硬件I2C和SPI来驱动的 ...

<p>你试一下,如果不接显示屏,while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_MODE_FLAG));那个循环能跑过去吗?</p>

xld0932 发表于 2022-8-8 16:03

littleshrimp 发表于 2022-8-8 15:52
你试一下,如果不接显示屏,while(!I2C_CheckEvent(I2C1, I2C_EVT_MASTER_MODE_FLAG));那个循环能跑过去 ...

<p>这个不是一开始就跑不过去,在配置OLED参数时,过程中间卡住了&hellip;&hellip;</p>

littleshrimp 发表于 2022-8-8 16:08

xld0932 发表于 2022-8-8 16:03
这个不是一开始就跑不过去,在配置OLED参数时,过程中间卡住了&hellip;&hellip;

<p>看来只能从波形下手了。</p>

未来ic 发表于 2023-2-13 09:21

国民技术的环境如何?听说待遇很好,有没有人分享下真实情况

xld0932 发表于 2023-2-14 10:30

未来ic 发表于 2023-2-13 09:21
国民技术的环境如何?听说待遇很好,有没有人分享下真实情况

<p>我也想八卦一下<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/lol.gif" width="48" /></p>

天若有情天亦老 发表于 2024-7-16 09:06

<p>最后怎么解决的</p>
页: [1]
查看完整版本: 【国民技术低功耗系列N32L43x测评】08.软硬件I2C驱动1.5寸16色灰度OLED显示