由于现在的LCD显示屏幕,有背光灯,看的时间长了眼睛会不舒服。所以,为了解决这个问题,又研发了一种不带背光的墨水屏,这不,我们今天就用墨水屏来制作一个电子书。
【墨水屏显示原理】
墨水屏采用的是“微胶囊电泳显示”技术进行图像显示,它的基本原理是悬浮在液体中的带电纳米粒子受到电场作用而产生迁移( 所以使用时间长了切换会有残影 )。墨水屏是靠反射环境光来显示图案的,所以不需要背光,在环境光下,墨水屏清晰可见,可视角度几乎达到了 180°。因此,墨水屏非常适合做电子书进行阅读。
不过,墨水屏也是有缺点的,首先它的刷新率不是很高,刷一屏的时间差不多是2秒,其次是它的显示颜色少,基本就是黑白两色。
好了,下面我们就看看怎么把墨水屏驱动起来。
【墨水屏驱动程序】
首先,墨水屏的接口为spi串行接口,所以直接接到单片机的spi1的管脚,如下图
spi的驱动程序如下
static void epaper_spi1_init(void)
{
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_SPI1);
rcu_periph_clock_enable(RCU_DMA0);
gpio_af_set(GPIOB, GPIO_AF_5, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_12);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_12);
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_11);
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_32;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPI1, &spi_init_struct);
spi_enable(SPI1);
}
其他墨水屏的驱动函数(比如画点函数,打印字符函数等)我们就不具体贴了,大家一般买屏幕卖家都会送的。
接下来我们就看看具体的电子书程序是怎么写的。
首先对墨水屏进行初始化
如下所示
int EPD_test_elink_book2(void)
{
page_turn_flag = 0;
book_num = 0;
DEV_Module_Init();
EPD_2IN9_Init(EPD_2IN9_FULL);
DEV_Delay_ms(500);
Paint_NewImage(BlackImage, EPD_2IN9_WIDTH, EPD_2IN9_HEIGHT, 270, WHITE);
然后显示一张开机图片
程序如下
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
Paint_DrawBitMap(gImage_dzs);
EPD_2IN9_Display(BlackImage);
DEV_Delay_ms(10000);
接下来就是电子书显示
程序如下
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
read_book(str_book);
DEV_Delay_ms(2000);
我们封装了一个函数read_book来显示电子书
它的参数只有一个,就是字符串指针
函数read_book原型
read_book函数如下
void read_book(const char *str2){
char flag = 1;
while(1){
flag = my_lcd_puts(str2);
EPD_2IN9_Display(BlackImage);
DEV_Delay_ms(20000);
if(0 == flag){
book_num = 0;
return;
}
set_page_turn();
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
}
}
其中,最主要的函数为 my_lcd_puts,他是用来显示传人的字符串到墨水屏的
my_lcd_puts函数如下
char my_lcd_puts(const char *str2)
{
char *str = str2 + book_num;
page_turn_flag = 0;
while(*str) {
if (*str == '\r') {
s_tLCDTextControl_su.tTextLocation.chX = 0;
} else if (*str == '\n') {
s_tLCDTextControl_su.tTextLocation.chX = 0;
s_tLCDTextControl_su.tTextLocation.chY++;
} else if (*str == '\t') {
s_tLCDTextControl_su.tTextLocation.chX += 8;
s_tLCDTextControl_su.tTextLocation.chX &= ~(_BV(3)-1);
if ( s_tLCDTextControl_su.tTextLocation.chX * Font16.Width
>= s_tLCDTextControl_su.tRegion.tSize.iWidth ) {
s_tLCDTextControl_su.tTextLocation.chX = 0;
s_tLCDTextControl_su.tTextLocation.chY++;
}
}else if (*str == '\b') {
if (s_tLCDTextControl_su.tTextLocation.chX) {
s_tLCDTextControl_su.tTextLocation.chX--;
}
} else {
int16_t iX = s_tLCDTextControl_su.tTextLocation.chX * Font16.Width;
int16_t iY = s_tLCDTextControl_su.tTextLocation.chY * Font16.Height;
if ( iY > (s_tLCDTextControl_su.tRegion.tSize.iHeight-Font16.Height) ) {
s_tLCDTextControl_su.tTextLocation.chY = 0;
s_tLCDTextControl_su.tTextLocation.chX = 0;
page_turn_flag = 1;
return 1;
}
my_lcd_draw_char( s_tLCDTextControl_su.tRegion.tLocation.iX + iX,
iY,
*str);
s_tLCDTextControl_su.tTextLocation.chX++;
if ( s_tLCDTextControl_su.tTextLocation.chX * Font16.Width
>= s_tLCDTextControl_su.tRegion.tSize.iWidth ) {
s_tLCDTextControl_su.tTextLocation.chX = 0;
s_tLCDTextControl_su.tTextLocation.chY++;
if ( s_tLCDTextControl_su.tTextLocation.chY * Font16.Height
>= s_tLCDTextControl_su.tRegion.tSize.iHeight) {
s_tLCDTextControl_su.tTextLocation.chY = 0;
s_tLCDTextControl_su.tTextLocation.chX = 0;
page_turn_flag = 1;
return 1;
}
}
}
if(0 == page_turn_flag){
book_num++;
str = str2 + book_num;
}
}
return 0;
}
原作者:兆易创新GD32 MCU boc