This commit is contained in:
qiyongshuang
2026-08-10 10:47:09 +08:00
parent 804daf39a2
commit dfe5ceea43
150 changed files with 20271 additions and 58 deletions
+383
View File
@@ -0,0 +1,383 @@
/*********************************************************************
* File Name : lcd.c
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for lcd screen.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "lcd.h"
#include "debug.h"
#include "LCD_Font.h"
#define LCD_SOFT_RESET (0x01)
#define LCD_READ_ID (0x04)
#define LCD_READ_DISPLAY_STATUS (0x09)
#define LCD_ON (0x28)
#define LCD_OFF (0x29)
#define LCD_SET_X (0x2a)
#define LCD_SET_Y (0x2b)
#define LCD_MEM_WRITE (0x2C)
#define LCD_MEM_READ (0x2e)
static void LCD_WR_REG(uint8_t data)
{
LCD_DC_CLR();
SPI2_Write(data);
}
static void LCD_WR_DATA(uint8_t data)
{
LCD_DC_SET();
SPI2_Write(data);
}
/*********************************************************************
* @fn Lcd_WriteData_16Bit
*
* @brief write two bytes to the lcd screen
*
* @param Data - the data to write
*
* @return none
*/
void Lcd_WriteData_16Bit(uint16_t Data)
{
SPI2_Write(Data >> 8);
SPI2_Write(Data);
}
/*********************************************************************
* @fn LCD_GPIOInit
*
* @brief Configuring the control gpio for the lcd screen
*
* @return none
*/
void LCD_GPIOInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(LCD_LED_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_DC_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_RST_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_CS_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = LCD_LED_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_LED_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_DC_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_DC_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_RST_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_RST_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_CS_PORT, &GPIO_InitStructure);
LCD_LED_CLR();
LCD_CS_SET();
}
/*********************************************************************
* @fn LCD_RESET
*
* @brief reset the lcd screen by the rst pin
*
* @return none
*/
void LCD_RESET(void)
{
Delay_Ms(50);
LCD_RST_CLR();
Delay_Ms(100);
LCD_RST_SET();
Delay_Ms(50);
}
static const uint8_t lcd_st7789_init_cmds[] = {
1,
0x3A,
0x05,
2,
0xB0,
0x00,
0xF0,
5,
0xB2,
0x0C,
0x0C,
0x00,
0x33,
0x33,
1,
0xB7,
0x35,
1,
0xBB,
0x19,
1,
0xC0,
0x2C,
1,
0xC2,
0x01,
1,
0xC3,
0x12,
1,
0xC4,
0x20,
1,
0xC6,
0x0F,
2,
0xD0,
0xA4,
0xA1,
14,
0xE0,
0xD0,
0x04,
0x0D,
0x11,
0x13,
0x2B,
0x3F,
0x54,
0x4C,
0x18,
0x0D,
0x0B,
0x1F,
0x23,
14,
0xE1,
0xD0,
0x04,
0x0C,
0x11,
0x13,
0x2C,
0x3F,
0x44,
0x51,
0x2F,
0x1F,
0x1F,
0x20,
0x23,
0,
0x21,
1,
0x36,
#if USE_HORIZONTAL == 0
0,
#elif USE_HORIZONTAL == 1
(1 << 7) | (1 << 6) | (0 << 5),
#elif USE_HORIZONTAL == 2
(1 << 6) | (0 << 7) | (1 << 5),
#elif USE_HORIZONTAL == 3
(1 << 7) | (1 << 5),
#endif
0,
0x11,
0,
0x29,
0xff,
0xff,
};
void LCD_exec_init(uint8_t* init_code)
{
uint8_t* p = init_code;
uint8_t data_len;
uint8_t cmd;
LCD_CS_CLR();
while (1)
{
data_len = *p++;
cmd = *p++;
if (cmd == 0xFF)
{
break;
}
LCD_WR_REG(cmd);
for (uint8_t i = 0; i < data_len; i++)
{
LCD_WR_DATA(*p++);
}
}
LCD_CS_SET();
}
void LCD_Init(void)
{
SPI2_Init();
SPI2_DMA_Init();
LCD_GPIOInit();
LCD_RESET();
LCD_CS_CLR();
LCD_WR_REG(0x28);
LCD_exec_init((uint8_t*)lcd_st7789_init_cmds);
Delay_Ms(10);
LCD_Clear(LCD_BLACK);
Delay_Ms(10);
LCD_LED_SET();
}
/*********************************************************************
* @fn LCD_SetWindows
*
* @brief Setting LCD display window
*
* @param xStar - the bebinning x coordinate of the LCD display window
* yStar - the bebinning y coordinate of the LCD display window
* xEnd - the endning x coordinate of the LCD display window
* yEnd - the endning y coordinate of the LCD display window
*
* @return none
*/
void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
{
LCD_CS_CLR();
LCD_WR_REG(LCD_SET_X);
LCD_WR_DATA(xStar >> 8);
LCD_WR_DATA(0x00FF & xStar);
LCD_WR_DATA(xEnd >> 8);
LCD_WR_DATA(0x00FF & xEnd);
LCD_WR_REG(LCD_SET_Y);
LCD_WR_DATA(yStar >> 8);
LCD_WR_DATA(0x00FF & yStar);
LCD_WR_DATA(yEnd >> 8);
LCD_WR_DATA(0x00FF & yEnd);
LCD_WR_REG(LCD_MEM_WRITE);
LCD_CS_SET();
}
// 设置引脚为高电平
void LCD_LED_SET(void)
{
LCD_LED_PORT->BSHR = LCD_LED_PIN;
}
void LCD_CS_SET(void)
{
LCD_CS_PORT->BSHR = LCD_CS_PIN;
}
void LCD_DC_SET(void)
{
LCD_DC_PORT->BSHR = LCD_DC_PIN;
}
void LCD_RST_SET(void)
{
LCD_RST_PORT->BSHR = LCD_RST_PIN;
}
// 设置引脚为低电平
void LCD_LED_CLR(void)
{
LCD_LED_PORT->BCR = LCD_LED_PIN;
}
void LCD_CS_CLR(void)
{
LCD_CS_PORT->BCR = LCD_CS_PIN;
}
void LCD_DC_CLR(void)
{
LCD_DC_PORT->BCR = LCD_DC_PIN;
}
void LCD_RST_CLR(void)
{
LCD_RST_PORT->BCR = LCD_RST_PIN;
}
void SPI1_wait_for_bsy()
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
;
}
void SPI2_wait_for_bsy()
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)
;
}
void SPI2_wait_for_txe()
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
;
}
void SPI1_wait_for_DMA()
{
while (SPI1_DMA_TX_CH->CNTR > 0)
{
}
}
void SPI2_wait_for_DMA()
{
while (SPI2_DMA_TX_CH->CNTR > 0)
{
}
}
void LCD_Clear(uint16_t color)
{
LCD_Fill(0, 0, LCD_W, LCD_H, color);
}
@@ -0,0 +1,84 @@
/*********************************************************************
* File Name : lcd.h
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for lcd screen.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __LCD_H
#define __LCD_H
#include "spi.h"
#include "stdio.h"
#include "stdlib.h"
#include "flash.h"
#include "config.h"
#define USE_HORIZONTAL 2
#if USE_HORIZONTAL == 0 || USE_HORIZONTAL == 1
#define LCD_W 240
#define LCD_H 320
#endif
#if USE_HORIZONTAL == 2 || USE_HORIZONTAL == 3
#define LCD_W 320
#define LCD_H 240
#endif
#define LCD_WIDTH LCD_W
#define LCD_HEIGHT LCD_H
#define LCD_SWAP16(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF))
#define RGB888_TO_RGB565(r, g, b) LCD_SWAP16((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))
#define RGB24_TO_RGB565(rgb) LCD_SWAP16((((rgb) >> 8) & 0xF800) | (((rgb) >> 5) & 0x07E0) | (((rgb) >> 3) & 0x001F))
#define LCD_red RGB888_TO_RGB565(255, 0, 0)
#define LCD_green RGB888_TO_RGB565(0, 255, 0)
#define LCD_blue RGB888_TO_RGB565(0, 0, 255)
#define LCD_white RGB888_TO_RGB565(255, 255, 255)
#define LCD_gray RGB888_TO_RGB565(128, 128, 128)
#define LCD_black RGB888_TO_RGB565(0, 0, 0)
#define LCD_yellow RGB888_TO_RGB565(255, 255, 0)
#define LCD_WHITE LCD_white
#define LCD_BLACK LCD_black
#define LCD_BLUE LCD_blue
#define LCD_RED LCD_red
#define LCD_MAGENTA RGB888_TO_RGB565(255, 0, 255)
#define LCD_GREEN LCD_green
#define LCD_CYAN RGB888_TO_RGB565(0, 255, 255)
#define LCD_YELLOW LCD_yellow
#define LCD_BROWN RGB888_TO_RGB565(165, 42, 42)
#define LCD_GRAY LCD_gray
void LCD_LED_SET(void);
void LCD_CS_SET(void);
void LCD_DC_SET(void);
void LCD_RST_SET(void);
void LCD_LED_CLR(void);
void LCD_CS_CLR(void);
void LCD_DC_CLR(void);
void LCD_RST_CLR(void);
void SPI1_wait_for_bsy();
void SPI2_wait_for_bsy();
void SPI2_wait_for_txe();
void SPI1_wait_for_DMA();
void SPI2_wait_for_DMA();
void LCD_Init(void);
void LCD_Clear(uint16_t Color);
void Lcd_WriteData_16Bit(uint16_t Data);
void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd);
void LCD_Fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);
#endif
@@ -0,0 +1,200 @@
#include "LCD_Font.h"
#include "wui.h"
//12*12
const unsigned char asc2_1206[95][12]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
};
//16*16
const unsigned char asc2_1608[95][16]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
};
@@ -0,0 +1,18 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : lcd_font.h
* Author : WCH
* Version : V1.0.1
* Date : 2025/09/15
* Description : ASCII character library.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __LCD_FONT_H
#define __LCD_FONT_H
extern const unsigned char asc2_1206[95][12];
extern const unsigned char asc2_1608[95][16];
#endif
@@ -0,0 +1,36 @@
/*********************************************************************
* File Name : config.h
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for Config.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __CONFIG_H__
#define __CONFIG_H__
/* SPI FLASH and LCD_SCREEN GPIO Definition */
#define FLASH_CS_PORT GPIOA
#define FLASH_CS_RCC RCC_APB2Periph_GPIOA
#define FLASH_CS_PIN (GPIO_Pin_4)
#define LCD_LED_RCC RCC_APB2Periph_GPIOB
#define LCD_LED_PORT GPIOB
#define LCD_LED_PIN (GPIO_Pin_9)
#define LCD_DC_RCC RCC_APB2Periph_GPIOB
#define LCD_DC_PORT GPIOB
#define LCD_DC_PIN (GPIO_Pin_10)
#define LCD_RST_RCC RCC_APB2Periph_GPIOB
#define LCD_RST_PORT GPIOB
#define LCD_RST_PIN (GPIO_Pin_11)
#define LCD_CS_RCC RCC_APB2Periph_GPIOB
#define LCD_CS_PORT GPIOB
#define LCD_CS_PIN (GPIO_Pin_12)
#endif
@@ -0,0 +1,465 @@
/*********************************************************************
* File Name : flash.c
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for spi flash.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "flash.h"
#include "spi.h"
static uint8_t FLASH_readWrite(uint8_t TxData)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
;
SPI_I2S_SendData(SPI1, TxData);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
;
return SPI_I2S_ReceiveData(SPI1);
}
/*********************************************************************
* @fn cs_pin_init
*
* @brief gpio cs pin init
*
* @return none
*/
static void cs_pin_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(FLASH_CS_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = FLASH_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(FLASH_CS_PORT, &GPIO_InitStructure);
}
/*********************************************************************
* @fn SPI_FLASH_Init
*
* @brief SPI FLASH Init
*
* @return none
*/
void SPI_FLASH_Init(void)
{
SPI1_Init();
SPI1_Read_DMA_Init();
cs_pin_init();
FLASH_CS_SET;
}
/*********************************************************************
* @fn SPI_Flash_ReadSR
*
* @brief Read W25Qxx status register.
* !!BIT7 6 5 4 3 2 1 0
* !!SPR RV TB BP2 BP1 BP0 WEL BUSY
*
* @return byte - status register value.
*/
uint8_t SPI_Flash_ReadSR(void)
{
uint8_t byte = 0;
FLASH_CS_CLR;
FLASH_readWrite(W25X_ReadStatusReg);
byte = FLASH_readWrite(0Xff);
FLASH_CS_SET;
return byte;
}
/*********************************************************************
* @fn SPI_FLASH_Write_SR
*
* @brief Write W25Qxx status register.
*
* @param sr - status register value.
*
* @return none
*/
void SPI_FLASH_Write_SR(uint8_t sr)
{
FLASH_CS_CLR;
FLASH_readWrite(W25X_WriteStatusReg);
FLASH_readWrite(sr);
FLASH_CS_SET;
}
/*********************************************************************
* @fn SPI_Flash_Wait_Busy
*
* @brief Wait flash free.
*
* @return none
*/
void SPI_Flash_Wait_Busy(void)
{
while ((SPI_Flash_ReadSR() & 0x01) == 0x01)
;
}
/*********************************************************************
* @fn SPI_FLASH_Write_Enable
*
* @brief Enable flash write.
*
* @return none
*/
void SPI_FLASH_Write_Enable(void)
{
FLASH_CS_CLR;
FLASH_readWrite(W25X_WriteEnable);
FLASH_CS_SET;
}
/*********************************************************************
* @fn SPI_FLASH_Write_Disable
*
* @brief Disable flash write.
*
* @return none
*/
void SPI_FLASH_Write_Disable(void)
{
FLASH_CS_CLR;
FLASH_readWrite(W25X_WriteDisable);
FLASH_CS_SET;
}
/*********************************************************************
* @fn SPI_Flash_ReadID
*
* @brief Read flash ID.
*
* @return Temp - FLASH ID.
*/
uint16_t SPI_Flash_ReadID(void)
{
uint16_t Temp = 0;
FLASH_CS_CLR;
FLASH_readWrite(W25X_ManufactDeviceID);
FLASH_readWrite(0x00);
FLASH_readWrite(0x00);
FLASH_readWrite(0x00);
Temp |= FLASH_readWrite(0xFF) << 8;
Temp |= FLASH_readWrite(0xFF);
FLASH_CS_SET;
return Temp;
}
/*********************************************************************
* @fn SPI_Flash_ReadJedecDeviceID
*
* @brief Read JedecDevice ID.
*
* @return JedecDevice ID.
*/
uint32_t SPI_Flash_ReadJedecDeviceID(void)
{
uint32_t Temp = 0;
FLASH_CS_CLR;
FLASH_readWrite(W25X_JedecDeviceID);
Temp |= FLASH_readWrite(0xFF) << 16;
Temp |= FLASH_readWrite(0xFF) << 8;
Temp |= FLASH_readWrite(0xFF);
FLASH_CS_SET;
return Temp;
}
/*********************************************************************
* @fn SPI_Flash_Erase_Sector
*
* @brief Erase one sector(4Kbyte).
*
* @param Dst_Addr - 0 !! 2047
*
* @return none
*/
void SPI_Flash_Erase_Sector(uint32_t Dst_Addr)
{
Dst_Addr *= 4096;
SPI_FLASH_Write_Enable();
SPI_Flash_Wait_Busy();
FLASH_CS_CLR;
FLASH_readWrite(W25X_SectorErase);
FLASH_readWrite((uint8_t)((Dst_Addr) >> 16));
FLASH_readWrite((uint8_t)((Dst_Addr) >> 8));
FLASH_readWrite((uint8_t)Dst_Addr);
FLASH_CS_SET;
SPI_Flash_Wait_Busy();
}
/*********************************************************************
* @fn SPI_Flash_Read
*
* @brief Read data from flash.
*
* @param pBuffer -
* ReadAddr -Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t size)
{
uint16_t i;
FLASH_CS_CLR;
FLASH_readWrite(W25X_ReadData);
FLASH_readWrite((uint8_t)((ReadAddr) >> 16));
FLASH_readWrite((uint8_t)((ReadAddr) >> 8));
FLASH_readWrite((uint8_t)ReadAddr);
for (i = 0; i < size; i++)
{
pBuffer[i] = FLASH_readWrite(0XFF);
}
FLASH_CS_SET;
}
/*********************************************************************
* @fn SPI_Flash_Write_Page
*
* @brief Write data by one page.
*
* @param pBuffer -
* WriteAddr - Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size)
{
uint16_t i;
SPI_FLASH_Write_Enable();
FLASH_CS_CLR;
FLASH_readWrite(W25X_PageProgram);
FLASH_readWrite((uint8_t)((WriteAddr) >> 16));
FLASH_readWrite((uint8_t)((WriteAddr) >> 8));
FLASH_readWrite((uint8_t)WriteAddr);
for (i = 0; i < size; i++)
{
FLASH_readWrite(pBuffer[i]);
}
FLASH_CS_SET;
SPI_Flash_Wait_Busy();
}
/*********************************************************************
* @fn SPI_Flash_Write_NoCheck
*
* @brief Write data to flash.(need Erase)
* All data in address rang is 0xFF.
*
* @param pBuffer -
* WriteAddr - Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size)
{
uint16_t pageremain;
pageremain = 256 - WriteAddr % 256;
if (size <= pageremain)
pageremain = size;
while (1)
{
SPI_Flash_Write_Page(pBuffer, WriteAddr, pageremain);
if (size == pageremain)
{
break;
}
else
{
pBuffer += pageremain;
WriteAddr += pageremain;
size -= pageremain;
if (size > 256)
pageremain = 256;
else
pageremain = size;
}
}
}
static uint8_t W25QXX_BUFFER[4096];
/*********************************************************************
* @fn SPI_Flash_Write
*
* @brief Write data to flash.(no need Erase)
*
* @param pBuffer -
* WriteAddr - Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size)
{
uint32_t secpos;
uint16_t secoff;
uint16_t secremain;
uint16_t i;
secpos = WriteAddr / 4096;
secoff = WriteAddr % 4096;
secremain = 4096 - secoff;
if (size <= secremain)
secremain = size;
while (1)
{
SPI_Flash_Read(W25QXX_BUFFER, secpos * 4096, 4096);
for (i = 0; i < secremain; i++)
{
if (W25QXX_BUFFER[secoff + i] != 0XFF)
break;
}
if (i < secremain)
{
SPI_Flash_Erase_Sector(secpos);
for (i = 0; i < secremain; i++)
{
W25QXX_BUFFER[i + secoff] = pBuffer[i];
}
SPI_Flash_Write_NoCheck(W25QXX_BUFFER, secpos * 4096, 4096);
}
else
{
SPI_Flash_Write_NoCheck(pBuffer, WriteAddr, secremain);
}
if (size == secremain)
{
break;
}
else
{
secpos++;
secoff = 0;
pBuffer += secremain;
WriteAddr += secremain;
size -= secremain;
if (size > 4096)
{
secremain = 4096;
}
else
{
secremain = size;
}
}
}
}
/*********************************************************************
* @fn SPI_Flash_Erase_Block
*
* @brief Erase all FLASH pages.
*
*
* @return none
*/
void SPI_Flash_Erase_Block(uint32_t Dst_Addr)
{
SPI_FLASH_Write_Enable();
SPI_Flash_Wait_Busy();
FLASH_CS_CLR;
FLASH_readWrite(W25X_BlockErase);
FLASH_readWrite((uint8_t)((Dst_Addr) >> 16));
FLASH_readWrite((uint8_t)((Dst_Addr) >> 8));
FLASH_readWrite((uint8_t)Dst_Addr);
FLASH_CS_SET;
SPI_Flash_Wait_Busy();
}
/*********************************************************************
* @fn SPI_Flash_PowerDown
*
* @brief Enter power down mode.
*
* @return none
*/
void SPI_Flash_PowerDown(void)
{
FLASH_CS_CLR;
FLASH_readWrite(W25X_PowerDown);
FLASH_CS_SET;
Delay_Us(3);
}
/*********************************************************************
* @fn SPI_Flash_WAKEUP
*
* @brief Power down wake up.
*
* @return none
*/
void SPI_Flash_WAKEUP(void)
{
FLASH_CS_CLR;
FLASH_readWrite(W25X_ReleasePowerDown);
FLASH_CS_SET;
Delay_Us(3);
}
/*********************************************************************
* @fn SPI_Flash_Read_dma_start
*
* @brief enable spi dma and set read address
*
* @param ReadAddr - the address in spi flash
*
* @return none
*/
void SPI_Flash_Read_dma_start(uint32_t ReadAddr)
{
FLASH_CS_CLR;
FLASH_readWrite(W25X_FastReadData);
FLASH_readWrite((uint8_t)((ReadAddr) >> 16));
FLASH_readWrite((uint8_t)((ReadAddr) >> 8));
FLASH_readWrite((uint8_t)ReadAddr);
FLASH_readWrite(0xFF);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);
}
/*********************************************************************
* @fn SPI_Flash_Read_dma_end
*
* @brief disable spi dma
*
* @return none
*/
void SPI_Flash_Read_dma_end(void)
{
FLASH_CS_SET;
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE);
}
@@ -0,0 +1,57 @@
/*********************************************************************
* File Name : flash.h
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for spi flash.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __SPI_FLASH_H
#define __SPI_FLASH_H
#include "debug.h"
#include "spi.h"
#include "config.h"
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
#define FLASH_CS_SET (FLASH_CS_PORT->BSHR = FLASH_CS_PIN)
#define FLASH_CS_CLR (FLASH_CS_PORT->BCR = FLASH_CS_PIN)
void SPI_FLASH_Init(void);
uint8_t SPI_Flash_ReadSR(void);
void SPI_FLASH_Write_SR(uint8_t sr);
void SPI_Flash_Wait_Busy(void);
void SPI_FLASH_Write_Enable(void);
void SPI_FLASH_Write_Disable(void);
uint16_t SPI_Flash_ReadID(void);
uint32_t SPI_Flash_ReadJedecDeviceID(void);
void SPI_Flash_Erase_Sector(uint32_t Dst_Addr);
void SPI_Flash_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t size);
void SPI_Flash_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size);
void SPI_Flash_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size);
void SPI_Flash_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size);
void SPI_Flash_Erase_Chip(void);
void SPI_Flash_PowerDown(void);
void SPI_Flash_WAKEUP(void);
void SPI_Flash_Read_dma_start(uint32_t ReadAddr);
void SPI_Flash_Read_dma_end(void);
#endif
+247
View File
@@ -0,0 +1,247 @@
/*********************************************************************
* File Name : spi.c
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for spi.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "spi.h"
/*********************************************************************
* @fn SPI1_Init
*
* @brief Initialize SPI1
*
* @return none
*/
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
SPI_InitTypeDef SPI_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
SPI1->HSCR = 1;
}
/*********************************************************************
* @fn SPI1_Read_DMA_Init
*
* @brief Initialize DMA for SPI1, In this condition every time send 0XFF to read data
*
* @return none
*/
void SPI1_Read_DMA_Init()
{
static uint32_t DummyByte = 0xff;
DMA_InitTypeDef DMA_InitStructure = {0};
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// Tx
DMA_DeInit(SPI1_DMA_TX_CH);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DATAR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DummyByte;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI1_DMA_TX_CH, &DMA_InitStructure);
// Rx
DMA_DeInit(SPI1_DMA_RX_CH);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DATAR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI1_DMA_RX_CH, &DMA_InitStructure);
}
/*********************************************************************
* @fn SPI1_Read_DMA
*
* @brief read data from SPI1 via DMA
*
* @param data - the data to recive
* len - read length
*
* @return none
*/
void SPI1_Read_DMA(uint8_t* data, uint16_t len)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
;
DMA_Cmd(SPI1_DMA_TX_CH, DISABLE);
DMA_Cmd(SPI1_DMA_RX_CH, DISABLE);
DMA_ClearFlag(DMA1_FLAG_TC3);
DMA_ClearFlag(DMA1_FLAG_TC3);
SPI1_DMA_TX_CH->CNTR = len;
SPI1_DMA_RX_CH->MADDR = (uint32_t)data;
SPI1_DMA_RX_CH->CNTR = len;
DMA_Cmd(SPI1_DMA_TX_CH, ENABLE);
DMA_Cmd(SPI1_DMA_RX_CH, ENABLE);
}
/*********************************************************************
* @fn SPI2_Init
*
* @brief Initialize SPI2
*
* @return none
*/
void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
SPI_InitTypeDef SPI_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
}
/*********************************************************************
* @fn SPI2_DMA_Init
*
* @brief Initialize DMA for SPI2
*
* @return none
*/
void SPI2_DMA_Init()
{
DMA_InitTypeDef DMA_InitStructure = {0};
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(SPI2_DMA_TX_CH);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DATAR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI2_DMA_TX_CH, &DMA_InitStructure);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
}
/*********************************************************************
* @fn SPI2_Write
*
* @brief send one byte
*
* @param data - the data to send
*
* @return none
*/
void SPI2_Write(uint8_t data)
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
;
SPI_I2S_SendData(SPI2, data);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)
;
}
/*********************************************************************
* @fn SPI2_Write_DMA
*
* @brief send a lot of data
*
* @param data - the data to be send
* len - the length of data
*
* @return none
*/
void SPI2_Write_DMA(uint8_t* data, uint16_t len)
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)
;
DMA_Cmd(SPI2_DMA_TX_CH, DISABLE);
DMA_ClearFlag(SPI2_DMA_TC_FLAG);
SPI2_DMA_TX_CH->MADDR = (uint32_t)data;
SPI2_DMA_TX_CH->CNTR = len;
SPI2_DMA_TX_CH->CFGR = 0x2090;
DMA_Cmd(SPI2_DMA_TX_CH, ENABLE);
}
@@ -0,0 +1,39 @@
/*********************************************************************
* File Name : spi.h
* Author : WCH
* Version : V1.0.0
* Date : 2023/8/15
* Description : file for spi.
*********************************************************************************
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __SPI_H__
#define __SPI_H__
#include "debug.h"
#include "config.h"
#define SPI1_DMA_RX_CH DMA1_Channel2
#define SPI1_DMA_TX_CH DMA1_Channel3
#define SPI1_DMA_TC_FLAG DMA1_FLAG_TC3
#define SPI1_DMA_RC_FLAG DMA1_FLAG_TC2
#define SPI2_DMA_RX_CH DMA1_Channel4
#define SPI2_DMA_TX_CH DMA1_Channel5
#define SPI2_DMA_TC_FLAG DMA1_FLAG_TC5
#define SPI2_DMA_RC_FLAG DMA1_FLAG_TC4
void SPI1_Init(void);
void SPI1_Read_DMA_Init(void);
void SPI1_Read_DMA(uint8_t *data, uint16_t len);
void SPI2_Init(void);
void SPI2_DMA_Init(void);
void SPI2_Write(uint8_t data);
void SPI2_Write_DMA(uint8_t *data, uint16_t len);
#endif