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

SPI硬件接口使用SPI1,PA5-SCK,PB5-MOSI,PD14-CS,PD15-DC,PF3-REST,因为不需要读取,所以MISO不需要用。

 

SPI软件配置,使用了2线的只发接口,SPI_DIRECTION_2LINES_TXONLY,分频为32分频=250M/32=7.8125MHz,速度太快屏幕受不了 - -!。
 

static void MX_SPI1_Init(void)

{

  /* USER CODE END SPI1_Init 1 */

  /* SPI1 parameter configuration*/

  hspi1.Instance = SPI1;

  hspi1.Init.Mode = SPI_MODE_MASTER;

  hspi1.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;

  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

  hspi1.Init.NSS = SPI_NSS_SOFT;

  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;

  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

  hspi1.Init.CRCPolynomial = 0x7;

  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

  hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;

  hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;

  hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;

  hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;

  hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;

  hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;

  hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;

  hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;

  hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;

  if (HAL_SPI_Init(&hspi1) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}/**

* [url=home.php?mod=space&uid=247401]@brief[/url] SPI MSP Initialization

* This function configures the hardware resources used in this example

* @param hspi: SPI handle pointer

* @retval None

*/

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  if(hspi->Instance==SPI1)

  {

  /* USER CODE BEGIN SPI1_MspInit 0 */

  /* USER CODE END SPI1_MspInit 0 */

  /** Initializes the peripherals clock

  */

    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI1;

    PeriphClkInitStruct.Spi1ClockSelection = RCC_SPI1CLKSOURCE_PLL1Q;

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

    {

      Error_Handler();

    }

    /* Peripheral clock enable */

    __HAL_RCC_SPI1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();

        __HAL_RCC_GPIOB_CLK_ENABLE();

    /**SPI1 GPIO Configuration

    PA5     ------> SPI1_SCK

    PA6     ------> SPI1_MISO

    PB5     ------> SPI1_MOSI

    */

    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_5;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_PULLDOWN;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* SPI1 interrupt Init */

    HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(SPI1_IRQn);

  /* USER CODE BEGIN SPI1_MspInit 1 */

  /* USER CODE END SPI1_MspInit 1 */

  }

}


SPI发送函数处理,发送后等待发送标值结束,并且增加超时功能,若5000次循环都没有完成,则结束本次等待。
 

void SPI1_SEND(uint8_t *data,uint8_t len)

{

int32_t cnt;

uint8_t rx[2] = {1};

HAL_SPI_TransmitReceive_IT(&hspi1, data, rx, len);

cnt = 5000;

while (wTransferState == TRANSFER_WAIT && cnt-->0);

wTransferState = TRANSFER_WAIT;

}


OLED的GPIO初始化
 

void DevOLED_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOD_CLK_ENABLE();

  __HAL_RCC_GPIOF_CLK_ENABLE();

//  /*Configure GPIO pin Output Level */

//  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);

//  /*Configure GPIO pin Output Level */

//  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);

//  /*Configure GPIO pin Output Level */

//  HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3, GPIO_PIN_RESET);

  GPIO_InitStruct.Pin = GPIO_PIN_14;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_15;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pin : LED3_Pin */

  GPIO_InitStruct.Pin = GPIO_PIN_3;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

}

OLED配置,其它的如何移植就不在赘述了,都很简单,
 

void DevOLED_Init(void)

{

        DevOLED_GPIO_Init();

    //SPI

    RST_H;  //SPI RST

    HAL_Delay(100);

    RST_L;

    HAL_Delay(100);

    RST_H;

        HAL_Delay(100);

    DevOLED_WRByte(0xAE,OLED_CMD);//--turn off oled panel

    DevOLED_WRByte(0x00,OLED_CMD);//---set low column address

    DevOLED_WRByte(0x10,OLED_CMD);//---set high column address

    DevOLED_WRByte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)

    DevOLED_WRByte(0x81,OLED_CMD);//--set contrast control register

    DevOLED_WRByte(0xCF,OLED_CMD); // Set SEG Output Current Brightness

    DevOLED_WRByte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0×óÓÒ·´ÖÃ 0xa1Õý³£

    DevOLED_WRByte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0ÉÏÏ·´Öà 0xc8Õý³£

    DevOLED_WRByte(0xA6,OLED_CMD);//--set normal display

    DevOLED_WRByte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)

    DevOLED_WRByte(0x3f,OLED_CMD);//--1/64 duty

    DevOLED_WRByte(0xD3,OLED_CMD);//-set display offset   Shift Mapping RAM Counter (0x00~0x3F)

    DevOLED_WRByte(0x00,OLED_CMD);//-not offset

    DevOLED_WRByte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency

    DevOLED_WRByte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec

    DevOLED_WRByte(0xD9,OLED_CMD);//--set pre-charge period

    DevOLED_WRByte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock

    DevOLED_WRByte(0xDA,OLED_CMD);//--set com pins hardware configuration

    DevOLED_WRByte(0x12,OLED_CMD);

    DevOLED_WRByte(0xDB,OLED_CMD);//--set vcomh

    DevOLED_WRByte(0x40,OLED_CMD);//Set VCOM Deselect Level

    DevOLED_WRByte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)

    DevOLED_WRByte(0x02,OLED_CMD);//

    DevOLED_WRByte(0x8D,OLED_CMD);//--set Charge Pump enable/disable

    DevOLED_WRByte(0x14,OLED_CMD);//--set(0x10) disable

    DevOLED_WRByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)

    DevOLED_WRByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)

    DevOLED_WRByte(0xAF,OLED_CMD);//--turn on oled panel

    DevOLED_WRByte(0xAF,OLED_CMD); /*display ON*/

    DevOLED_Clear();

    DevOLED_Set_Pos(0,0);

    DevOLED_UIInit();

}


 

void DevOLED_UIInit(void)

{

    //固定显示第一行,不刷新,显示中文“时间”和“:”

    DevOLED_ShowChinese(0,0,0,16);

    DevOLED_ShowChinese(1,0,1,16);

    DevOLED_ShowString(2,0,":",16);

}


FreeRTOS任务刷新显示,system_count是1ms定时器累计数值。
 

void DevOLED_UIHandle(void)

{

    

        DevOLED_ShowTime(44,0,system_count/1000,16);

}
void LEDThread_Entry(void *argument)

{

        (void) argument;

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

  while(1)

  {

          DevOLED_UIHandle();

        HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);

        /* Delay for 500ms */

        vTaskDelay(50);

        HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);

        vTaskDelay(50);

        HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin);

        vTaskDelay(50);

  }

}


最后显示效果

 



---------------------
作者:穿西装的强子
链接:https://bbs.21ic.com/icview-3316168-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值