[STM32H5] 【NUCLEO- H563ZI 测评】3.SPI+OLED

[复制链接]
 楼主| 穿西装的强子 发表于 2023-7-22 10:19 | 显示全部楼层 |阅读模式
<
本帖最后由 穿西装的强子 于 2023-7-22 10:27 编辑

SPI硬件接口使用SPI1,PA5-SCK,PB5-MOSI,PD14-CS,PD15-DC,PF3-REST,因为不需要读取,所以MISO不需要用。
222222.bmp
SPI软件配置,使用了2线的只发接口,SPI_DIRECTION_2LINES_TXONLY,分频为32分频=250M/32=7.8125MHz,速度太快屏幕受不了 - -!。
  1. static void MX_SPI1_Init(void)
  2. {

  3.   /* USER CODE END SPI1_Init 1 */
  4.   /* SPI1 parameter configuration*/
  5.   hspi1.Instance = SPI1;
  6.   hspi1.Init.Mode = SPI_MODE_MASTER;
  7.   hspi1.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
  8.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  9.   hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  10.   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  11.   hspi1.Init.NSS = SPI_NSS_SOFT;
  12.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  13.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  14.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  15.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  16.   hspi1.Init.CRCPolynomial = 0x7;
  17.   hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  18.   hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  19.   hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  20.   hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  21.   hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  22.   hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  23.   hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  24.   hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  25.   hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
  26.   hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
  27.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  28.   {
  29.     Error_Handler();
  30.   }
  31.   /* USER CODE BEGIN SPI1_Init 2 */

  32.   /* USER CODE END SPI1_Init 2 */

  33. }/**
  34. * [url=home.php?mod=space&uid=247401]@brief[/url] SPI MSP Initialization
  35. * This function configures the hardware resources used in this example
  36. * @param hspi: SPI handle pointer
  37. * @retval None
  38. */
  39. void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
  40. {
  41.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  42.   RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  43.   if(hspi->Instance==SPI1)
  44.   {
  45.   /* USER CODE BEGIN SPI1_MspInit 0 */

  46.   /* USER CODE END SPI1_MspInit 0 */

  47.   /** Initializes the peripherals clock
  48.   */
  49.     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
  50.     PeriphClkInitStruct.Spi1ClockSelection = RCC_SPI1CLKSOURCE_PLL1Q;
  51.     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  52.     {
  53.       Error_Handler();
  54.     }

  55.     /* Peripheral clock enable */
  56.     __HAL_RCC_SPI1_CLK_ENABLE();

  57.     __HAL_RCC_GPIOA_CLK_ENABLE();
  58.         __HAL_RCC_GPIOB_CLK_ENABLE();
  59.     /**SPI1 GPIO Configuration
  60.     PA5     ------> SPI1_SCK
  61.     PA6     ------> SPI1_MISO
  62.     PB5     ------> SPI1_MOSI
  63.     */
  64.     GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
  65.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  66.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  67.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  68.     GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
  69.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  70.     GPIO_InitStruct.Pin = GPIO_PIN_5;
  71.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  72.     GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  73.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  74.     GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
  75.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  76.     /* SPI1 interrupt Init */
  77.     HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
  78.     HAL_NVIC_EnableIRQ(SPI1_IRQn);
  79.   /* USER CODE BEGIN SPI1_MspInit 1 */

  80.   /* USER CODE END SPI1_MspInit 1 */
  81.   }

  82. }
SPI发送函数处理,发送后等待发送标值结束,并且增加超时功能,若5000次循环都没有完成,则结束本次等待。
  1. void SPI1_SEND(uint8_t *data,uint8_t len)
  2. {
  3. int32_t cnt;
  4. uint8_t rx[2] = {1};
  5. HAL_SPI_TransmitReceive_IT(&hspi1, data, rx, len);
  6. cnt = 5000;
  7. while (wTransferState == TRANSFER_WAIT && cnt-->0);
  8. wTransferState = TRANSFER_WAIT;
  9. }
OLED的GPIO初始化

  1. void DevOLED_GPIO_Init(void)
  2. {
  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  4.   /* GPIO Ports Clock Enable */
  5.   __HAL_RCC_GPIOD_CLK_ENABLE();
  6.   __HAL_RCC_GPIOF_CLK_ENABLE();

  7. //  /*Configure GPIO pin Output Level */
  8. //  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);

  9. //  /*Configure GPIO pin Output Level */
  10. //  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);

  11. //  /*Configure GPIO pin Output Level */
  12. //  HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3, GPIO_PIN_RESET);

  13.   GPIO_InitStruct.Pin = GPIO_PIN_14;
  14.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  15.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  16.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  17.   HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  18.   GPIO_InitStruct.Pin = GPIO_PIN_15;
  19.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  20.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  21.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  22.   HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);


  23.   /*Configure GPIO pin : LED3_Pin */
  24.   GPIO_InitStruct.Pin = GPIO_PIN_3;
  25.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  26.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  27.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  28.   HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  29. }
