STM32使用软件SPI协议操作TFT18彩屏

时间记录:2024/2/20

一、SPI协议介绍

(1)SPI设备通过4根线进行通信,CS片选线,选择从设备,SCK时钟线,由主设备产生时钟,主机MOSI线连从机MISO线,由主机向从机发送信息,主机MISO线连接从机MOSI线,由从机向主机发送信息

(2)SPI分为4种通信方式

模式0:CPOL=0,CPHA=0,空闲时SCK时钟线为低电平,在奇数边沿进行数据采集,在偶数边沿时进行数据变换,数据采集在上升沿,数据变换在下降沿

模式1:CPOL=0,CPHA=1,空闲时SCK时钟为低电平,在偶数边沿进行数据采集,在奇数边沿时进行数据变换,数据采集在下降沿,数据变换在上升沿

模式2:CPOL=1,CPHA=0,空闲时SCK时钟为高电平,在奇数边沿进行数据采集,在偶数边沿时进行数据变换,数据采集在下降沿,数据变换在上升沿

模式3:CPOL=1,CPHA=1,空闲时SCK时钟为高电平,在偶数边沿进行数据采集,在奇数边沿时进行数据变换,数据采集在上升沿,数据变换在下降沿

(3)常用的模式是0和3,具体的操作要根据从机模块的数据手册进行选择

二、tft18显示屏介绍

(1)引脚介绍(1.8寸TFT18显示屏,驱动为ST7735)

引脚 介绍
GND 电源地
VCC 电源线
SCL 时钟线
SDA 数据输入线
RES 复位线,低电平复位
DC 命令/数据选择线,低电平选择命令寄存器,高电平选择数据寄存器
CS 片选线,低电平选中
BL 背光线,可通过PWM控制背光亮度,默认高电平全亮

(2)SPI模式,模式3,在上升沿采集数据,下降沿更改数据

三、示例代码

(1)头文件

c 复制代码
#ifndef __TFT18_H__
#define __TFT18_H__
#include <stm32f10x.h>
#include "delay.h"

#define LCD_WIDTH       128
#define LCD_HEIGHT      160
#define LCDXOFFSET      1
#define LCDYOFFSET      0

#define LCD_RCC         RCC_APB2Periph_GPIOA
#define LCD_GPIO        GPIOA
#define LCD_SCL_PIN     GPIO_Pin_0
#define LCD_SDA_PIN     GPIO_Pin_1
#define LCD_RES_PIN     GPIO_Pin_2
#define LCD_DC_PIN      GPIO_Pin_3
#define LCD_CS_PIN      GPIO_Pin_4

#define SET_SCL         GPIO_SetBits(LCD_GPIO,LCD_SCL_PIN);
#define SET_SDA         GPIO_SetBits(LCD_GPIO,LCD_SDA_PIN);
#define SET_RES         GPIO_SetBits(LCD_GPIO,LCD_RES_PIN);
#define SET_DC          GPIO_SetBits(LCD_GPIO,LCD_DC_PIN);
#define SET_CS          GPIO_SetBits(LCD_GPIO,LCD_CS_PIN);

#define RESET_SCL       GPIO_ResetBits(LCD_GPIO,LCD_SCL_PIN);
#define RESET_SDA       GPIO_ResetBits(LCD_GPIO,LCD_SDA_PIN);
#define RESET_RES       GPIO_ResetBits(LCD_GPIO,LCD_RES_PIN);
#define RESET_DC        GPIO_ResetBits(LCD_GPIO,LCD_DC_PIN);
#define RESET_CS        GPIO_ResetBits(LCD_GPIO,LCD_CS_PIN);

//颜色显示565,RGB888ToRGB565:R取高5位,G取中间6位,B取低5位
#define TFT_BLACK       0x0000//黑色
#define TFT_WHITE       0xFFFF//白色
#define TFT_RED         0xF800//红色
#define TFT_GREEN       0x07E0//绿色
#define TFT_BLUE        0x001F//蓝色
#define TFT_YELLOW      0xFFE0//黄色

