STM32开发(屏幕驱动ST7735S-SPI方式)用RT-Thread驱动测试

前言

  1. 使用ST7735S屏幕驱动,方便学习LVGL
  2. 通过结构体的方式来管理相关函数和变量
  3. 通讯协议和硬件驱动层进行解耦

驱动

配置(用于对接硬件)

st7735s_conf.h

//
// Created by shchl on 2024/2/28.
//#ifndef STM32F407V4T6_RTOS_ST7735S_CONF_H
#define STM32F407V4T6_RTOS_ST7735S_CONF_H#include "stdint.h"
#include "stdio.h"#ifndef ST7735S_SCREEN_MODE
#define ST7735S_SCREEN_MODE           VER_0_MODE
#endif
#ifndef ST7735S_SCREEN_WIDTH
#define ST7735S_SCREEN_WIDTH           128
#endif
#ifndef ST7735S_SCREEN_HIGH
#define ST7735S_SCREEN_HIGH           160
#endif
/*背景色*/
#ifndef ST7735S_BACK_COLOR
#define ST7735S_BACK_COLOR           0xFFFF
#endif
/*画笔颜色*/
#ifndef ST7735S_POINT_COLOR
#define ST7735S_POINT_COLOR           0x0000
#endif/用户配置区///
#define ST7735S_BUS_NAME "spi3"
#define ST7735S_SPI_DEVICE "spi30"
#define ST7735S_DC_PIN GET_PIN(B, 13)  /*寄存器或数据引脚*/
#define ST7735S_RESET_PIN GET_PIN(B, 11) /*复位引脚*/
#define ST7735S_CS_PIN GET_PIN(B, 14)    /*使能引脚*/
#define ST7735S_BLK_PIN GET_PIN(A,8)  // 背光引脚//扫描方向定义--扫描方式有不同规格,可能定义不左右和上下的参照方向不同,总结方式,只有一下八种#define L2R_U2D  0 //从左到右,从上到下
#define L2R_D2U  1 //从左到右,从下到上
#define R2L_U2D  2 //从右到左,从上到下
#define R2L_D2U  3 //从右到左,从下到上#define U2D_L2R  4 //从上到下,从左到右
#define U2D_R2L  5 //从上到下,从右到左
#define D2U_L2R  6 //从下到上,从左到右
#define D2U_R2L  7 //从下到上,从右到左///  颜色值  /////画笔颜色
#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             0x7FFF
#define YELLOW             0xFFE0
#define BROWN             0xBC40 //棕色
#define BRRED             0xFC07 //棕红色
#define GRAY             0x8430 //灰色
//GUI颜色
#define DARKBLUE         0x01CF    //深蓝色
#define LIGHTBLUE         0x7D7C    //浅蓝色
#define GRAYBLUE         0x5458 //灰蓝色
//以上三色为PANEL的颜色
#define LIGHTGREEN         0x841F //浅绿色
//#define LIGHTGRAY        0XEF5B //浅灰色(PANNEL)
#define LGRAY             0xC618 //浅灰色(PANNEL),窗体背景色
#define GRAY0            0xEF7D        //灰色0
#define GRAY1            0x8410        //灰色1
#define GRAY2            0x4208        //灰色2
#define LGRAYBLUE        0xA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0x2B12 //浅棕蓝色(选择条目的反色)typedef enum {VER_0_MODE, /*竖屏模式0: 从上至下*/VER_1_MODE, /*竖屏模式1: 从下至上*/HOR_0_MODE, /*横屏屏模式0: 从左至右*/HOR_1_MODE  /*横屏屏模式1: 从右至左*/
} ST7735S_DIR_MODE;
struct ST7735S { /*ST7735S 总结构体*/struct {ST7735S_DIR_MODE screen_mode;uint16_t width; /*宽*/uint16_t height;  /*高*/uint16_t back_color; /*背景色*/uint16_t point_color; /*画笔颜色*/struct {uint16_t wramcmd; //开始写gram指令uint16_t setxcmd; //设置x坐标指令uint16_t setycmd; //设置y坐标指令} CMD;} CNF;struct {void (*_enter)(void);  ///< crtical section entervoid (*_exit)(void);    ///< critial section exit} CRIS;struct {void (*_select)(void);void (*_deselect)(void);} CS; /*CS引脚*/struct {void (*_select_data)(void);void (*_select_reg)(void);} DC; /*数据或寄存器选择引脚*/struct {void (*_write_byte)(uint8_t dat); /*写字节*/} SPI; /*SPI数据接口*/};
extern struct ST7735S ST7735S_DEV;/*-----------------------------------ST7735S回调函数注册------------------------------------------------*/
void reg_st7735s_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void));void reg_st7735s_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void));void reg_st7735s_dc_cbfunc(void(*dc_dat)(void), void(*dc_reg)(void));void reg_st7735s_spi_cbfunc(void(*spi_write_byte)(uint8_t data));/*-----------------------------------ST7735S回调函数注册--------END----------------------------------------*/
void st7735s_init(void);#endif //STM32F407V4T6_RTOS_ST7735S_CONF_H

