本帖最后由 suncat0504 于 2023-11-7 18:07 编辑
#申请原创# @21小跑堂
本次使用SPI接口的OLED测试显示刷新速度。依旧使用128*64点阵的OLED,
接口定义:
这个OLED的时钟信号要求,SCK时钟最小支持到20ns,完全不用担心和这个开发板的匹配问题。
为了减少接口连接线,CS固定接地。使用4个GPIO口模拟SPI时钟、SPI数据、RESET、DC。感觉如果不是考虑到RESET和DC数据/指令选择,好像和IIC方式也没啥区别了。测试程序使用Work Bench进行重新设计。
使用定时器1溢出中断,用来实现1秒的计时。
使用GPIO的C0、C1、C2、C3模拟通讯口的SCK时钟、SDA(数据)、RESET(复位信号)、DC(数据、指令选择)。CS常态接地,就不用程序控制了。
为了方便观察,注册是刷新图像过程中,加入标试点的显示,以证明刷新在不断进行中。
以下是主程序处理代码:
- /* add user code begin Header */
- /**
- **************************************************************************
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=247401]@brief[/url] main program
- **************************************************************************
- * Copyright notice & Disclaimer
- *
- * The software Board Support Package (BSP) that is made available to
- * download from Artery official website is the copyrighted work of Artery.
- * Artery authorizes customers to use, copy, and distribute the BSP
- * software and its related documentation for the purpose of design and
- * development in conjunction with Artery microcontrollers. Use of the
- * software is governed by this copyright notice and the following disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
- * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
- * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
- * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
- * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- *
- **************************************************************************
- */
- /* add user code end Header */
- /* Includes ------------------------------------------------------------------*/
- #include "at32f423_wk_config.h"
- #include "delay.h"
- #include "spi_oled.h"
- #include "bmp.h"
- /* private includes ----------------------------------------------------------*/
- /* add user code begin private includes */
- /* add user code end private includes */
- /* private typedef -----------------------------------------------------------*/
- /* add user code begin private typedef */
- /* add user code end private typedef */
- /* private define ------------------------------------------------------------*/
- /* add user code begin private define */
- /* add user code end private define */
- /* private macro -------------------------------------------------------------*/
- /* add user code begin private macro */
- /* add user code end private macro */
- /* private variables ---------------------------------------------------------*/
- /* add user code begin private variables */
- uint32_t gi_us=0; // 微秒计数
- uint32_t gi_us_dao=0; // 微秒倒计时
- uint32_t gi_ms_dao=0; // 微秒倒计时
- uint8_t gi_1sflag=0; // 1秒中断标志
- /* add user code end private variables */
- /* private function prototypes --------------------------------------------*/
- /* add user code begin function prototypes */
- /* add user code end function prototypes */
- /* private user code ---------------------------------------------------------*/
- /* add user code begin 0 */
- /* add user code end 0 */
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] take some delay for waiting power stable, delay is about 60ms with frequency 8MHz.
- * @param none
- * @retval none
- */
- static void wk_wait_for_power_stable(void)
- {
- volatile uint32_t delay = 0;
- for(delay = 0; delay < 50000; delay++);
- }
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] main function.
- * @param none
- * @retval none
- */
- int main(void) {
- /* add user code begin 1 */
- uint32_t cnt = 0, pos=0,dir=0;
- /* add user code end 1 */
- /* add a necessary delay to ensure that Vdd is higher than the operating
- voltage of battery powered domain (2.57V) when the battery powered
- domain is powered on for the first time and being operated. */
- wk_wait_for_power_stable();
-
- /* system clock config. */
- wk_system_clock_config();
- /* config periph clock. */
- wk_periph_clock_config();
- /* nvic config. */
- wk_nvic_config();
- /* init usart1 function. */
- wk_usart1_init();
- /* init gpio function. */
- wk_gpio_config();
- /* init tmr1 function. */
- wk_tmr1_init();
- /* init tmr2 function. */
- //wk_tmr2_init();
- /* add user code begin 2 */
- cnt=0; // 清除计数次数变量
- SPI_OLED_Init(); // 初始化SPI OLED
- gi_1sflag=0; // 清除1秒计数标志
- gi_us=0; // 清除10微秒计数标志
- /* add user code end 2 */
- while(1) {
- /* add user code begin 3 */
- for (int i=0;i<128;i++) {
- BMP[i]=0;
- }
- // 动态标识标试点,以证明刷新处理进行中
- BMP[pos] = 1;
- // 显示手的图案
- SPI_OLED_DrawBMP(0,0,128,64,BMP);
- cnt++;
- if (dir) {
- // 反向移动标识点
- pos--;
- if (pos==0) {
- dir=0;
- pos=1;
- }
- } else {
- // 正向移动标识点
- pos++;
- if (pos==128) {
- dir=1;
- pos=126;
- }
- }
- // 一秒时间到
- if (gi_1sflag>0) {
- // 串口输出刷新次数
- usart_data_transmit(USART1, '=');
- while ((USART1->sts & 0x80)==0);
- usart_data_transmit(USART1, (cnt/100)+48);
- while ((USART1->sts & 0x80)==0);
- usart_data_transmit(USART1, ((cnt%100)/10)+48);
- while ((USART1->sts & 0x80)==0);
- usart_data_transmit(USART1, (cnt%10)+48);
- while ((USART1->sts & 0x80)==0);
- usart_data_transmit(USART1, 10);
- while ((USART1->sts & 0x80)==0);
- usart_data_transmit(USART1, 13);
- while ((USART1->sts & 0x80)==0);
- // 清除中间记录信息和标志
- cnt=0;
- gi_1sflag = 0;
- gi_us=0;
- }
- /* add user code end 3 */
- }
- }
定时器处理的代码:
- void TMR1_OVF_TMR10_IRQHandler(void)
- {
- /* add user code begin TMR1_OVF_TMR10_IRQ 0 */
- if(tmr_flag_get(TMR1, TMR_OVF_FLAG) == SET) {
- gpio_bits_toggle(LED2_GPIO_PORT, LED2_PIN);
- if (gi_us_dao>0) {
- gi_us_dao--;
- }
- if (gi_ms_dao>0) {
- gi_ms_dao--;
- }
- gi_us++;
- //gpio_bits_toggle(LED2_GPIO_PORT, LED2_PIN);
- if (gi_us == 100000) {
- // 1秒
- gi_1sflag = 1;
- gi_us = 0;
- gpio_bits_toggle(LED4_GPIO_PORT, LED4_PIN);
- }
- if (gi_us == 50000) {
- // 0.5秒
- gpio_bits_toggle(LED3_GPIO_PORT, LED3_PIN);
- }
- // 清除溢出标志
- tmr_flag_clear(TMR1, TMR_OVF_FLAG);
- }
实测刷新能力为每秒111帧。这里面如果去掉标试点的处理部分,可以提高到112帧。刷新一页图片的时间在9ms以下。可以看到刷新速度比IIC方式快了近一倍。
以下是OLED上的测试结果:
附上工程:
SPIOLED.zip
(6.12 MB, 下载次数: 16)
|