我们生活在一个色彩缤纷的世界,尽管我们可以分辨出不同的色彩,但我们却无法叫出它们每一个的名字。
那么我们能够将它们展现出来吗?
这个是可以做到的,那就是在屏幕上绘制一幅全彩的色度变化图,图1就是其应用于色彩分析仪的场景及效果。

图1 应用场景及效果
那该任何来实现呢?
1)硬件构成
在硬件方面,需要有开发板和显示屏的配合,这里选取的是RA-Eco-RA2E1-V1.0开发板和一个128*160像素的彩色显示屏。
其中,显示屏与开发板的连接关系如下:
CS ----P407
REST----P408
DC---P409
BL ---VCC
SDI ----P213
SCK ----P100
2)软件设计
在显示屏的驱动方面,可分为模拟驱动方式和SPI硬件驱动方式,这里选择的是硬件驱动方式。
为驱动显示屏,可使用RASC来配置引脚并生成KEIL项目工程。
具体的步骤为:
在栈中添加SPI,见图2所示。

图2 添加SPI
按图3所示来配置参数及按图4所示来配置辅助引脚,并在完成引脚配置后,点击“Generate Project Content”来生成Keil项目工程。

图3 配置参数

图4 辅助引脚配置
在生成KEIL项目工程后,需在程序中添加以下关键函数:
SPI的初始化函数为:
void SCI_SPI_Init(void)
{
fsp_err_t err = R_SCI_SPI_Open(&g_spi1_ctrl,&g_spi1_cfg);
assert(err == FSP_SUCCESS);
}SPI的中断回调函数为:
void sci_spi_callback(spi_callback_args_t *arg)
{
if(arg->event == SPI_EVENT_TRANSFER_COMPLETE)
{
sci_spi_send_complete_flag = true;
}
}写字节数据的函数为:
void LCD_WriteData(uint8_t data)
{
CS_Clr;
DC_Set;
R_SCI_SPI_Write(&g_spi1_ctrl,(uint8_t*)&data,1,SPI_BIT_WIDTH_8_BITS);
while(!sci_spi_send_complete_flag);
sci_spi_send_complete_flag = false;
CS_Set;
}写字节指令的函数为:
void LCD_WriteCommond(uint8_t cmd)
{
CS_Clr;
DC_Clr;
R_SCI_SPI_Write(&g_spi1_ctrl,(uint8_t*)&cmd,1,SPI_BIT_WIDTH_8_BITS);
while(!sci_spi_send_complete_flag);
sci_spi_send_complete_flag = false;
CS_Set;
}写16位数据的函数为:
void LCD_WriteData16(uint16_t data)
{
uint8_t buffer[2];
buffer[0] = (uint8_t)(data >> 8);
buffer[1] = (uint8_t)data;
CS_Clr;
DC_Set;
R_SCI_SPI_Write(&g_spi1_ctrl,(uint8_t*)&buffer[0],1,SPI_BIT_WIDTH_8_BITS);
while(!sci_spi_send_complete_flag);
sci_spi_send_complete_flag = false;
R_SCI_SPI_Write(&g_spi1_ctrl,(uint8_t*)&buffer[1],1,SPI_BIT_WIDTH_8_BITS);
while(!sci_spi_send_complete_flag);
sci_spi_send_complete_flag = false;
CS_Set;
}显示屏的初始化函数为:
void LCD_Init(void)
{
SCI_SPI_Init();
RST_Clr;
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
RST_Set;
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
LCD_WriteCommond(0x11);
R_BSP_SoftwareDelay(120, BSP_DELAY_UNITS_MILLISECONDS);
LCD_WriteCommond(0xB1);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteCommond(0xB2);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteCommond(0xB3);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteCommond(0xB4);
LCD_WriteData(0x03);
LCD_WriteCommond(0xC0);
LCD_WriteData(0x28);
LCD_WriteData(0x08);
LCD_WriteData(0x04);
LCD_WriteCommond(0xC1);
LCD_WriteData(0XC0);
LCD_WriteCommond(0xC2);
LCD_WriteData(0x0D);
LCD_WriteData(0x00);
LCD_WriteCommond(0xC3);
LCD_WriteData(0x8D);
LCD_WriteData(0x2A);
LCD_WriteCommond(0xC4);
LCD_WriteData(0x8D);
LCD_WriteData(0xEE);
LCD_WriteCommond(0xC5);
LCD_WriteData(0x1A);
LCD_WriteCommond(0x36);
LCD_WriteData(0x00);
LCD_WriteCommond(0xE0);
LCD_WriteData(0x04);
LCD_WriteData(0x22);
LCD_WriteData(0x07);
LCD_WriteData(0x0A);
LCD_WriteData(0x2E);
LCD_WriteData(0x30);
LCD_WriteData(0x25);
LCD_WriteData(0x2A);
LCD_WriteData(0x28);
LCD_WriteData(0x26);
LCD_WriteData(0x2E);
LCD_WriteData(0x3A);
LCD_WriteData(0x00);
LCD_WriteData(0x01);
LCD_WriteData(0x03);
LCD_WriteData(0x13);
LCD_WriteCommond(0xE1);
LCD_WriteData(0x04);
LCD_WriteData(0x16);
LCD_WriteData(0x06);
LCD_WriteData(0x0D);
LCD_WriteData(0x2D);
LCD_WriteData(0x26);
LCD_WriteData(0x23);
LCD_WriteData(0x27);
LCD_WriteData(0x27);
LCD_WriteData(0x25);
LCD_WriteData(0x2D);
LCD_WriteData(0x3B);
LCD_WriteData(0x00);
LCD_WriteData(0x01);
LCD_WriteData(0x04);
LCD_WriteData(0x13);
LCD_WriteCommond(0x3A);
LCD_WriteData(0x05);
LCD_WriteCommond(0x29);
}绘制色彩环的函数为:
void draw_circular()
{
uint16_t color ;
int center_x = 128 / 2;
int center_y = 160 / 2;
float max_distance = sqrtf(center_x * center_x + center_y * center_y);
for (int y = 0; y < 160; y++)
{
for (int x = 0; x < 128; 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);
color=(( r>>3)<<11)+((g>>2)<<5)+(b>>3);
LCD_Address_Set(x, y, x+1, y+1);
LCD_WriteData16(color);
}
}
}实现功能测试的主程序为:
void hal_entry(void)
{
LCD_Init();
Lcd_Clear(MAGENTA);
draw_circular();
while(1);
}经程序的编译和下载,其测试效果如图5所示,说明程序设计有效。

图5 绘制色彩环形图
演示视频:
我要赚赏金