#define STR_MAX_COUNT   16

void vTft18Init(void);//显示屏初始化
void vTft18Clear(void);//清屏函数
void vTft18ShowStr(u8 row,u8 col,u16 bkColor,u16 color,const char *fmt,...);//显示字符串
void vTft18DrawPic(void);//绘制图片

#endif

(2)源文件

c 复制代码
#include "tft18.h"
#include "tft18_font.h"
#include "img.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

//初始化GPIO口
static void vGpioInit(void)
{
    RCC_APB2PeriphClockCmd(LCD_RCC,ENABLE);//使能时钟
    
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = LCD_SCL_PIN | LCD_SDA_PIN | LCD_RES_PIN | LCD_DC_PIN | LCD_CS_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LCD_GPIO,&GPIO_InitStruct);//初始化GPIO口
    
    vDelayInit();
}

//复位LCD,低电平>10us,高电平大于120ms
static void vTft18Reset(void)
{
    SET_RES;
    vDelayMs(10);
    RESET_RES;
    vDelayMs(10);
    SET_RES;
    vDelayMs(150);
}

//写命令:DC=0
static void vWriteCmd(u8 data)
{
    RESET_CS;
    RESET_DC;//写命令
    
    for(u8 i=0;i<8;i++){//发送命令,高位先发
        if(data & 0x80){
            SET_SDA;
        }else{
            RESET_SDA;
        }
        RESET_SCL;
        SET_SCL;//产生上升沿将数据发送出去
        data <<= 1;
    }
    SET_CS;//拉高选择线空闲状态
}

//写数据:DC=1
static void vWriteData(u8 data)
{
    RESET_CS;
    SET_DC;//写数据
    
    for(u8 i=0;i<8;i++){//发送命令,高位先发
        if(data & 0x80){
            SET_SDA;
        }else{
            RESET_SDA;
        }
        RESET_SCL;
        SET_SCL;//产生上升沿将数据发送出去
        data <<= 1;
    }
    SET_CS;//拉高选择线空闲状态
}

//写16位颜色数据
static void vWriteU16Data(u16 data)
{
    vWriteData(data >> 8);
    vWriteData(data & 0xFF);
}

//初始化参数设置
static void vTft18InitParameter(void)
{
    vWriteCmd(0x11);//退出睡眠模式
    
//    vWriteCmd(0xB1);
//    vWriteData(0x05);
//    vWriteData(0x3C);
//    vWriteData(0x3C);
//    
//    vWriteCmd(0xB2);
//    vWriteData(0x05);
//    vWriteData(0x3C);
//    vWriteData(0x3C);
//    
//    vWriteCmd(0xB3);
//    vWriteData(0x05);
//    vWriteData(0x3C);
//    vWriteData(0x3C);
//    vWriteData(0x05);
//    vWriteData(0x3C);
//    vWriteData(0x3C);
//    
//    vWriteCmd(0xB4);
//    vWriteData(0x03);
//    
//    vWriteCmd(0xC0);
//    vWriteData(0x28);
//    vWriteData(0x08);
//    vWriteData(0x04);
//    
//    vWriteCmd(0xC1);
//    vWriteData(0xC0);
//    
//    vWriteCmd(0xC2);
//    vWriteData(0x0D);
//    vWriteData(0x00);
//    
//    vWriteCmd(0xC3);
//    vWriteData(0x8D);
//    vWriteData(0x2A);
//    
//    vWriteCmd(0xC4);
//    vWriteData(0x8D);
//    vWriteData(0xEE);
//    
//    vWriteCmd(0xC5);
//    vWriteData(0x1A);
    
    vWriteCmd(0x36);//显存控制
    vWriteData(0xC0);//设置显存指针自动移动的方向为从左到右,从上到下,颜色数据格式为RGB
    
//    vWriteCmd(0xE0);
//    vWriteData(0x04);
//    vWriteData(0x22);
//    vWriteData(0x07);
//    vWriteData(0x0A);
//    vWriteData(0x2E);
//    vWriteData(0x30);
//    vWriteData(0x25);
//    vWriteData(0x2A);
//    vWriteData(0x28);
//    vWriteData(0x26);
//    vWriteData(0x2E);
//    vWriteData(0x3A);
//    vWriteData(0x00);
//    vWriteData(0x01);
//    vWriteData(0x03);
//    vWriteData(0x13);
//    
//    vWriteCmd(0xE1);
//    vWriteData(0x04);
//    vWriteData(0x16);
//    vWriteData(0x06);
//    vWriteData(0x0D);
//    vWriteData(0x2D);
//    vWriteData(0x26);
//    vWriteData(0x23);
//    vWriteData(0x27);
//    vWriteData(0x27);
//    vWriteData(0x25);
//    vWriteData(0x2D);
//    vWriteData(0x3B);
//    vWriteData(0x00);
//    vWriteData(0x01);
//    vWriteData(0x04);
//    vWriteData(0x13);
    
    vWriteCmd(0x3A);//设置颜色格式
    vWriteData(0x05);//设置颜色格式为16bit
    
    vWriteCmd(0x29);//开启显示
}