st7735s_conf.c

//
// Created by shchl on 2024/2/28.
//
#include "st7735s_conf.h"struct ST7735S ST7735S_DEV = {.CNF={.screen_mode =ST7735S_SCREEN_MODE,.width=ST7735S_SCREEN_WIDTH,.height = ST7735S_SCREEN_HIGH,.back_color = ST7735S_BACK_COLOR,.point_color = ST7735S_POINT_COLOR,},.SPI={NULL},.CS ={NULL, NULL},.DC={NULL, NULL},.CRIS={NULL, NULL}
};void reg_st7735s_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) {ST7735S_DEV.CRIS._enter = cris_en;ST7735S_DEV.CRIS._exit = cris_ex;
}void reg_st7735s_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) {ST7735S_DEV.CS._select = cs_sel;ST7735S_DEV.CS._deselect = cs_desel;
}void reg_st7735s_dc_cbfunc(void(*dc_dat)(void), void(*dc_reg)(void)) {ST7735S_DEV.DC._select_reg = dc_reg;ST7735S_DEV.DC._select_data = dc_dat;
}void reg_st7735s_spi_cbfunc(void(*spi_write_byte)(uint8_t data)) {ST7735S_DEV.SPI._write_byte = spi_write_byte;
}

通讯协议(数据手册)

st7735s.h

//
// Created by shchl on 2024/2/28.
//#ifndef STM32F407V4T6_RTOS_ST7735S_H
#define STM32F407V4T6_RTOS_ST7735S_H#include "st7735s_conf.h"
#include "st7735s_ex.h"void ST7735S_write_dat_u8(uint8_t dat);void ST7735S_write_dat_u16(uint16_t dat);void ST7735S_write_reg_val(uint16_t reg, uint16_t dat);void ST7735S_write_reg(uint8_t dat);void LCD_Init(void);//初始化
void LCD_SoftRest(void); //软复位
void LCD_DisplayOn(void);	//开显示
void LCD_DisplayOff(void);	//关显示
void LCD_Clear(uint16_t Color); //清屏
void LCD_Display_Dir(ST7735S_DIR_MODE dir);//设置屏幕显示方向
void LCD_WriteRAM_Prepare(void);  //开始写GRAM  命令
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);    //设置光标
void LCD_DrawPoint(uint16_t x, uint16_t y);//画点--使用设置的笔尖颜色
void LCD_Set_Window(uint16_t sx, uint16_t sy, uint16_t width, uint16_t height); //设置窗口
void LCD_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color);//填充指定颜色
void LCD_WriteRAM(uint16_t RGB_Code);//LCD写GRAM
void LCD_Fast_DrawPoint(uint16_t x,uint16_t y,uint16_t color);	//快速画点--使用当前输入颜色参数
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);		                //画线
void LCD_Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r, uint16_t Color);					            //画圆
#endif //STM32F407V4T6_RTOS_ST7735S_H

st7735s.c