OLED配置,其它的如何移植就不在赘述了,都很简单,
  1. void DevOLED_Init(void)
  2. {
  3.         DevOLED_GPIO_Init();
  4.     //SPI
  5.     RST_H;  //SPI RST
  6.     HAL_Delay(100);
  7.     RST_L;
  8.     HAL_Delay(100);
  9.     RST_H;
  10.         HAL_Delay(100);
  11.     DevOLED_WRByte(0xAE,OLED_CMD);//--turn off oled panel
  12.     DevOLED_WRByte(0x00,OLED_CMD);//---set low column address
  13.     DevOLED_WRByte(0x10,OLED_CMD);//---set high column address
  14.     DevOLED_WRByte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  15.     DevOLED_WRByte(0x81,OLED_CMD);//--set contrast control register
  16.     DevOLED_WRByte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
  17.     DevOLED_WRByte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0×óÓÒ·´ÖÃ 0xa1Õý³£
  18.     DevOLED_WRByte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0ÉÏÏ·´Öà 0xc8Õý³£
  19.     DevOLED_WRByte(0xA6,OLED_CMD);//--set normal display
  20.     DevOLED_WRByte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  21.     DevOLED_WRByte(0x3f,OLED_CMD);//--1/64 duty
  22.     DevOLED_WRByte(0xD3,OLED_CMD);//-set display offset   Shift Mapping RAM Counter (0x00~0x3F)
  23.     DevOLED_WRByte(0x00,OLED_CMD);//-not offset
  24.     DevOLED_WRByte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  25.     DevOLED_WRByte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  26.     DevOLED_WRByte(0xD9,OLED_CMD);//--set pre-charge period
  27.     DevOLED_WRByte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  28.     DevOLED_WRByte(0xDA,OLED_CMD);//--set com pins hardware configuration
  29.     DevOLED_WRByte(0x12,OLED_CMD);
  30.     DevOLED_WRByte(0xDB,OLED_CMD);//--set vcomh
  31.     DevOLED_WRByte(0x40,OLED_CMD);//Set VCOM Deselect Level
  32.     DevOLED_WRByte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  33.     DevOLED_WRByte(0x02,OLED_CMD);//
  34.     DevOLED_WRByte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  35.     DevOLED_WRByte(0x14,OLED_CMD);//--set(0x10) disable
  36.     DevOLED_WRByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  37.     DevOLED_WRByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  38.     DevOLED_WRByte(0xAF,OLED_CMD);//--turn on oled panel

  39.     DevOLED_WRByte(0xAF,OLED_CMD); /*display ON*/
  40.     DevOLED_Clear();
  41.     DevOLED_Set_Pos(0,0);
  42.     DevOLED_UIInit();
  43. }
  1. void DevOLED_UIInit(void)
  2. {
  3.     //固定显示第一行,不刷新,显示中文“时间”和“:”
  4.     DevOLED_ShowChinese(0,0,0,16);
  5.     DevOLED_ShowChinese(1,0,1,16);
  6.     DevOLED_ShowString(2,0,":",16);
  7. }


FreeRTOS任务刷新显示,system_count是1ms定时器累计数值。
  1. void DevOLED_UIHandle(void)
  2. {
  3.    
  4.         DevOLED_ShowTime(44,0,system_count/1000,16);
  5. }
  1. void LEDThread_Entry(void *argument)
  2. {
  3.         (void) argument;

  4.         printf("system start\r\n");

  5.   while(1)
  6.   {
  7.           DevOLED_UIHandle();
  8.         HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
  9.         /* Delay for 500ms */
  10.         vTaskDelay(50);
  11.         HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
  12.         vTaskDelay(50);
  13.         HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin);
  14.         vTaskDelay(50);
  15.   }
  16. }


最后显示效果
6086064bb3c7bcac96.jpg
Undshing 发表于 2023-8-18 10:59 | 显示全部楼层
freeRTOS是需要自己移植吗?
中国龙芯CDX 发表于 2023-8-21 10:14 | 显示全部楼层
SPI软件配置还是挺方便的,整体刷新速率快
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

257

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部