//x:128
//y:160
//显示范围[xEnd-xStart,yEnd-yStart],[1-128,1,160]
static void vSetAddr(u8 xStart,u8 yStart,u8 xEnd,u8 yEnd)
{
    //设置显示RAM范围
    vWriteCmd(0x2A);//xMax:128,设置列显示的起始和结束地址
    vWriteData(0x00);//此位无效
    vWriteData(xStart+LCDXOFFSET);//此位有效
    vWriteData(0x00);//此位无效
    vWriteData(xEnd+LCDXOFFSET);//此位有效
    
    vWriteCmd(0x2B);//yMax:160,设置行显示的起始和结束地址
    vWriteData(0x00);//此位无效
    vWriteData(yStart+LCDYOFFSET);//此位有效
    vWriteData(0x00);//此位无效
    vWriteData(yEnd+LCDYOFFSET);//此位有效
    
    vWriteCmd(0x2C);//开始向设定的区域填充颜色
}

void vTft18Init(void)
{
    vGpioInit();
    
    vTft18Reset();
    
    vTft18InitParameter();
}

void vTft18Clear(void)
{
    vSetAddr(1,1,LCD_WIDTH,LCD_HEIGHT);//设置显示范围
    for(u8 col=0;col<LCD_WIDTH;col++){
        for(u8 row=0;row<LCD_HEIGHT;row++){
            vWriteU16Data(TFT_BLUE);
        }
    }
}

void vTft18ShowStr(u8 row,u8 col,u16 bkColor,u16 color,const char *fmt,...)
{    
    char tempStr[STR_MAX_COUNT];
    memset(tempStr,0,sizeof(tempStr));
    
    //拼接不定参数
    va_list vaList;
    va_start(vaList,fmt);
    vsnprintf(tempStr,STR_MAX_COUNT,fmt,vaList);
    va_end(vaList);
    
    //进行显示
    int len = strlen(tempStr);
    vSetAddr(col,(row-1)*16+1,8*len+col-1,row*16);
    
    //显示点,从xStart-xEnd xStart+1-xEnd+1 ... xStart+yEnd-xEnd+yEnd
    for(int currRow= 0;currRow<16;currRow++){//当前行,16行
        for(int k=0;k<len;k++){
            int index = tempStr[k]-' ';
            for(int currCol=0;currCol<8;currCol++){//当前列,8列
                if((char8x16[index][currRow] << currCol) &0x80)
                    vWriteU16Data(color);
                else
                    vWriteU16Data(bkColor);
            }
        }
    }
}

void vTft18DrawPic(void)
{
    vSetAddr(1,1,LCD_WIDTH,LCD_HEIGHT);
    
    for(int index =0;index<LCD_WIDTH*LCD_HEIGHT*2;index+=2){
        vWriteU16Data((image[index] << 8) + image[index+1]);
    }
}
相关推荐
智商偏低2 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen3 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森5 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白5 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D6 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术9 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt9 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘9 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang10 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
几个几个n12 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件