入手一片微雪3寸墨水屏模块,四色红、黄、黑、白。400×168分辨率,一直很喜欢墨水屏显示的质感,乘此机会买了一片,把玩一下。
一、项目目标
使用NUCLEO-WBA55CG开发板驱动墨水屏,并通过PWM控制LED灯管的亮度。硬件列表。NUCLEO-WBA55CG开发板;一个LED灯管;3寸墨水屏模块;一块电机驱动板,用来通过PWM驱动LED灯管。电机驱动板自带电池升压功能。
二、硬件连接
墨水屏有8根线,通过SPI与单片机相连接。LED灯连接驱动板,单片机通过PWM控制驱动板,调节PWM占空比,控制LED灯的亮度。
3寸墨水屏 | CN4 | 3寸墨水屏 | ||||||||||||||||
2 | GPIO_2 | 1 | GPIO_26 | 2 | GPIO_25 | |||||||||||||
4 | GPIO_4 | 3 | GPIO_28 | PB2 | D15 | SCL | 黄 | 4 | GPIO_27 | |||||||||
6 | 5V | 5 | GPIO_29 | PB1 | D14 | SDA | 绿 | 6 | GPIO_30 | |||||||||
8 | GND | 7 | AVDD | AVDD | 8 | 5V | ||||||||||||
10 | 9 | GND | 10 | GPIO_32 | ||||||||||||||
12 | IOREF | 11 | GPIO_31 | PB4(LD1) | D13 | SCK | 黄 | sclk | 12 | GPIO_35 | ||||||||
14 | NRST | 13 | GPIO_33 | PB3 | D12 | MISO | 14 | GPIO_36 | ||||||||||
16 | 3V3 | 15 | GPIO_34 | PA15 | D11 | MOSI | 兰 | din | 16 | GPIO_38 | ||||||||
18 | 5V | 17 | GPIO_37 | PA12 | D10 | SS | 橙 | cs | 18 | GPIO_40 | ||||||||
20 | GND | 19 | GPIO_39 | PA9 | D9 | 20 | GND | |||||||||||
22 | GND | 21 | GPIO_41 | PA15/PA11 | D8 | 22 | GPIO_43 | |||||||||||
24 | VIN | 23 | GPIO_42 | PB9/PC13 | D7 | 24 | GPIO_45 | |||||||||||
26 | GPIO_7 | 25 | GPIO_44 | PB0 | D6 | 白 | rst | 26 | GPIO_46 | |||||||||
28 | GPIO_11 | PA7 | A0 | 27 | GPIO_47 | PB14 | D5 | 绿 | dc | 28 | GPIO_48 | |||||||
30 | GPIO_12 | PA6 | A1 | TIM2_CH4 | PWM输出 | 29 | GPIO_49 | PB13 | D4 | 30 | GPIO_51 | |||||||
32 | GPIO_17 | PA2 | A2 | 紫 | busy | 31 | GPIO_50 | PB6(B2) | D3 | 32 | GND | |||||||
34 | GPIO_18 | PA1 | A3 | 33 | GPIO_52 | PB7(B3) | D2 | 34 | GPIO_53 | |||||||||
36 | GPIO_21 | PA5/PA8 | A4 | SDA | 35 | GPIO_54 | PB5 | D1 | 36 | GPIO_56 | ||||||||
38 | GPIO_22 | PA0/PA5 | A5 | SCL | 37 | GPIO_55 | PA10 | D0 | 38 | GPIO_57 |
三、通过例程创建工程
这里使用stm32cubemx,通过例程创建工程。
调整tim2的pwm输出,这里只需要一个PWM输出即可。调整PWM频率为1000Hz。
设置SPI输出,墨水屏驱动,仅仅需要单片机发出指令,所以只开启MOSI。
最后,开启墨水屏管脚对应的GPIO。
四、代码实现
添加一个方法,用来控制PWM的输出。
/* USER CODE BEGIN 0 */ void TIM_SetTIM2Compare4(uint32_t compare){ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, compare); // } /* USER CODE END 0 */
重构fputc函数,这样就可以将printf函数,映射输出到串口,方便调试代码。
/* USER CODE BEGIN 4 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; } /* USER CODE END 4 */
参考着微雪提供的例程,来驱动墨水屏。这里需要留意,墨水屏显示速度不快,不合适做高速显示的内容。这里将LED灯的亮度分割为了10份,每隔几秒累加一。当PWM值小于4时,使用黑色显示,超过4是使用黄色,高于6时,使用红色。
printf("e-Paper Init and Clear...\r\n"); EPD_3IN0G_Init(); EPD_3IN0G_Clear(EPD_3IN0G_WHITE); // WHITE DEV_Delay_ms(2000); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(num>9 ) num=0; printf("%d EPD_3IN0G_test Demo\r\n",num++); HAL_Delay(1000); printf("SelectImage:BlackImage\r\n"); if((BlackImage = (UBYTE *)malloc(16680)) == NULL) { printf("Failed to apply for black memory...\r\n"); return -1; } printf("Paint_NewImage\r\n"); Paint_NewImage(BlackImage, EPD_3IN0G_WIDTH, EPD_3IN0G_HEIGHT, 0, EPD_3IN0G_WHITE); Paint_SetScale(4); EPD_3IN0G_Init(); Paint_SelectImage(BlackImage); Paint_Clear(EPD_3IN0G_WHITE); //Paint_DrawString_EN(10, 0, "Red, yellow, white and black", &Font16, EPD_3IN0G_RED, EPD_3IN0G_YELLOW); sprintf(buf,"PWM = %d",num); if(num<4) Paint_DrawString_EN(10, 35, buf, &Font24, EPD_3IN0G_WHITE, EPD_3IN0G_BLACK); else if(num>6) Paint_DrawString_EN(10, 35, buf, &Font24, EPD_3IN0G_WHITE, EPD_3IN0G_RED); else Paint_DrawString_EN(10, 35, buf, &Font24, EPD_3IN0G_WHITE, EPD_3IN0G_YELLOW); EPD_3IN0G_Display(BlackImage); free(BlackImage); TIM_SetTIM2Compare4(num*100); DEV_Delay_ms(5000); }
因为墨水屏显示部分使用了,动态内存,并且一次申请内存容量较大,所以需要修改STM32的堆栈设置。否则在malloc时会提示失败。
五、效果展示
六、项目源码