wangpeng 发表于 2022-1-6 09:08:50

【FM33LG0系列开发板测评】I2C、SPI

【FM33LG0系列开发板测评】I2C、SPI
原帖地址:【FM33LG0系列开发板测评】05.I2C、SPI - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

1、介绍FM33LG0系列MCU最多带有1路支持主从模式的I2C接口和3路支持主从模式的SPI接口;其中I2C支持7位或10位的从机地址,在传输速度上支持100kbps的标准模式、400kbps的快速模式和1Mbps的超快模式三种速度,且支持唤醒功能,唯一遗憾的就是不支持多主机模式;对于SPI接口,全双工4线串行收发,可以自定义数据字长为8/16/24/32位,方便应用在不同的场合;有专用于TFT屏驱动的半双工4线串行同步收发模式;对于MISO和MOSI这两个信号引脚,可以通过软件配置交换引脚顺序,万一硬件工程师一不小心连错了线,也不用担心重新修改硬件,很方便。
2、实现功能在开发板上已经将1路I2C和2路SPI接口通过排针的形式引出来了,我们通过I2C接口和SPI1接口分别来驱动两块OLED屏,一块OLED屏为I2C通讯接口,另外一块OLED屏为SPI接口;结合上篇帖子实现的RTC功能,显示时钟动画和当前的日期和时间信息;
3、主要代码OLED1:I2C/*******************************************************************************
* @brief * @param      
* @retval      
* @attention *******************************************************************************/
void OLED1_InitI2C(void)
{
    FL_GPIO_InitTypeDef         GPIO_InitStruct;
    FL_I2C_MasterMode_InitTypeDef I2C_InitStruct;

    FL_GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.pin      = FL_GPIO_PIN_11 | FL_GPIO_PIN_12;
    GPIO_InitStruct.mode       = FL_GPIO_MODE_DIGITAL;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
    GPIO_InitStruct.pull       = FL_DISABLE;
    FL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    I2C_InitStruct.clockSource = FL_CMU_I2C_CLK_SOURCE_APBCLK;
    I2C_InitStruct.baudRate    = 400000;
    FL_I2C_MasterMode_Init(I2C, &I2C_InitStruct);
}

……

/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED1_DrawImage(uint8_t Width, uint8_t Height, const uint8_t *ImageData)
{
    uint8_tx = 0, y = 0;
    uint8_tBuffer;
    uint16_t Index    = 0;

    for(y = 0; y < Height / 8; y++)
    {
      OLED1_SetPosition(32, y);

      for(x = 0; x < Width; x++)
      {
            Buffer = ImageData;
      }

      OLED1_WriteBuffer(Buffer, Width);
    }
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED1_Init(void)
{
    OLED1_InitI2C();

    OLED1_InitCFG();

    OLED1_Clear(0x00);

    TASK_Append(TASK_ID_OLED1, OLED1_Handler, 100);
}

……OLED2:SPI/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED2_InitSPI(void)
{
    FL_DMA_InitTypeDefDMA_InitStruct;
    FL_GPIO_InitTypeDef GPIO_InitStruct;
    FL_SPI_InitTypeDefSPI_InitStruct;

    FL_SPI_StructInit(&SPI_InitStruct);
    SPI_InitStruct.baudRate      = FL_SPI_BAUDRATE_DIV2;
    SPI_InitStruct.bitOrder      = FL_SPI_BIT_ORDER_MSB_FIRST;
    SPI_InitStruct.clockPhase    = FL_SPI_PHASE_EDGE1;
    SPI_InitStruct.clockPolarity = FL_SPI_POLARITY_NORMAL;
    SPI_InitStruct.dataWidth   = FL_SPI_DATA_WIDTH_8B;
    SPI_InitStruct.mode          = FL_SPI_WORK_MODE_MASTER;
    SPI_InitStruct.softControl   = FL_ENABLE;
    SPI_InitStruct.transferMode= FL_SPI_TRANSFER_MODE_FULL_DUPLEX;
    FL_SPI_Init(SPI1, &SPI_InitStruct);

    FL_DMA_StructInit(&DMA_InitStruct);
    DMA_InitStruct.circMode = FL_DISABLE;
    DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_8B;
    DMA_InitStruct.direction = FL_DMA_DIR_PERIPHERAL_TO_RAM;
    DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
    DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH ;
    DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION1;
    FL_DMA_Init(DMA, &DMA_InitStruct, FL_DMA_CHANNEL_3);

    FL_DMA_StructInit(&DMA_InitStruct);
    DMA_InitStruct.circMode = FL_DISABLE;
    DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_8B;
    DMA_InitStruct.direction = FL_DMA_DIR_RAM_TO_PERIPHERAL;
    DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
    DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH ;
    DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION2;
    FL_DMA_Init(DMA, &DMA_InitStruct, FL_DMA_CHANNEL_4);

    FL_GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.pin      = FL_GPIO_PIN_2 | FL_GPIO_PIN_3 |
                                 FL_GPIO_PIN_4 |FL_GPIO_PIN_5;
    GPIO_InitStruct.mode       = FL_GPIO_MODE_DIGITAL;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

……

/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED2_Init(void)
{
    OLED2_InitSPI();

    OLED2_HardwareReset();

    OLED2_ConfigureREG();

    OLED2_Clear(0x00);

    TASK_Append(TASK_ID_OLED2, OLED2_Handler, 500);
}


/*******************************************************************************
* @brief      
* @param      
* @retval      
* @attention   
*******************************************************************************/
void OLED_ShowChar(uint8_t X, uint8_t Y, char ch, uint8_t Size)
{
    uint8_t Data = 0;

    for(uint8_t i = 0; i < Size; i++)
    {
      OLED2_SetPosition(X + i, Y);

      if(Size == 12)
      {
            Data = ASCII_1206;
      }
      else
      {
            Data = ASCII_1608;
      }

      OLED2_WriteDAT(Data);
    }
}

……
4、运行效果可查看原帖5、源代码

lifeng5478 发表于 2022-5-29 00:39:36

写的特别好,但是有个小瑕疵。。。
*******************************************************************************/
void TASK_TimeSlice(uint32_t tick)
{
    LinkedList_TypeDef *node = head;

    while(node != NULL)
    {
      if((tick % node->info.tick) == 0)
      {
            node->info.ready = 1;
      }
      
      node = node->next;
    }
}

void LPTIM_IRQHandler(void)
{
    if(FL_LPTIM32_IsEnabledIT_Update(LPTIM32) &&
       FL_LPTIM32_IsActiveFlag_Update(LPTIM32) )
    {
      LPTIM32_Tick++;
      TASK_TimeSlice(LPTIM32_Tick);

      FL_LPTIM32_ClearFlag_Update(LPTIM32);
    }
}
*******************************************************************************/
void TASK_TimeSlice(uint32_t tick)
{
    LinkedList_TypeDef *node = head;

    while(node != NULL)
    {
      node->info.nowtick+=tick;
      if((node->info.nowtick==node->info.tick))
      {
            node->info.nowtick = 0;
            node->info.ready = 1;
      }
      node = node->next;
    }
}

void LPTIM_IRQHandler(void)
{
    if(FL_LPTIM32_IsEnabledIT_Update(LPTIM32) &&
       FL_LPTIM32_IsActiveFlag_Update(LPTIM32) )
    {
      // LPTIM32_Tick++;
      TASK_TimeSlice(1);

      FL_LPTIM32_ClearFlag_Update(LPTIM32);
    }
}
上面我修改了一下。不知道行不行。
页: [1]
查看完整版本: 【FM33LG0系列开发板测评】I2C、SPI