//
// Created by shchl on 2024/2/28.
//#include "st7735s.h"#define CRITICAL_ENTER()  if(ST7735S_DEV.CRIS._enter)ST7735S_DEV.CRIS._enter()
#define CRITICAL_EXIT()   if(ST7735S_DEV.CRIS._enter)ST7735S_DEV.CRIS._exit()
#define DC_DATA_SELECT()  if(ST7735S_DEV.DC._select_data) ST7735S_DEV.DC._select_data()
#define DC_REG_SELECT()   if(ST7735S_DEV.DC._select_reg) ST7735S_DEV.DC._select_reg()
#define CS_SELECT()       if(ST7735S_DEV.CS._select) ST7735S_DEV.CS._select()
#define CS_DESELECT()     if(ST7735S_DEV.CS._deselect) ST7735S_DEV.CS._deselect()void ST7735S_write_dat_u8(uint8_t dat) {CRITICAL_ENTER();DC_DATA_SELECT(); /*恢复到写数据模式*/CS_SELECT();if (ST7735S_DEV.SPI._write_byte) {ST7735S_DEV.SPI._write_byte(dat);}CS_DESELECT();CRITICAL_EXIT();
}void ST7735S_write_dat_u16(uint16_t dat) {ST7735S_write_dat_u8(dat >> 8);ST7735S_write_dat_u8(dat);
}void ST7735S_write_reg_val(uint16_t reg, uint16_t dat) {ST7735S_write_reg(reg);ST7735S_write_dat_u8(dat);
}void ST7735S_write_reg(uint8_t dat) {CRITICAL_ENTER();DC_REG_SELECT();/*恢复到写寄存器模式*/CS_SELECT();if (ST7735S_DEV.SPI._write_byte) {ST7735S_DEV.SPI._write_byte(dat);}CS_DESELECT();CRITICAL_EXIT();
}/*******************************************************************************/
//函数:void LCD_Init(void)
//函数功能:初始化lcd
/*******************************************************************************/void LCD_Init(void) {//初始化驱动 I/O接口st7735s_init();LCD_SoftRest();        //软复位ST7735S_write_reg(0x11);      //Sleep exitHAL_Delay(120);      // delay 120 ms//ST7735R Frame RateST7735S_write_reg(0xB1);ST7735S_write_dat_u8(0x01);ST7735S_write_dat_u8(0x2C);ST7735S_write_dat_u8(0x2D);ST7735S_write_reg(0xB2);ST7735S_write_dat_u8(0x01);ST7735S_write_dat_u8(0x2C);ST7735S_write_dat_u8(0x2D);ST7735S_write_reg(0xB3);ST7735S_write_dat_u8(0x01);ST7735S_write_dat_u8(0x2C);ST7735S_write_dat_u8(0x2D);ST7735S_write_dat_u8(0x01);ST7735S_write_dat_u8(0x2C);ST7735S_write_dat_u8(0x2D);ST7735S_write_reg(0xB4); //Column inversionST7735S_write_dat_u8(0x07);//ST7735R Power SequenceST7735S_write_reg(0xC0);ST7735S_write_dat_u8(0xA2);ST7735S_write_dat_u8(0x02);ST7735S_write_dat_u8(0x84);ST7735S_write_reg(0xC1);ST7735S_write_dat_u8(0xC5);ST7735S_write_reg(0xC2);ST7735S_write_dat_u8(0x0A);ST7735S_write_dat_u8(0x00);ST7735S_write_reg(0xC3);ST7735S_write_dat_u8(0x8A);ST7735S_write_dat_u8(0x2A);ST7735S_write_reg(0xC4);ST7735S_write_dat_u8(0x8A);ST7735S_write_dat_u8(0xEE);ST7735S_write_reg(0xC5); //VCOMST7735S_write_dat_u8(0x0E);ST7735S_write_reg(0x36); //MX, MY, RGB modeST7735S_write_dat_u8(0xC0);//ST7735R Gamma SequenceST7735S_write_reg(0xe0);ST7735S_write_dat_u8(0x0f);ST7735S_write_dat_u8(0x1a);ST7735S_write_dat_u8(0x0f);ST7735S_write_dat_u8(0x18);ST7735S_write_dat_u8(0x2f);ST7735S_write_dat_u8(0x28);ST7735S_write_dat_u8(0x20);ST7735S_write_dat_u8(0x22);ST7735S_write_dat_u8(0x1f);ST7735S_write_dat_u8(0x1b);ST7735S_write_dat_u8(0x23);ST7735S_write_dat_u8(0x37);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x07);ST7735S_write_dat_u8(0x02);ST7735S_write_dat_u8(0x10);ST7735S_write_reg(0xe1);ST7735S_write_dat_u8(0x0f);ST7735S_write_dat_u8(0x1b);ST7735S_write_dat_u8(0x0f);ST7735S_write_dat_u8(0x17);ST7735S_write_dat_u8(0x33);ST7735S_write_dat_u8(0x2c);ST7735S_write_dat_u8(0x29);ST7735S_write_dat_u8(0x2e);ST7735S_write_dat_u8(0x30);ST7735S_write_dat_u8(0x30);ST7735S_write_dat_u8(0x39);ST7735S_write_dat_u8(0x3f);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x07);ST7735S_write_dat_u8(0x03);ST7735S_write_dat_u8(0x10);ST7735S_write_reg(0x2a);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x7f);ST7735S_write_reg(0x2b);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x00);ST7735S_write_dat_u8(0x9f);ST7735S_write_reg(0xF0); //Enable test commandST7735S_write_dat_u8(0x01);ST7735S_write_reg(0xF6); //Disable ram power save modeST7735S_write_dat_u8(0x00);ST7735S_write_reg(0x3A); //65k modeST7735S_write_dat_u8(0x05);ST7735S_write_reg(0x29);//Display onLCD_Display_Dir(ST7735S_DEV.CNF.screen_mode);    //选择--屏幕显示方式LCD_Clear(ST7735S_DEV.CNF.back_color);
}
//********************************************************************************/
//函数:void LCD_DisplayOn(void)
//函数功能:
//LCD开启显示
//*******************************************************************/
void LCD_DisplayOn(void) {ST7735S_write_reg(0X29);    //开启显示
}//*******************************************************************/
//函数:void LCD_DisplayOff(void)
//函数功能:
//LCD关闭显示
//*******************************************************************/void LCD_DisplayOff(void) {ST7735S_write_reg(0X28);    //关闭显示}/**************************************************************************/
//函数:void LCD_Display_Dir(u8 dir)
//函数功能:设置LCD的显示方向及像素参数//输入参数://设置LCD显示方向dir:   0,竖屏  正
//         1,竖屏  反
//         2,横屏  左
//         3,横屏  右
//*************************************************************************/
void LCD_Display_Dir(ST7735S_DIR_MODE dir) {ST7735S_DEV.CNF.screen_mode = dir;uint16_t width, high;switch (ST7735S_DEV.CNF.screen_mode) {case VER_0_MODE: { //竖屏  正width = ST7735S_SCREEN_WIDTH;high = ST7735S_SCREEN_HIGH;ST7735S_DEV.CNF.CMD.wramcmd = 0X2C;ST7735S_DEV.CNF.CMD.setxcmd = 0X2A;ST7735S_DEV.CNF.CMD.setycmd = 0X2B;ST7735S_write_reg_val(0x36, 0xC0);//选择扫描方向}break;case VER_1_MODE: {width = ST7735S_SCREEN_WIDTH;high = ST7735S_SCREEN_HIGH;ST7735S_DEV.CNF.CMD.wramcmd = 0X2C;ST7735S_DEV.CNF.CMD.setxcmd = 0X2A;ST7735S_DEV.CNF.CMD.setycmd = 0X2B;ST7735S_write_reg_val(0x36, 0x40);//选择扫描方向}break;case HOR_0_MODE: {width = ST7735S_SCREEN_HIGH;high = ST7735S_SCREEN_WIDTH;ST7735S_DEV.CNF.CMD.wramcmd = 0X2C;ST7735S_DEV.CNF.CMD.setxcmd = 0X2A;ST7735S_DEV.CNF.CMD.setycmd = 0X2B;ST7735S_write_reg_val(0x36, 0xA0);//选择扫描方向}break;case HOR_1_MODE: {width = ST7735S_SCREEN_HIGH;high = ST7735S_SCREEN_WIDTH;ST7735S_DEV.CNF.CMD.wramcmd = 0X2C;ST7735S_DEV.CNF.CMD.setxcmd = 0X2A;ST7735S_DEV.CNF.CMD.setycmd = 0X2B;ST7735S_write_reg_val(0x36, 0x60);//选择扫描方向}break;}ST7735S_DEV.CNF.width = width;ST7735S_DEV.CNF.height = high;//以下设置,为窗口参数设置,设置了全屏的显示范围LCD_Set_Window(0, 0, width, high);//设置全屏窗口}/**************************************************************************/
//函数功能:设置LCD的显示窗口
//设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
//sx,sy:窗口起始坐标(左上角)
//width,height:窗口宽度和高度,必须大于0!!
//窗体大小:width*height.
//*************************************************************************/
void LCD_Set_Window(uint16_t sx, uint16_t sy, uint16_t width, uint16_t height) {width = sx + width - 1;height = sy + height - 1;if (ST7735S_DEV.CNF.screen_mode == VER_0_MODE || ST7735S_DEV.CNF.screen_mode == VER_1_MODE) {ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setxcmd);ST7735S_write_dat_u16(sx + 2);      //设置 X方向起点ST7735S_write_dat_u16(width + 2);   //设置 X方向终点ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setycmd);ST7735S_write_dat_u16(sy + 1);      //设置 Y方向起点ST7735S_write_dat_u16(height + 1);  //设置 Y方向终点} else {ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setxcmd);ST7735S_write_dat_u16(sx + 1);      //设置 X方向起点ST7735S_write_dat_u16(width + 1);   //设置 X方向终点ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setycmd);ST7735S_write_dat_u16(sy + 2);      //设置 Y方向起点ST7735S_write_dat_u16(height + 2);  //设置 Y方向终点}
}
/*******************************************************************************/
//函数:void LCD_Clear(u16 color)
//函数功能:全屏清屏填充函数
//输入参数:
//color:要清屏的填充色
/*******************************************************************************/void LCD_Clear(uint16_t color) {uint32_t index = 0;uint32_t totalpoint;LCD_Set_Window(0, 0, ST7735S_DEV.CNF.width, ST7735S_DEV.CNF.height);//设置全屏窗口totalpoint = ST7735S_DEV.CNF.width * ST7735S_DEV.CNF.height;            //得到总点数LCD_SetCursor(0, 0);    //设置光标位置LCD_WriteRAM_Prepare();            //开始写入GRAMfor (index = 0; index < totalpoint; index++) {ST7735S_write_dat_u16(color);}
}//*******************************************************************/
//函数功能:设置光标位置
//输入参数:
//Xpos:横坐标
//Ypos:纵坐标
//*******************************************************************/
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos) {if (ST7735S_DEV.CNF.screen_mode == VER_0_MODE || ST7735S_DEV.CNF.screen_mode == VER_1_MODE) {ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setxcmd);ST7735S_write_dat_u16(Xpos);ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setycmd);ST7735S_write_dat_u16(Ypos);} else {ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setxcmd);ST7735S_write_dat_u16(Xpos);ST7735S_write_reg(ST7735S_DEV.CNF.CMD.setycmd);ST7735S_write_dat_u16(Ypos);}}
//*******************************************************************/
//函数:void LCD_WriteRAM_Prepare(void)
//函数功能:开始写GRAM  命令
//*******************************************************************/void LCD_WriteRAM_Prepare(void) {ST7735S_write_reg(ST7735S_DEV.CNF.CMD.wramcmd);
}
//*******************************************************************/
//函数:void LCD_DrawPoint(u16 x,u16 y)
//函数功能:画点
//输入参数:
//x,y:坐标
//POINT_COLOR:此点的颜色
//*******************************************************************/void LCD_DrawPoint(uint16_t x, uint16_t y) {LCD_SetCursor(x, y);        //设置光标位置LCD_WriteRAM_Prepare();    //开始写入GRAMST7735S_write_dat_u16(ST7735S_DEV.CNF.point_color);
}//*******************************************************************/
//函数:LCD_WriteRAM(u16 RGB_Code)
//函数功能:写入点阵颜色值
//输入参数:
//RGB_Code:颜色值
//*******************************************************************/void LCD_WriteRAM(uint16_t RGB_Code) {ST7735S_write_dat_u16(RGB_Code);//写十六位GRAM
}
/*******************************************************************************/
//函数:void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)//函数功能:区域填充函数
//输入参数:
//在指定区域内填充指定颜色块
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)
//color:要填充的颜色
/*******************************************************************************/void LCD_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color) {uint32_t i;uint16_t xlen = 0;//设置窗口LCD_Set_Window(sx, sy, ex - sx, ey - sy);//设置窗口ST7735S_write_reg(ST7735S_DEV.CNF.CMD.wramcmd);xlen = (ex - sx) * (ey - sy);//计算出总共需要写入的点数LCD_WriteRAM_Prepare();                //开始写入GRAMfor (i = 0; i <= xlen; i++) {ST7735S_write_dat_u16(color);    //显示颜色}//以下设置,为窗口参数设置,设置了全屏的显示范围LCD_Set_Window(0, 0, ST7735S_DEV.CNF.width, ST7735S_DEV.CNF.height);//设置全屏窗口}
//*******************************************************************/
//函数:void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)
//函数功能:快速画点
//输入参数:
//x,y:坐标
//color:颜色
//*******************************************************************/void LCD_Fast_DrawPoint(uint16_t x, uint16_t y, uint16_t color) {LCD_SetCursor(x, y);        //设置光标位置ST7735S_write_reg(ST7735S_DEV.CNF.CMD.wramcmd);ST7735S_write_dat_u16(color); //写入16位颜色}
/*******************************************************************************/
//函数:void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
//函数功能:画矩形
//输入参数:
//(x1,y1),(x2,y2):矩形的对角坐标
//Color;线条颜色
/*******************************************************************************/void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color) {LCD_DrawLine(x1, y1, x2, y1, Color);LCD_DrawLine(x1, y1, x1, y2, Color);LCD_DrawLine(x1, y2, x2, y2, Color);LCD_DrawLine(x2, y1, x2, y2, Color);
}
/*******************************************************************************/
//函数功能:画线
//输入参数:
//x1,y1:起点坐标
//x2,y2:终点坐标
//Color;线条颜色
/*******************************************************************************/
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color) {uint16_t t;int xerr = 0, yerr = 0, delta_x, delta_y, distance;int incx, incy, uRow, uCol;delta_x = x2 - x1; //计算坐标增量delta_y = y2 - y1;uRow = x1;uCol = y1;if (delta_x > 0)incx = 1; //设置单步方向else if (delta_x == 0)incx = 0;//垂直线else {incx = -1;delta_x = -delta_x;}if (delta_y > 0)incy = 1;else if (delta_y == 0)incy = 0;//水平线else {incy = -1;delta_y = -delta_y;}if (delta_x > delta_y)distance = delta_x; //选取基本增量坐标轴else distance = delta_y;for (t = 0; t <= distance + 1; t++)//画线输出{LCD_Fast_DrawPoint(uRow, uCol, Color);//画点 --使用输入颜色参数xerr += delta_x;yerr += delta_y;if (xerr > distance) {xerr -= distance;uRow += incx;}if (yerr > distance) {yerr -= distance;uCol += incy;}}
}
/*******************************************************************************/
//函数:void LCD_Draw_Circle(u16 x0,u16 y0,u8 r)
//函数功能:在指定位置画一个指定大小的圆
//输入参数:
//(x,y):中心点
//r    :半径
//Color;线条颜色
/*******************************************************************************/void LCD_Draw_Circle(uint16_t x0, uint16_t y0, uint8_t r, uint16_t Color) {int a, b;int di;a = 0;b = r;di = 3 - (r << 1);             //判断下个点位置的标志while (a <= b) {LCD_Fast_DrawPoint(x0 + a, y0 - b, Color);             //5LCD_Fast_DrawPoint(x0 + b, y0 - a, Color);             //0LCD_Fast_DrawPoint(x0 + b, y0 + a, Color);             //4LCD_Fast_DrawPoint(x0 + a, y0 + b, Color);             //6LCD_Fast_DrawPoint(x0 - a, y0 + b, Color);             //1LCD_Fast_DrawPoint(x0 - b, y0 + a, Color);LCD_Fast_DrawPoint(x0 - a, y0 - b, Color);             //2LCD_Fast_DrawPoint(x0 - b, y0 - a, Color);             //7a++;//使用Bresenham算法画圆if (di < 0)di += 4 * a + 6;else {di += 10 + 4 * (a - b);b--;}}
}

