前面一篇我们介绍了C开发环境的搭建,并使用官方的Demo体验了LCD的显示。
我们看到圆形LCD显示效果不错。一看到圆形LCD肯定想到的就是表盘了,
这一篇我们就来生成一些具备艺术性的表盘。
使用c示例工程,
添加draw.c和draw.h文件
draw.c
#include "LCD_1in28.h"
#include <math.h>
#include <stdint.h>
#define DIM 240
#define DM1 (DIM-1)
#define _sq(x) ((x)*(x)) // square88ikkkkkkkkkkkkkkkkkk
#define _cb(x) abs((x)*(x)*(x)) // absolute value of cube
#define _cr(x) (unsigned char)(pow((x),1.0/3.0)) // cube root
void draw_test1(void)
{
unsigned char RD1(int i,int j){
return (char)(_sq(cos(atan2(j-DIM/2,i-DIM/2)/2))*255);
}
unsigned char GR1(int i,int j){
return (char)(_sq(cos(atan2(j-DIM/2,i-DIM/2)/2-2*acos(-1)/3))*255);
}
unsigned char BL1(int i,int j){
return (char)(_sq(cos(atan2(j-DIM/2,i-DIM/2)/2+2*acos(-1)/3))*255);
}
uint8_t r;
uint8_t g;
uint8_t b;
for(volatile int j=0;j<DIM;j++)
{
for(volatile int i=0;i<DIM;i++)
{
r = RD1(i,j)&255;
g = GR1(i,j)&255;
b = BL1(i,j)&255;
LCD_1IN28_DisplayPoint(i, j, (((uint16_t)r>>3)<<11) | (((uint16_t)g>>2)<<5) | (((uint16_t)b>>3)<<0));
}
}
}
void draw_test2(void)
{
unsigned char RD2(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=DIM/2;return l>255?DIM/2-1-l:l;
}
unsigned char GR2(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=DIM/2;return l>255?DIM/2-1-l:l;
}
unsigned char BL2(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=DIM/2;return l>255?DIM/2-1-l:l;
}
uint8_t r;
uint8_t g;
uint8_t b;
for(volatile int j=0;j<DIM;j++)
{
for(volatile int i=0;i<DIM;i++)
{
r = RD2(i,j)&255;
g = GR2(i,j)&255;
b = BL2(i,j)&255;
LCD_1IN28_DisplayPoint(i, j, ((r>>3)<<11) | ((g>>2)<<5) | ((b>>3)<<0));
}
}
}
void draw_test(void)
{
draw_test1();
DEV_Delay_ms(2000);
draw_test2();
DEV_Delay_ms(2000);
}
draw.h
#ifndef DRAW_H
#define DRAW_H
void draw_test(void);
#endif
c/examples/LCD_1in28_test.c中调用测试函数
int LCD_1in28_test(void)
{
if (DEV_Module_Init() != 0)
{
return -1;
}
adc_init();
adc_gpio_init(29);
adc_select_input(3);
LCD_1IN28_Init(HORIZONTAL);
LCD_1IN28_Clear(WHITE);
DEV_SET_PWM(60);
while(1)
{
draw_test();
}
DEV_Module_Exit();
return 0;
}
编译
cd到RP2040-LCD-1.28/c/build路径
export PICO_SDK_PATH="/home/lhj/pico-setup/pico/pico-sdk" && cmake ..
make
生成的程序位于当前路径下
复制到windows下,下载到开发板运行
cp main.uf2 /mnt/d
void LCD_1IN28_DisplayPoint(UWORD X, UWORD Y, UWORD Color)
{
LCD_1IN28_SetWindows(X,Y,X,Y);
LCD_1IN28_SendData_16Bit(Color);
}
Xend和Yend都-1了
void LCD_1IN28_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
{
//set the X coordinates
LCD_1IN28_SendCommand(0x2A);
LCD_1IN28_SendData_8Bit(0x00);
LCD_1IN28_SendData_8Bit(Xstart);
LCD_1IN28_SendData_8Bit((Xend-1)>>8);
LCD_1IN28_SendData_8Bit(Xend-1);
//set the Y coordinates
LCD_1IN28_SendCommand(0x2B);
LCD_1IN28_SendData_8Bit(0x00);
LCD_1IN28_SendData_8Bit(Ystart);
LCD_1IN28_SendData_8Bit((Xend-1)>>8);
LCD_1IN28_SendData_8Bit(Yend-1);
LCD_1IN28_SendCommand(0X2C);
}
所以要改为
void LCD_1IN28_DisplayPoint(UWORD X, UWORD Y, UWORD Color)
{
LCD_1IN28_SetWindows(X,Y,X+1,Y+1);
LCD_1IN28_SendData_16Bit(Color);
}
for(int j=0;j<DIM;j++)
{
for(int i=0;i<DIM;i++)
{
r = RD2(i,j)&255;
g = GR2(i,j)&255;
b = BL2(i,j)&255;
LCD_1IN28_DisplayPoint(i, j, ((r>>3)<<11) | ((g>>2)<<5) | ((b>>3)<<0));
}
}
改为
for(volatile int j=0;j<DIM;j++)
{
for(volatile int i=0;i<DIM;i++)
{
r = RD2(i,j)&255;
g = GR2(i,j)&255;
b = BL2(i,j)&255;
LCD_1IN28_DisplayPoint(i, j, ((r>>3)<<11) | ((g>>2)<<5) | ((b>>3)<<0));
}
}
编译器聪明过头,将双循环优化掉了,虽然不管从什么角度考虑这里都不应该被优化掉(即不是多线程访问全局变量,也不是回调函数中使用全局变量),
所以这也是编译器可能存在弄巧成拙的地方,个人看来这应该算是编译器的BUG,因为这里不管编译等级设置多高都没有理由优化掉。
引用: lugl4313820 发表于 2022-12-5 09:15 刷新有点跟不上呀。
文中有说明,故意做的运算一个bit显示一个bit,为了演示画图的过程.
实际就肯定是先写道缓冲区,再一次刷新。