本帖最后由 changweilin 于 2024-3-23 23:58 编辑
HC32F4A0开发板W25Q64芯片读写及LCD显示
1概述
1.1开发板接口
该开发板搭载了QSPI_FLASH型号为W25Q64JVSSIQ,本篇主要测评该芯片的读写功能,查看原理图后发现该开发板还有LCD接口,该接口可以兼容主控为NT35510的LCD屏实现FLASH读写时的显示功能。
1.2开发板原理图
W25Q64芯片的外围电路及接口如图1所示。
图1 W25Q64外围电路及接口示意图
LCD显示屏外围电路及接口如图2所示。
图2 LCD接口及外围电路示意图
1.3测试设备
本次测试所用设备如表1所示,设备实物图如图3所示:
测试设备 |
单位 |
数量 |
EV_F4A0_LQ176_REV1.0开发板 |
块 |
壹 |
ARM仿真器 |
个 |
壹 |
5V电源适配器 |
个 |
壹 |
ALIENTEK 4.3’TFTLCD |
块 |
壹 |
表1 测试设备
图3 开发板实物连接图
2代码编写
2.1LCD驱动函数
编写LCD驱动函数,使其可以显示字符串和数字代码如下
BSP_NT35510.c
#include "BSP_NT35510.h"
#include "FONT.h"
uint32_t g_back_color = 0XFFFF;
static uint32_t lcd_pow(uint8_t m, uint8_t n)
{
uint32_t result = 1;
while (n--) result *= m;
return result;
}
void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height)
{
uint8_t temp, t1, t;
uint16_t y0 = y;
uint8_t csize = 0;
uint8_t *pfont = 0;
csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
chr = chr - ' ';
switch (size)
{
case 12:
pfont = (uint8_t *)asc2_1206[chr];
break;
case 16:
pfont = (uint8_t *)asc2_1608[chr];
break;
case 24:
pfont = (uint8_t *)asc2_2412[chr];
break;
case 32:
pfont = (uint8_t *)asc2_3216[chr];
break;
default:
return ;
}
for (t = 0; t < csize; t++)
{
temp = pfont[t];
for (t1 = 0; t1 < 8; t1++)
{
if (temp & 0x80)
{
BSP_NT35510_WritePixel(x, y, color);
}
else if (mode == 0)
{
BSP_NT35510_WritePixel(x, y, g_back_color);
}
temp <<= 1;
y++;
if (y >= u16Height) return;
if ((y - y0) == size)
{
y = y0;
x++;
if (x >= u16Width) return;
break;
}
}
}
}
void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint16_t color,uint16_t u16Width,uint16_t u16Height)
{
uint8_t x0 = x;
width += x;
height += y;
while ((*p <= '~') && (*p >= ' '))
{
if (x >= width)
{
x = x0;
y += size;
}
if (y >= height) break;
lcd_show_char(x, y, *p, size, 0, color,u16Width,u16Height);
x += size / 2;
p++;
}
}
void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height)
{
uint8_t t, temp;
uint8_t enshow = 0;
for (t = 0; t < len; t++)
{
temp = (num / lcd_pow(10, len - t - 1)) % 10;
if (enshow == 0 && t < (len - 1))
{
if (temp == 0)
{
if (mode & 0X80)
{
lcd_show_char(x + (size / 2) * t, y, '0', size, mode & 0X01, color, u16Width, u16Height);
}
else
{
lcd_show_char(x + (size / 2) * t, y, ' ', size, mode & 0X01, color, u16Width, u16Height);
}
continue;
}
else
{
enshow = 1;
}
}
lcd_show_char(x + (size / 2) * t, y, temp + '0', size, mode & 0X01, color, u16Width, u16Height);
}
}
BSP_NT35510.h
#ifndef __BSP_NT35510_H__
#define __BSP_NT35510_H__
#include "main.h"
void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height);
void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint16_t color,uint16_t u16Width,uint16_t u16Height);
void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height);
#endif
2.2主函数
#include "main.h"
#define SPI_FLASH_DATA_SIZE (256UL)
#define SPI_FLASH_ADDR (0UL)
static uint8_t m_au8WriteData[SPI_FLASH_DATA_SIZE];
static uint8_t m_au8ReadData[SPI_FLASH_DATA_SIZE];
static void LoadData(void);
static void ClearData(void);
static void VerifyData(void);
int32_t main(void)
{
uint16_t u16Width;
uint16_t u16Height;
uint16_t count;
/* MCU Peripheral registers write unprotected */
LL_PERIPH_WE(LL_PERIPH_ALL);
/* Initialize system clock: */
BSP_CLK_Init();
BSP_IO_Init();
BSP_LED_Init();
BSP_LCD_IO_Init();
/* Initialize NT35510 LCD */
BSP_NT35510_Init();
/* Clear LCD screen */
BSP_NT35510_Clear(LCD_COLOR_WHITE);
/* Turn on LCD backlight */
BSP_LCD_BKLCmd(EIO_PIN_SET);
/* Set LCD cursor */
BSP_W25QXX_Init();
/* MCU Peripheral registers write protected */
LL_PERIPH_WP(LL_PERIPH_ALL);
u16Width = BSP_NT35510_GetPixelWidth();
u16Height = BSP_NT35510_GetPixelHeight();
lcd_show_string(20,20,u16Width,32,32,"wirte:",LCD_COLOR_BLACK,u16Width,u16Height);
lcd_show_string(20,100,u16Width,32,32,"read:",LCD_COLOR_BLACK,u16Width,u16Height);
LoadData();
for(count=0;count<SPI_FLASH_DATA_SIZE;count++){
(void)BSP_W25QXX_EraseSector(SPI_FLASH_ADDR);
(void)BSP_W25QXX_Write(SPI_FLASH_ADDR,m_au8WriteData,SPI_FLASH_DATA_SIZE);
(void)BSP_W25QXX_Read(SPI_FLASH_ADDR,m_au8ReadData,SPI_FLASH_DATA_SIZE);
VerifyData();
lcd_show_xnum(20,60,m_au8WriteData[count],3,32,0,LCD_COLOR_BLACK,u16Width,u16Height);
lcd_show_xnum(20,140,m_au8ReadData[count],3,32,0,LCD_COLOR_BLACK,u16Width,u16Height);
BSP_LED_Toggle(LED_BLUE);
ClearData();
}
while(1){};
}
static void LoadData(void)
{
uint32_t i;
for (i = 0UL; i < SPI_FLASH_DATA_SIZE; i++) {
m_au8WriteData[i] = (uint8_t)i;
}
}
static void ClearData(void)
{
uint32_t i;
for (i = 0UL; i < SPI_FLASH_DATA_SIZE; i++) {
m_au8ReadData[i] = 0U;
}
}
static void VerifyData(void)
{
uint32_t i;
for (i = 0UL; i < SPI_FLASH_DATA_SIZE; i++) {
if (m_au8ReadData[i] != m_au8WriteData[i]) {
BSP_LED_Off(LED_BLUE);
BSP_LED_On(LED_RED);
for (;;) {
;
}
}
}
}
3实验现象
3.1实验现象分析
试验现象应为,每读写一次FLASH,LCD显示屏刷新一次,开发板上蓝色LED灯闪烁一次,读写256次后停止。
3.2实验现象
如视频所示: