我们这款开发板应该是最便宜的AI开发板了吧,200RMB左右,搭载1TOPS处理能力的K210芯片,丰富的外设接口,内置超多算法,除此之外,开发板还带了屏幕和摄像头。本章我们介绍SPI接口的另一个应用,驱动LCD屏幕。需要开发板可以联系我,可以价格更低哦!
LCD显示的基本原理是将液晶至于两片导电玻璃基板之间,在上下玻璃基板的两个电极作用下,引起液晶分子扭曲变形,改变通过液晶盒光束的偏振状态,实现对背光源光束的开关控制。
如果液晶盒上不施加外电场,由于TN型液晶显示器件中液晶分子在盒中的扭曲螺距远比可见光波长大得多,所以当入射直线偏振光的偏振方向与玻璃表面液晶分子的排列方向一致时,其偏光方向在通过整个液晶层后会随着液晶分子扭曲变形而被扭曲90。由另一侧射出,呈透光状态。如果这时在液晶盒上施加一个电压并达到一定值后,液晶分子长轴将开始沿电场方向倾斜,除电极表面的液晶分子外,所有液晶盒内两电极之间的液晶分子都变成沿电场方向的再排列。液晶显示屏技术是根据电压的大小来改变亮度,每个液晶显示屏的子图元显示的颜色取决于色彩筛检程序。
SPI是一种高速、高效率的串行接口技术。通常由一个主模块和一个或多个从模块组成,主模块选择一个从模块进行同步通信,从而完成数据的交换。SPI是一个环形结构,通信时需要至少4根线(事实上在单向传输时3根线也可以),它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)。
(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;
(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;
(3)SCLK – Serial Clock,时钟信号,由主设备产生;
(4)CS – Chip Select,从设备使能信号,由主设备控制。当有多个从设备的时候,因为每个从设备上都有一个片选引脚接入到主设备机中,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高。
开发板上的LCD显示为2.0寸,分辨率为320*240,驱动芯片是st7789,体积小,厚度薄,耗能低,工作电压为3.3V,显示屏的材料为TFT。
TFT(Thin Film Transistor)是指薄膜晶体管,使每个液晶像素点都是由集成在像素点后面的薄膜晶体管来驱动。从而可以做到高速度、高亮度、高对比度显示屏幕信息。
硬件连接:K210开发板出厂默认已经安装好LCD显示屏,其中LCD_D0~D7总共八个引脚连接到SPI0_D0-D7,LCD_CS连接到IO36上,LCD_RST连接到IO37上,LCD_RS连接IO3上,LCD_WR连接IO39上
对应的头文件 spi.h
SPI是一种高速的,全双工,同步的通信总线。
SPI模块具有以下功能:
独立的SPI设备封装外设相关参数,自动处理多设备总线争用,支持标准、双线、四线、八线模式,支持先写后读和全双工读写,支持发送一串相同的数据帧,常见与清屏、填充储存扇区等场景。
为用户提供以下接口:
• spi_init:设置SPI工作模式、多线模式和位宽。
• spi_init_non_standard:多线模式下设置指令长度、地址长度、等待时钟数、指令地址传输模式。
• spi_send_data_standard:SPI标准模式传输数据。
• spi_send_data_standard_dma:SPI标准模式下使用DMA传输数据。
• spi_receive_data_standard:标准模式下接收数据。
• spi_receive_data_standard_dma:标准模式下通过DMA接收数据。
• spi_send_data_multiple:多线模式发送数据。
• spi_send_data_multiple_dma:多线模式使用DMA发送数据。
• spi_receive_data_multiple:多线模式接收数据。
• spi_receive_data_multiple_dma:多线模式通过DMA 接收。
• spi_fill_data_dma:通过DMA 始终发送同一个数据,可以用于刷新数据。
• spi_send_data_normal_dma:通过DMA 发送数据。不用设置指令地址。
• spi_set_clk_rate:设置SPI的时钟频率。
• spi_handle_data_dma:SPI 通过DMA 传输数据。
st7789驱动对SPI提供的接口进行了封装,提供了以下这些API,使用这些接口,我们可以方便的传输字符数据了:
void tft_hard_init(void);
void tft_write_command(uint8_t cmd);
void tft_write_byte(uint8_t *data_buf, uint32_t length);
void tft_write_half(uint16_t *data_buf, uint32_t length);
void tft_write_word(uint32_t *data_buf, uint32_t length, uint32_t flag);
void tft_fill_data(uint32_t *data_buf, uint32_t length);
在数据可以简单传输的基础上,我们为一些基础的图形封装好接口,如下:
void lcd_init(void);
void lcd_clear(uint16_t color);
void lcd_set_direction(lcd_dir_t dir);
void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color);
void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color);
void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr);
void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color);
void lcd_draw_picture_half(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t *ptr);
void lcd_clear_all(void);
这个实验主要包含两个部分,一部分是SPI驱动的调试,另一部分是图片格式的转换和显示;
我们先进行第一部分,SPI驱动调试,先进行FPIOA映射,这部分代码比较多,有驱动代码,有图片转换后的代码,我之后将代码打包上传,这里不做全部展示。开源仓库
#define PIN_LCD_CS (36)
#define PIN_LCD_RST (37)
#define PIN_LCD_RS (38)
#define PIN_LCD_WR (39)
/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define LCD_RST_GPIONUM (0)
#define LCD_RS_GPIONUM (1)
/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_LCD_CS (FUNC_SPI0_SS3)
#define FUNC_LCD_RST (FUNC_GPIOHS0 + LCD_RST_GPIONUM)
#define FUNC_LCD_RS (FUNC_GPIOHS0 + LCD_RS_GPIONUM)
#define FUNC_LCD_WR (FUNC_SPI0_SCLK)
void hardware_init(void)
{
/**
*PIN_LCD_CS 36
*PIN_LCD_RST 37
*PIN_LCD_RS 38
*PIN_LCD_WR 39
**/
fpioa_set_function(PIN_LCD_CS, FUNC_LCD_CS);
fpioa_set_function(PIN_LCD_RST, FUNC_LCD_RST);
fpioa_set_function(PIN_LCD_RS, FUNC_LCD_RS);
fpioa_set_function(PIN_LCD_WR, FUNC_LCD_WR);
/* 使能SPI0和DVP数据 */
sysctl_set_spi0_dvp_data(1);
}
根据LCD的datasheet,LCD的IO口需要为1.8V电压。
void io_set_power(void)
{
sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
}
int main(void)
{
/* 硬件引脚初始化 */
hardware_init();
/* 设置IO口电压 */
io_set_power();
/* 初始化LCD */
lcd_init();
/* 显示图片 */
lcd_draw_picture_half(0, 0, 320, 240, gImage_logo);
sleep(1);
/* 显示字符 */
lcd_draw_string(16, 60, "picture demo", BLUE);
while (1);
return 0;
}
安装并打开图片转化工具Image2Lcd,关于图片是如何转化成数据格式,再把保存得到的.c文件复制到项目目录下
该工具有几个要求,Image2Lcd支持的输入图像格式包括BMP、WBMP、JPG、GIF、WMF、EMF、ICO等
代码写好后,我们开始编译,注意:如果你编译过程中出现错误,可以先make clean掉之前生成的过程文件,重新生成
cd build
//注意这里的目标文件目录改成lcd,和刚才新建的文件夹名称一致
cmake .. -DPROJ=lcd -G "MinGW Makefiles"
make
编译完成后,在build文件夹下会生成flash.bin文件。
使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。
实验结果
本章讲述了SPI驱动LCD显示屏,在实验过程中可能有很多坑,我首先将要显示的图片分辨率改为320*240,然后通过图片转化工具把图片转成.c文件的这里要注意下。