硬件驱动(SPI3,这里使用的)

//
// Created by shchl on 2024/2/28.
//
#include "st7735s.h"
#include "drv_common.h"
#include "drv_spi.h"#define DBG_ENABLE
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG#include <rtdbg.h>struct rt_spi_device *st7735s_device = RT_NULL;static void spi_cris_enter(void) { rt_spi_take_bus(st7735s_device); }static void spi_cris_exit(void) { rt_spi_release_bus(st7735s_device); }static void spi_cs_deselect(void) { rt_spi_release(st7735s_device); }static void spi_cs_select(void) { rt_spi_take(st7735s_device); }static void dc_dat_select(void) { rt_pin_write(ST7735S_DC_PIN, PIN_HIGH); }static void dc_reg_select(void) { rt_pin_write(ST7735S_DC_PIN, PIN_LOW); }static void spi_write_byte(uint8_t data) { rt_spi_send(st7735s_device, &data, 1); }rt_err_t st7735s_device_init(const char *spi_dev_name) {//将spi设备挂载到总线rt_hw_spi_device_attach(ST7735S_BUS_NAME, spi_dev_name, GPIOB, GPIO_PIN_14);/* 查找 spi 设备获取设备句柄 */st7735s_device = (struct rt_spi_device *) rt_device_find(spi_dev_name);if (st7735s_device == NULL) {LOG_W("未找到该设备");return -RT_ERROR;} else {LOG_W("找到该设备");//配置spi参数struct rt_spi_configuration cfg;{cfg.data_width = 8;//数据宽度为八位cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;cfg.max_hz = 40 * 1000 * 1000;//最大波特率,因为在cubemx配置分频后,spi2的波特率是4.5M,所以这里最大就写5了}rt_spi_configure(st7735s_device, &cfg);}return RT_EOK;
}static void st7735s_callback_register() {/* register critical section callback function */reg_st7735s_cris_cbfunc(spi_cris_enter, spi_cris_exit);/* register SPI device CS select callback function */reg_st7735s_cs_cbfunc(spi_cs_select, spi_cs_deselect);/* register DC select callback function */reg_st7735s_dc_cbfunc(dc_dat_select, dc_reg_select);/* register SPI write data callback function */reg_st7735s_spi_cbfunc(spi_write_byte);
}
//********************************************************************************/
//函数:void LCD_SoftRest(void)
//函数功能:给屏幕发命令,执行软复位命令
//LCD开启显示
//*******************************************************************/
void LCD_SoftRest(void) {rt_pin_write(ST7735S_RESET_PIN, PIN_LOW);rt_thread_mdelay(100);rt_pin_write(ST7735S_RESET_PIN, PIN_HIGH);rt_thread_mdelay(1000);
}void st7735s_init(void) {rt_err_t result = RT_EOK;/*初始化对应的引脚*/rt_pin_mode(ST7735S_DC_PIN, PIN_MODE_OUTPUT);rt_pin_mode(ST7735S_RESET_PIN, PIN_MODE_OUTPUT);
//    rt_pin_mode(ST7735S_CS_PIN, PIN_MODE_OUTPUT);rt_pin_mode(ST7735S_BLK_PIN, PIN_MODE_OUTPUT);result = st7735s_device_init(ST7735S_SPI_DEVICE);if (result != RT_EOK) goto __exit;/* 回调函数注册 */st7735s_callback_register();__exit:if (result == RT_EOK) {LOG_I("st7735s_init initialize success.");} else {LOG_I("st7735s_init initialize err:%d.", result);}
}

