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 enter
        void (*_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 exit
    HAL_Delay(120);      // delay 120 ms
    //ST7735R Frame Rate
    ST7735S_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 inversion
    ST7735S_write_dat_u8(0x07);
    //ST7735R Power Sequence
    ST7735S_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); //VCOM
    ST7735S_write_dat_u8(0x0E);
    ST7735S_write_reg(0x36); //MX, MY, RGB mode
    ST7735S_write_dat_u8(0xC0);
    //ST7735R Gamma Sequence
    ST7735S_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 command
    ST7735S_write_dat_u8(0x01);
    ST7735S_write_reg(0xF6); //Disable ram power save mode
    ST7735S_write_dat_u8(0x00);
    ST7735S_write_reg(0x3A); //65k mode
    ST7735S_write_dat_u8(0x05);
    ST7735S_write_reg(0x29);//Display on
    LCD_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();            //开始写入GRAM
    for (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();    //开始写入GRAM
    ST7735S_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();                //开始写入GRAM

    for (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);             //5
        LCD_Fast_DrawPoint(x0 + b, y0 - a, Color);             //0
        LCD_Fast_DrawPoint(x0 + b, y0 + a, Color);             //4
        LCD_Fast_DrawPoint(x0 + a, y0 + b, Color);             //6
        LCD_Fast_DrawPoint(x0 - a, y0 + b, Color);             //1
        LCD_Fast_DrawPoint(x0 - b, y0 + a, Color);
        LCD_Fast_DrawPoint(x0 - a, y0 - b, Color);             //2
        LCD_Fast_DrawPoint(x0 - b, y0 - a, Color);             //7
        a++;
        //使用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);

    }
}


  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

詩不诉卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值