瑞萨 R7FA4E2 有 2 个 SPI 接口,除此之外,还有 2 个 SCI 接口可以实现 Simple SPI 功能,这次使用 SPI0 接口来驱动 LCD 屏
ST7796U 是一款支持 320x480 像素的 LCD 控制器,并且能够支持 RGB565、RGB666 颜色深度,效果如图:

开发板兼容 PMOD 接口,SPI 引脚与 PMOD 相关引脚位置对应:

接口定义如下:
| 引脚 |
功能 |
|---|
| P111 |
SCK |
| P109 |
MOSI |
| P110 |
DC |
| P408 |
RST |
| P301 |
CS |
使能硬件 SPI0 功能,在 RASC 上配置如下:
引脚配置:

SPI 外设配置:

配置 SPI0 速率 32Mbps,使能后即可使用以下函数初始化 SPI0 接口:
fsp_err_t err = R_SPI_Open(&g_spi0_ctrl, &g_spi0_cfg)
使用以下函数发送数据:
fsp_err_t err = R_SPI_Write(&g_spi0_ctrl, &dat, 1, SPI_BIT_WIDTH_8_BITS);
未使用 DMA,采用的是中断清除标志位方式进行 SPI 数据发送,代码如下:
void SPI0_Tx1B(u16 dat)
{
while (gf_SPI0_Busy);
gf_SPI0_Busy = 1;
fsp_err_t err = R_SPI_Write(&g_spi0_ctrl, &dat, 1, SPI_BIT_WIDTH_8_BITS);
assert(err == FSP_SUCCESS);
}
中断函数中清除发送忙标志位:
void spi0_callback (spi_callback_args_t * p_args)
{
if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event)
{
gf_SPI0_Busy = 0;
}
}
设置好 SPI 接口后,就可以进行初始化寄存器配置和图像显示了
显示色盘代码如下:
#define M_PI 3.14159
void draw_circular_gradient(GUI_t gui) {
int center_x = WIDTH / 2;
int center_y = HEIGHT / 2;
float max_distance = sqrtf(center_x * center_x + center_y * center_y);
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
float dx = x - center_x;
float dy = y - center_y;
float distance = sqrtf(dx * dx + dy * dy);
float angle = atan2f(dy, dx);
if (angle < 0) angle += 2 * M_PI;
uint8_t r, g, b;
if (angle < M_PI / 3) {
float t = angle / (M_PI / 3);
r = 255;
g = (uint8_t)(255 * t);
b = 0;
} else if (angle < 2 * M_PI / 3) {
float t = (angle - M_PI / 3) / (M_PI / 3);
r = (uint8_t)(255 * (1 - t));
g = 255;
b = 0;
} else if (angle < M_PI) {
float t = (angle - 2 * M_PI / 3) / (M_PI / 3);
r = 0;
g = 255;
b = (uint8_t)(255 * t);
} else if (angle < 4 * M_PI / 3) {
float t = (angle - M_PI) / (M_PI / 3);
r = 0;
g = (uint8_t)(255 * (1 - t));
b = 255;
} else if (angle < 5 * M_PI / 3) {
float t = (angle - 4 * M_PI / 3) / (M_PI / 3);
r = (uint8_t)(255 * t);
g = 0;
b = 255;
} else {
float t = (angle - 5 * M_PI / 3) / (M_PI / 3);
r = 255;
g = 0;
b = (uint8_t)(255 * (1 - t));
}
float brightness = 1.0f - (distance / max_distance) * 0.8f;
if (brightness < 0.2f) brightness = 0.2f;
r = (uint8_t)(r * brightness);
g = (uint8_t)(g * brightness);
b = (uint8_t)(b * brightness);
uint16_t color = COLOR_RGB565(r, g, b);
GUI_SetPenColor(gui, color);
GUI_Point(gui, x, y);
}
}
}