點(diǎn)亮AliOS Things IOT開發(fā)板上的的OLED全彩屏
關(guān)注嵌入式云IOT技術(shù)群,給你帶來更多精彩!
https://github.com/alibaba/AliOSThings/tree/rel_3.0.0/app/example/dk/dk_gui
一、LCD的管腳定義以及在開發(fā)板上對應(yīng)的IO
相關(guān)的管腳連接
即是下面這幾個核心的管腳:
二、開始stm32CubeMX的配置
2.1 時鐘配置
2.2 SPI配置
2.3 GPIO配置
三、生成代碼與LCD驅(qū)動移植
LCD的初始化代碼以及寄存器手冊詳情可參考:
https://download.csdn.net/download/bhtlbhtl123/8963365
接下來看一下我移植過來的ST7789.h
#ifndef __ST7789_H
#define __ST7789_H
#include "main.h"
#include "spi.h"
#define WIDTH 240
#define HEIGHT 240
#define BPP 16
#define LCD_MAX_MEM16_BLOCK (1 << 6)
#define LCD_PIXEL_PER_BLOCK (LCD_MAX_MEM16_BLOCK >> 1)
/* Init script function */
struct st7789_function {
uint8_t cmd;
uint16_t data;
};
/* Init script commands */
enum st7789_cmd {
ST7789_START,
ST7789_END,
ST7789_CMD,
ST7789_DATA,
ST7789_DELAY
};
/* ST7789 Commands */
#define ST7789_CASET 0x2A
#define ST7789_RASET 0x2B
#define ST7789_RAMWR 0x2C
#define ST7789_RAMRD 0x2E
//LCD初始化
int st7789_init(void);
//寫寄存器
void LcdWriteReg(uint8_t Data);
//寫數(shù)據(jù)
void LcdWriteData(uint8_t Data);
//將多個值寫入顯示寄存器
void LcdWriteDataMultiple(uint8_t * pData, int NumItems);
//寫一個像素到指定位置
void ST7789H2_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode);
//寫一行數(shù)據(jù)
void ST7789H2_WriteLine(uint16_t Xpos, uint16_t Ypos, uint16_t *RGBCode, uint16_t pointNum);
//顯示圖片
void st7789_display_picture(void);
#endif //__ST7789_H
ST7789.c
#include "ST7789.h"
static SPI_HandleTypeDef *hspi_lcd = NULL;
uint8_t black_gui[480] = {0};
uint8_t endian_buffer[480];
//參考LCD的寄存器手冊
static struct st7789_function st7789_cfg_script[] = {
{ST7789_START, ST7789_START},
{ST7789_CMD, 0x11},
{ST7789_DELAY, 120},
{ST7789_CMD, 0x36},
{ST7789_DATA, 0x00},
{ST7789_CMD, 0x3a},
{ST7789_DATA, 0x05},
{ST7789_CMD, 0xb2},
{ST7789_DATA, 0x0c},
{ST7789_DATA, 0x0c},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0x33},
{ST7789_DATA, 0x33},
{ST7789_CMD, 0xb7},
{ST7789_DATA, 0x72},
{ST7789_CMD, 0xbb},
{ST7789_DATA, 0x3d},
{ST7789_CMD, 0xc2},
{ST7789_DATA, 0x01},
{ST7789_CMD, 0xc3},
{ST7789_DATA, 0x19},
{ST7789_CMD, 0xc4},
{ST7789_DATA, 0x20},
{ST7789_CMD, 0xc6},
{ST7789_DATA, 0x0f},
{ST7789_CMD, 0xd0},
{ST7789_DATA, 0xa4},
{ST7789_DATA, 0xa1},
{ST7789_CMD, 0xe0},
{ST7789_DATA, 0x70},
{ST7789_DATA, 0x04},
{ST7789_DATA, 0x08},
{ST7789_DATA, 0x09},
{ST7789_DATA, 0x09},
{ST7789_DATA, 0x05},
{ST7789_DATA, 0x2a},
{ST7789_DATA, 0x33},
{ST7789_DATA, 0x41},
{ST7789_DATA, 0x07},
{ST7789_DATA, 0x13},
{ST7789_DATA, 0x13},
{ST7789_DATA, 0x29},
{ST7789_DATA, 0x2f},
{ST7789_CMD, 0xe1},
{ST7789_DATA, 0x70},
{ST7789_DATA, 0x03},
{ST7789_DATA, 0x09},
{ST7789_DATA, 0x0a},
{ST7789_DATA, 0x09},
{ST7789_DATA, 0x06},
{ST7789_DATA, 0x2b},
{ST7789_DATA, 0x34},
{ST7789_DATA, 0x41},
{ST7789_DATA, 0x07},
{ST7789_DATA, 0x12},
{ST7789_DATA, 0x14},
{ST7789_DATA, 0x28},
{ST7789_DATA, 0x2e},
{ST7789_CMD, 0x21},
{ST7789_CMD, 0x29},
{ST7789_CMD, 0x2a},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0xef},
{ST7789_CMD, 0x2b},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0x00},
{ST7789_DATA, 0xef},
{ST7789_CMD, 0x2c},
{ST7789_END, ST7789_END},
};
//ST7789復(fù)位
static void st7789_reset(void)
{
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
HAL_Delay(120);
}
//打開LCD電源
void st7789_power_on(void)
{
HAL_GPIO_WritePin(LCD_PWR_GPIO_Port, LCD_PWR_Pin, GPIO_PIN_SET);
}
//ST7789寫函數(shù)
static HAL_StatusTypeDef st7789_write(int is_cmd, uint8_t data)
{
uint8_t pData[2] = {0};
assert_param(NULL != hspi_lcd);
pData[0] = data;
if (is_cmd)
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
return HAL_SPI_Transmit(hspi_lcd, pData, 1, HAL_MAX_DELAY);
}
static HAL_StatusTypeDef st7789_write_fb(uint16_t *data, uint16_t size)
{
assert_param(NULL != hspi_lcd);
return HAL_SPI_Transmit(hspi_lcd, (uint8_t *)data, size, HAL_MAX_DELAY);
}
/********************************************************************
*
* LcdWriteReg
*
* Function description:
* Sets display register
*/
void LcdWriteReg(uint8_t Data)
{
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, &Data, 1, 10);
}
/********************************************************************
*
* LcdWriteData
*
* Function description:
* Writes a value to a display register
*/
void LcdWriteData(uint8_t Data)
{
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
HAL_SPI_Transmit(&hspi1, &Data, 1, 10);
}
/********************************************************************
*
* LcdWriteDataMultiple
*
* Function description:
* Writes multiple values to a display register.
*/
void LcdWriteDataMultiple(uint8_t * pData, int NumItems)
{
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
HAL_SPI_Transmit(&hspi1, pData, NumItems, 10);
}
//配置啟動參數(shù)
static void st7789_run_cfg_script(void)
{
uint8_t data[2] = {0};
int i = 0;
int end_script = 0;
do {
switch (st7789_cfg_script[i].cmd) {
case ST7789_START:
break;
case ST7789_CMD:
data[0] = st7789_cfg_script[i].data & 0xff;
st7789_write(1, data[0]);
break;
case ST7789_DATA:
data[0] = st7789_cfg_script[i].data & 0xff;
st7789_write(0, data[0]);
break;
case ST7789_DELAY:
HAL_Delay(120);
break;
case ST7789_END:
end_script = 1;
}
i++;
} while (!end_script);
}
//設(shè)置地址
static void st7789_set_addr_win(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye)
{
uint8_t col_data[4] = {0};
uint8_t row_data[4] = {0};
col_data[0] = xs >> 8 & 0xff;
col_data[1] = xs & 0xff;
col_data[2] = xe >> 8 & 0xff;
col_data[3] = xe & 0xff;
row_data[0] = ys >> 8 & 0xff;
row_data[1] = ys & 0xff;
row_data[2] = ye >> 8 & 0xff;
row_data[3] = ye & 0xff;
st7789_write(1, ST7789_CASET);
st7789_write(0, col_data[0]);
st7789_write(0, col_data[1]);
st7789_write(0, col_data[2]);
st7789_write(0, col_data[3]);
st7789_write(1, ST7789_RASET);
st7789_write(0, row_data[0]);
st7789_write(0, row_data[1]);
st7789_write(0, row_data[2]);
st7789_write(0, row_data[3]);
}
//發(fā)送到顯示區(qū)域
static void spec_send_fb(uint16_t color, uint16_t pixel_num)
{
int i;
int count, remain;
uint16_t real_mem[LCD_MAX_MEM16_BLOCK] = {0};
for (i = 0; i < LCD_MAX_MEM16_BLOCK; ++i) {
real_mem[i] = color;
}
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
if (pixel_num <= LCD_MAX_MEM16_BLOCK) {
st7789_write_fb(real_mem, pixel_num << 1);
} else {
count = pixel_num / LCD_MAX_MEM16_BLOCK;
remain = pixel_num % LCD_MAX_MEM16_BLOCK;
for (i = 0; i < count; ++i) {
st7789_write_fb(real_mem, LCD_MAX_MEM16_BLOCK << 1);
}
st7789_write_fb(real_mem, remain << 1);
}
}
//顯示圖片
void st7789_display_picture(void)
{
st7789_write(1, ST7789_RAMWR);
spec_send_fb(0x0, WIDTH * HEIGHT / 4);
spec_send_fb(0x1111, WIDTH * HEIGHT / 4);
spec_send_fb(0x7777, WIDTH * HEIGHT / 4);
spec_send_fb(0xeeee, WIDTH * HEIGHT / 4);
}
//寫寄存器
void ST7789H2_WriteReg(uint8_t Command, uint8_t *Parameters, uint8_t NbParameters)
{
uint8_t i;
/* Send command */
LcdWriteReg(Command);
/* Send command's parameters if any */
for (i=0; i<NbParameters; i++)
{
LcdWriteData(Parameters[i]);
}
}
//在指定位置設(shè)置光標(biāo)
void ST7789H2_SetCursor(uint16_t Xpos, uint16_t Ypos)
{
uint8_t parameter[4];
/* CASET: Comumn Addrses Set */
parameter[0] = 0x00;
parameter[1] = 0x00 + Xpos;
parameter[2] = 0x00;
parameter[3] = 0xEF + Xpos;
ST7789H2_WriteReg(0x2A, parameter, 4);
/* RASET: Row Addrses Set */
parameter[0] = 0x00;
parameter[1] = 0x00 + Ypos;
parameter[2] = 0x00;
parameter[3] = 0xEF + Ypos;
ST7789H2_WriteReg(0x2B, parameter, 4);
}
//清屏
void BSP_LCD_Clear(void)
{
uint32_t counter = 0;
uint32_t y_size = 0;
memset(black_gui, 0x00, sizeof(black_gui));
for (counter = 0; counter < 240; counter++)
{
/* Set Cursor */
ST7789H2_SetCursor(0, counter);
/* Prepare to write to LCD RAM */
ST7789H2_WriteReg(0x2C, (uint8_t*)NULL, 0); /* RAM write data command */
LcdWriteDataMultiple(black_gui, 480);
}
}
//往指定區(qū)域?qū)懸粋€像素
void ST7789H2_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t data)
{
uint8_t dataB = 0;
/* Set Cursor */
ST7789H2_SetCursor(Xpos, Ypos);
/* Prepare to write to LCD RAM */
ST7789H2_WriteReg(0x2C, (uint8_t*)NULL, 0); /* RAM write data command */
/* Write RAM data */
dataB = (uint8_t)(data >> 8);
LcdWriteData(dataB);
dataB = (uint8_t)data;
LcdWriteData(dataB);
}
//往指定區(qū)域?qū)懸恍袛?shù)據(jù)
void ST7789H2_WriteLine(uint16_t Xpos, uint16_t Ypos, uint16_t *RGBCode, uint16_t pointNum)
{
int i = 0;
/* Set Cursor */
ST7789H2_SetCursor(Xpos, Ypos);
/* Prepare to write to LCD RAM */
ST7789H2_WriteReg(0x2C, (uint8_t*)NULL, 0); /* RAM write data command */
for (i = 0; i < pointNum; i++) {
endian_buffer[2*i] = (uint8_t)(RGBCode[i] >> 8);
endian_buffer[2*i + 1] = (uint8_t)RGBCode[i];
}
/* Write RAM data */
LcdWriteDataMultiple(endian_buffer, pointNum*2);
}
//ST7789初始化
int st7789_init(void)
{
hspi_lcd = &hspi1;
st7789_power_on();
st7789_reset();
st7789_run_cfg_script();
return HAL_OK;
}
在main.c中添加邏輯:
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
st7789_init();
st7789_display_picture();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_Delay(200);
}
/* USER CODE END 3 */
}
四、運(yùn)行結(jié)果
https://github.com/alibaba/AliOS-Things/wiki/Developer-Kit-Tutorial
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!