找回密码
 立即注册

只需一步,快速开始

搜索

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

1
回复
2258
查看
[复制链接]

166

主题

343

帖子

3076

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3076
QQ
2022-1-6 09:08:50 显示全部楼层 |阅读模式
【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

  1. /*******************************************************************************
  2. * @brief * @param      
  3. * @retval      
  4. * @attention *******************************************************************************/
  5. void OLED1_InitI2C(void)
  6. {
  7.     FL_GPIO_InitTypeDef           GPIO_InitStruct;
  8.     FL_I2C_MasterMode_InitTypeDef I2C_InitStruct;

  9.     FL_GPIO_StructInit(&GPIO_InitStruct);
  10.     GPIO_InitStruct.pin        = FL_GPIO_PIN_11 | FL_GPIO_PIN_12;
  11.     GPIO_InitStruct.mode       = FL_GPIO_MODE_DIGITAL;
  12.     GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
  13.     GPIO_InitStruct.pull       = FL_DISABLE;
  14.     FL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  15.     I2C_InitStruct.clockSource = FL_CMU_I2C_CLK_SOURCE_APBCLK;
  16.     I2C_InitStruct.baudRate    = 400000;
  17.     FL_I2C_MasterMode_Init(I2C, &I2C_InitStruct);
  18. }

  19. ……

  20. /*******************************************************************************
  21. * @brief      
  22. * @param      
  23. * @retval      
  24. * @attention   
  25. *******************************************************************************/
  26. void OLED1_DrawImage(uint8_t Width, uint8_t Height, const uint8_t *ImageData)
  27. {
  28.     uint8_t  x = 0, y = 0;
  29.     uint8_t  Buffer[0x80];
  30.     uint16_t Index    = 0;

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

  34.         for(x = 0; x < Width; x++)
  35.         {
  36.             Buffer[x] = ImageData[Index++];
  37.         }

  38.         OLED1_WriteBuffer(Buffer, Width);
  39.     }
  40. }


  41. /*******************************************************************************
  42. * @brief      
  43. * @param      
  44. * @retval      
  45. * @attention   
  46. *******************************************************************************/
  47. void OLED1_Init(void)
  48. {
  49.     OLED1_InitI2C();

  50.     OLED1_InitCFG();

  51.     OLED1_Clear(0x00);

  52.     TASK_Append(TASK_ID_OLED1, OLED1_Handler, 100);
  53. }

  54. ……
复制代码

OLED2:SPI

  1. /*******************************************************************************
  2. * @brief      
  3. * @param      
  4. * @retval      
  5. * @attention   
  6. *******************************************************************************/
  7. void OLED2_InitSPI(void)
  8. {
  9.     FL_DMA_InitTypeDef  DMA_InitStruct;
  10.     FL_GPIO_InitTypeDef GPIO_InitStruct;
  11.     FL_SPI_InitTypeDef  SPI_InitStruct;

  12.     FL_SPI_StructInit(&SPI_InitStruct);
  13.     SPI_InitStruct.baudRate      = FL_SPI_BAUDRATE_DIV2;
  14.     SPI_InitStruct.bitOrder      = FL_SPI_BIT_ORDER_MSB_FIRST;
  15.     SPI_InitStruct.clockPhase    = FL_SPI_PHASE_EDGE1;
  16.     SPI_InitStruct.clockPolarity = FL_SPI_POLARITY_NORMAL;
  17.     SPI_InitStruct.dataWidth     = FL_SPI_DATA_WIDTH_8B;
  18.     SPI_InitStruct.mode          = FL_SPI_WORK_MODE_MASTER;
  19.     SPI_InitStruct.softControl   = FL_ENABLE;
  20.     SPI_InitStruct.transferMode  = FL_SPI_TRANSFER_MODE_FULL_DUPLEX;
  21.     FL_SPI_Init(SPI1, &SPI_InitStruct);

  22.     FL_DMA_StructInit(&DMA_InitStruct);
  23.     DMA_InitStruct.circMode = FL_DISABLE;
  24.     DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_8B;
  25.     DMA_InitStruct.direction = FL_DMA_DIR_PERIPHERAL_TO_RAM;
  26.     DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
  27.     DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH ;
  28.     DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION1;
  29.     FL_DMA_Init(DMA, &DMA_InitStruct, FL_DMA_CHANNEL_3);

  30.     FL_DMA_StructInit(&DMA_InitStruct);
  31.     DMA_InitStruct.circMode = FL_DISABLE;
  32.     DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_8B;
  33.     DMA_InitStruct.direction = FL_DMA_DIR_RAM_TO_PERIPHERAL;
  34.     DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
  35.     DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH ;
  36.     DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION2;
  37.     FL_DMA_Init(DMA, &DMA_InitStruct, FL_DMA_CHANNEL_4);

  38.     FL_GPIO_StructInit(&GPIO_InitStruct);
  39.     GPIO_InitStruct.pin        = FL_GPIO_PIN_2 | FL_GPIO_PIN_3 |
  40.                                  FL_GPIO_PIN_4 |FL_GPIO_PIN_5;
  41.     GPIO_InitStruct.mode       = FL_GPIO_MODE_DIGITAL;
  42.     GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  43.     FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  44. }

  45. ……

  46. /*******************************************************************************
  47. * @brief      
  48. * @param      
  49. * @retval      
  50. * @attention   
  51. *******************************************************************************/
  52. void OLED2_Init(void)
  53. {
  54.     OLED2_InitSPI();

  55.     OLED2_HardwareReset();

  56.     OLED2_ConfigureREG();

  57.     OLED2_Clear(0x00);

  58.     TASK_Append(TASK_ID_OLED2, OLED2_Handler, 500);
  59. }


  60. /*******************************************************************************
  61. * @brief      
  62. * @param      
  63. * @retval      
  64. * @attention   
  65. *******************************************************************************/
  66. void OLED_ShowChar(uint8_t X, uint8_t Y, char ch, uint8_t Size)
  67. {  
  68.     uint8_t Data = 0;

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

  72.         if(Size == 12)
  73.         {
  74.             Data = ASCII_1206[ch - 0x20];
  75.         }
  76.         else
  77.         {
  78.             Data = ASCII_1608[ch - 0x20];
  79.         }

  80.         OLED2_WriteDAT(Data);
  81.     }
  82. }

  83. ……
复制代码

4、运行效果

可查看原帖

5、源代码

Project_I2C_SPI.zip (379.68 KB, 下载次数: 227)

回复

使用道具 举报

0

主题

1

帖子

60

积分

中级工程师

Rank: 2

积分
60
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);
    }
}
上面我修改了一下。不知道行不行。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

返回顶部