任务所需的开发板型号为seeed studio 0.96' Yello&Blue OLED,其驱动芯片为SSD1315,支持SPI和IIC驱动,其官网介绍为Grove - OLED Yellow&Blue Display 0.96(SSD1315) - SPI/IIC -3.3V/5V | Seeed Studio Wiki
考虑到脉搏血氧计传感器MAXREFDES117得用IIC接口,而评估板MAX78000FTHR上只有一个IIC接口,因此为了便于开发,选择屏幕驱动用SPI,MAXREFDES117驱动用IIC
查看官方Wiki可以看到如果想要用SPI驱动屏幕,得先切断几根线,然后用焊锡将另外两个焊盘连接起来
然而可能是我的手艺不太行,导致切完之后屏幕彻底亮不起来了
由于我手头正好有个1.8寸LCD屏幕,驱动芯片是ST7789,这里就用这个屏幕来做了
1.8寸LCD屏幕接口引脚定义如下
MAX78000FTHR的SPI引脚接口如下
由于我们只需要用评估板控制LCD屏幕即可,因此需要用到SCK引脚、MOSI引脚,为了充分发挥硬件SPI的性能,LCD的CS引脚接到评估板的SS0上(当然也可以使用软件片选,我在程序里也设计了这种方案),最终LCD对评估板的引脚连线如下
GND -> GND
VCC -> 3V3
SCK -> P0_7
SDA -> P0_5
RES -> P0_6
DC -> P2_6
CS -> P0_11
BL -> 3V3
由于LCD初始化的c文件内容较多,这里贴出h文件说明相关接口函数
首先是LCD的初始化文件lcd_init.h,这里初始化了SPI和LCD屏幕,提供了底层的API接口
#ifndef LCD_INIT_H #define LCD_INIT_H #include <stdint.h> #include <stdbool.h> #include <stddef.h> #include "mxc_device.h" #include "gpio.h" #include "mxc_delay.h" // ======================= 用户可配置项 ======================= // 0/1 竖屏,2/3 横屏 #define USE_HORIZONTAL 2 // ST7735S 常见分辨率:128x160 #if (USE_HORIZONTAL==0) || (USE_HORIZONTAL==1) #define LCD_WIDTH 128 #define LCD_HEIGHT 160 #else #define LCD_WIDTH 160 #define LCD_HEIGHT 128 #endif // 引脚映射(与你给定的连线保持一致) #define LCD_SCLK_PORT MXC_GPIO0 #define LCD_SCLK_PIN 7 // SCL -> P0_7 #define LCD_MOSI_PORT MXC_GPIO0 #define LCD_MOSI_PIN 5 // SDA -> P0_5 #define LCD_RES_PORT MXC_GPIO0 #define LCD_RES_PIN 6 // RST -> P0_6 #define LCD_DC_PORT MXC_GPIO2 #define LCD_DC_PIN 6 // DC -> P2_6 #define LCD_CS_PORT MXC_GPIO2 #define LCD_CS_PIN 7 // CS -> P2_7 // 可选背光(若未接 GPIO,请将 BLK 宏留空,或常接 3V3) /* 示例(若你接了 BLK 到某 GPIO,请启用并配置): #define LCD_BLK_PORT MXC_GPIOx #define LCD_BLK_PIN y */ // ======================= GPIO 宏 ======================= #define PIN_MASK(p) (1u << (p)) #define GPIO_SET(PORT, PIN) MXC_GPIO_OutSet((PORT), PIN_MASK(PIN)) #define GPIO_CLR(PORT, PIN) MXC_GPIO_OutClr((PORT), PIN_MASK(PIN)) #define LCD_SCLK_Set() GPIO_SET(LCD_SCLK_PORT, LCD_SCLK_PIN) #define LCD_SCLK_Clr() GPIO_CLR(LCD_SCLK_PORT, LCD_SCLK_PIN) #define LCD_MOSI_Set() GPIO_SET(LCD_MOSI_PORT, LCD_MOSI_PIN) #define LCD_MOSI_Clr() GPIO_CLR(LCD_MOSI_PORT, LCD_MOSI_PIN) #define LCD_RES_Set() GPIO_SET(LCD_RES_PORT, LCD_RES_PIN) #define LCD_RES_Clr() GPIO_CLR(LCD_RES_PORT, LCD_RES_PIN) #define LCD_DC_Set() GPIO_SET(LCD_DC_PORT, LCD_DC_PIN) #define LCD_DC_Clr() GPIO_CLR(LCD_DC_PORT, LCD_DC_PIN) #define LCD_CS_Set() GPIO_SET(LCD_CS_PORT, LCD_CS_PIN) #define LCD_CS_Clr() GPIO_CLR(LCD_CS_PORT, LCD_CS_PIN) #ifdef LCD_BLK_PORT #define LCD_BLK_Set() GPIO_SET(LCD_BLK_PORT, LCD_BLK_PIN) #define LCD_BLK_Clr() GPIO_CLR(LCD_BLK_PORT, LCD_BLK_PIN) #else #define LCD_BLK_Set() ((void)0) #define LCD_BLK_Clr() ((void)0) #endif // 便捷延时(ms) static inline void delay_ms(uint32_t ms) { MXC_Delay(ms * 1000UL); } // ======================= 低层 API ======================= void LCD_GPIO_Init(void); void LCD_Writ_Bus(uint8_t dat); void LCD_WR_DATA8(uint8_t dat); void LCD_WR_DATA(uint16_t dat); void LCD_WR_REG(uint8_t dat); void LCD_Address_Set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); void LCD_Init(void); #endif // LCD_INIT_H
接着是上层API调用函数,包括了绘图和字符
#ifndef LCD_H #define LCD_H #include <stdint.h> #include "lcd_init.h" // 颜色(RGB565) #define WHITE 0xFFFF #define BLACK 0x0000 #define BLUE 0x001F #define BRED 0xF81F #define GRED 0xFFE0 #define GBLUE 0x07FF #define RED 0xF800 #define MAGENTA 0xF81F #define GREEN 0x07E0 #define CYAN 0x07FF #define YELLOW 0xFFE0 #define BROWN 0xBC40 #define BRRED 0xFC07 #define GRAY 0x8430 #define DARKBLUE 0x01CF #define LIGHTBLUE 0x7D7C #define GRAYBLUE 0x5458 #define LIGHTGREEN 0x841F #define LGRAY 0xC618 #define LGRAYBLUE 0xA651 #define LBBLUE 0x2B12 // 上层绘图与字符接口 void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color); void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color); void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color); void LCD_DrawRectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color); void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color); void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode); void LCD_ShowString(uint16_t x,uint16_t y,const uint8_t *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode); void LCD_ShowIntNum(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey); void LCD_ShowFloatNum1(uint16_t x,uint16_t y,float num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey); void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[]); #endif // LCD_H
此外还需定义一个字符文件font.h,这里不再赘述
最后在main.c中,初始化LCD屏幕,显示字符,并不断刷频测试其流畅度
#include <stdio.h> #include "mxc_device.h" #include "board.h" #include "mxc_delay.h" #include "led.h" #include "lcd_init.h" #include "lcd.h" int main(void) { // (可选)同步系统时钟变量,保持与 SDK 示例一致 MXC_SYS_Clock_Select(MXC_SYS_CLOCK_IPO); // 初始化 LCD LCD_Init(); LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, BLACK); LCD_ShowString(5, 30, (const uint8_t *)"Hello World", WHITE, BLACK, 16, 0); LCD_ShowString(5, 80, (const uint8_t *)"FuShenxiao", WHITE, BLACK, 16, 0); MXC_Delay(3000000); while (1) { LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, RED); LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, BLUE); LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, YELLOW); LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, GREEN); LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, WHITE); LCD_Fill(0, 0, LCD_WIDTH, LCD_HEIGHT, BLACK); } }
展示效果如下
工程代码如下