测试调用

int main(void) {LCD_Init();for (int i = 0; i < 100; ++i) {LCD_Fast_DrawPoint(10,i,RED);}for (;;) {rt_thread_mdelay(1000);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/707231.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css常用的选择器介绍

CSS&#xff08;层叠样式表&#xff09;选择器是CSS规则的一部分&#xff0c;它用于选择和定位网页上的元素&#xff0c;以便将样式应用到这些元素上。CSS选择器的种类繁多&#xff0c;每种选择器都有其特定的用途、特点和效率。在这篇文章中&#xff0c;我们将讨论一些常用的C…

Spring Boot项目如何快速从零开始打造一个属于自己的RPC框架

一、前言 在平时Spring Boot项目开发过程中,我们进行远程服务调用大都采用@RestController + @RequestMapping相关注解发布接口,使用OpenFeign组件进行微服务之间调用。这套技术架构已经足够完善了,当然没有什么问题,但是作为一个开发者,老是用一套框架天天写代码,不免有…

环境分析检测小剂量移液用耐受硝酸盐酸PFA材质吸管特氟龙移液枪枪头

PFA枪头&#xff0c;为移液枪专业定制&#xff0c;广泛用于ICP-MS、ICP-OES等痕量分析以及同位素分析等实验室。地质、电子化学品、半导体分析测试、疾控中心、制药厂、环境检测中心等一些机构少量移液用。 规格参考:0.1-0.2ml、1ml、2ml、5ml、10ml等。 目前部分规格可适配普…

什么是智能运维产品线和服务线

智能运维产品线和服务线涵盖了一系列自动化和智能化的技术和服务&#xff0c;旨在提升IT运维的效率和有效性。智能运维&#xff08;AIOps&#xff09;利用大数据、分析技术和机器学习能力来自动执行和简化运营工作流程&#xff0c;包括收集和汇总多源IT基础架构组件的数据、应用…

ARTS Week 18

Algorithm 本周的算法题为 485. 最大连续 1 的个数 给定一个二进制数组 nums &#xff0c; 计算其中最大连续 1 的个数。 示例 1&#xff1a;输入&#xff1a;nums [1,1,0,1,1,1]输出&#xff1a;3解释&#xff1a;开头的两位和最后的三位都是连续 1 &#xff0c;所以最大连续…

el-checkbox实现全选,反选,单选

<template><div class"box"><el-checkbox v-model"checkAll" :indeterminate"isIndeterminate" change"onAllSelectChange"> 全选</el-checkbox><div class"item" v-for"(item,index) in l…

R语言——条形图数据可视化的多种方式

本文章将会介绍如何使用R语言中的ggplot2包使用条形图进行数据可视化。将会使用一个“生产企业原材料的订购与运输”的订单数据&#xff0c;该数据来自2021数学建模国赛C题。 某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料总体可分为 A B C 三种类…

【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C那些事儿 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 1. 面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符…

使用 Python 和CE进行游戏修改

你好。在这篇文章中,我将向您展示如何通过使用作弊引擎编辑内存来破解游戏,并且还将用 python 编写一个程序,该程序将自动编辑内存并为我们进行破解。当我学习游戏黑客时,我注意到关于使用 python 进行游戏黑客的资源很少,而关于 c++ 的资源更多。但我是 python 的忠实粉丝…

【蓝桥杯】快读|min和max值的设置|小明和完美序列|​顺子日期​|星期计算|山

目录 一、输入的三种方式 1.最常见的Scanner的输入方法 2.数据多的时候常用BufferedReader快读 3.较麻烦的StreamTokenizer快读&#xff08;用的不多&#xff09; StreamTokenizer常见错误&#xff1a; 二、min和max值的设置 三、妮妮的翻转游戏 四、小明和完美序列 五…

AI引擎助力,CamScanner智能高清滤镜开启扫描新纪元!

文章目录 ⭐ 写在前面⭐ 突破图像处理难点&#xff1a;扫描全能王的独特优势⭐ 耳听为虚&#xff0c;眼见为实⭐ 产品背后的主要核心&#xff1a;AI-Scan助力⭐ 深度学习助力智能文档处理的国际化进程⭐ 品味智能文档处理的轻松与精准 ⭐ 写在前面 在数字化快速发展的今天&…

MySQL 篇-深入了解 DML、DQL 语言(二)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 DML、DQL 语言说明 2.0 使用 DML 实现对数据管理和操作 2.1 DML - 增添数据 insert 2.2 DML - 修改数据 update 2.3 DML - 删除数据 delete 3.0 使用 DQL 实现对…

数据界的达克摩斯之剑----深入浅出带你理解网络爬虫(Forth)

目录 3.爬虫身份识别 4.用户爬虫的例子 4.1 开源爬虫 网络爬虫的组成 控制器 解析器 资源库 3.爬虫身份识别 网络爬虫通过使用http请求的用户代理&#xff08;User Agent&#xff09;字段来向网络服务器表明他们的身份。网络管理员则通过检查网络服务器的日志&#xff0…

77. 组合(力扣LeetCode)

文章目录 77. 组合题目描述回溯算法组合问题的剪枝操作 77. 组合 题目描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [ [2,4], [3,4],…

ArcgisForJS如何将ArcGIS Server发布的点要素渲染为热力图?

文章目录 0.引言1.ArcGIS创建点要素2.ArcGIS Server发布点要素3.ArcgisForJS将ArcGIS创建的点要素渲染为热力图 0.引言 ArcGIS For JS 是一个强大的地理信息系统&#xff08;GIS&#xff09;工具&#xff0c;它允许开发者使用 JavaScript 语言来创建各种 GIS 应用。ArcGIS Ser…

DolphinScheduler——介绍及架构设计

目录 一、DolphinScheduler介绍 1.1 概述 1.2 特性 1.2.1 简单易用 1.2.2 丰富的使用场景 1.2.3 High Reliability 1.2.4 High Scalability 1.3 名词解释 1.3.1 名词解释 1.3.2 模块介绍 二、DolphinScheduler架构原理 2.1 系统架构图 2.2 架构说明 2.2.1 Maste…

音频混音算法的实现

最近项目有用到混音算法&#xff0c;这里用比较常见的一种&#xff0c;就是简单的加和之后做一下归一化。 是参考这个博主实现的&#xff1a; 音频混音的算法实现 下面直接贴代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <math.h&…

Python学习 day05(异常、模块导入)

异常 为什么要捕获异常 当程序遇到了BUG&#xff0c;如果不对BUG进行手动捕获&#xff0c;那么整个程序就会因为一个BUG而停止运行&#xff0c;这在有些情况下是会造成很大的损失&#xff0c;但是如果我们进行了手动捕获&#xff0c;那么整个程序会继续运行捕获异常的作用在于&…

vue-router4 (六) 命名视图

命名视图可以使得同一级&#xff08;同一个组件&#xff09;中展示更多的路由视图&#xff0c;而不是嵌套显示&#xff0c; 命名视图可以让一个组件中具有多个路由渲染出口&#xff0c;这对于一些特定的布局组件非常有用。 应用场景&#xff1a; 比如点击login切换到组件A&am…

vue3第三节(v-model 执行原理)

特殊说明&#xff1a; 以下vue3语法是基于 3.4之前版本进行使用的&#xff0c;3.4之后的版本 引入了 defineModel 宏&#xff0c;后续会介绍defineModel 1、vue3 与vue2 中v-model区别 vue3 中v-model绑定的不再是value&#xff0c;而是modelValue&#xff0c;接收的方法也不再…