当前位置: 首页 > news >正文

第31讲:实战——SPI屏驱动快速试错、点亮屏幕

CSDN专栏:

  • 嵌入式程序开发实战
  • 嵌入式双范式AI编程
  • 嵌入式开发必掌握
  • 嵌入式求职面试技术资料

第31讲:实战——SPI屏驱动快速试错、点亮屏幕

一、SPI屏幕驱动基础

SPI屏幕是嵌入式常见的显示设备,驱动屏幕需要正确配置SPI、理解屏幕控制命令、实现绘图功能。

1.1 常见SPI屏幕

小尺寸屏幕

  • 0.96寸 OLED(SSD1306):128x64
  • 1.3寸 OLED(SH1106):128x64
  • 1.8寸 TFT(ST7735):128x160
  • 2.4寸 TFT(ILI9341):240x320

SPI接口

  • SCK:时钟
  • MOSI:主出从入(数据)
  • MISO:主入从出(可选)
  • CS:片选
  • DC:数据/命令选择
  • RST:复位

1.2 驱动要点

SPI配置

  • 模式:主机模式
  • 时钟极性/相位:根据屏幕芯片确定
  • 速率:通常10-40MHz
  • 数据位:8位

控制命令

  • 初始化序列:配置屏幕参数
  • 写命令:发送控制命令
  • 写数据:发送显示数据
  • 刷新:更新显示

二、OLED屏幕驱动(SSD1306)

2.1 快速试错流程

第一步:AI生成初始驱动

Prompt

生成STM32F103 SSD1306 OLED驱动: - SPI1:PA5(SCK)、PA7(MOSI) - CS:PA4 - DC:PA6 - RST:PB0 - 屏幕:0.96寸,128x64 - 使用HAL库

AI生成

#include"stm32f1xx_hal.h"#defineSSD1306_WIDTH128#defineSSD1306_HEIGHT64SPI_HandleTypeDef hspi1;voidSSD1306_Init(void);voidSSD1306_WriteCommand(uint8_tcmd);voidSSD1306_WriteData(uint8_t*data,uint16_tlen);voidSSD1306_Fill(uint8_tcolor);voidSSD1306_Update(void);// CS控制#defineSSD1306_CS_LOW()HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET)#defineSSD1306_CS_HIGH()HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET)// DC控制#defineSSD1306_DC_LOW()HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET)// 命令#defineSSD1306_DC_HIGH()HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET)// 数据// RST控制#defineSSD1306_RST_LOW()HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET)#defineSSD1306_RST_HIGH()HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET)voidSPI1_Init(void){hspi1.Instance=SPI1;hspi1.Init.Mode=SPI_MODE_MASTER;hspi1.Init.Direction=SPI_DIRECTION_2LINES;hspi1.Init.DataSize=SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity=SPI_POLARITY_LOW;hspi1.Init.CLKPhase=SPI_PHASE_1EDGE;hspi1.Init.NSS=SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4;hspi1.Init.FirstBit=SPI_FIRSTBIT_MSB;HAL_SPI_Init(&hspi1);}voidSSD1306_WriteCommand(uint8_tcmd){SSD1306_CS_LOW();SSD1306_DC_LOW();// 命令模式HAL_SPI_Transmit(&hspi1,&cmd,1,100);SSD1306_CS_HIGH();}voidSSD1306_WriteData(uint8_t*data,uint16_tlen){SSD1306_CS_LOW();SSD1306_DC_HIGH();// 数据模式HAL_SPI_Transmit(&hspi1,data,len,100);SSD1306_CS_HIGH();}voidSSD1306_Init(void){// 复位SSD1306_RST_LOW();HAL_Delay(10);SSD1306_RST_HIGH();HAL_Delay(10);// 初始化序列SSD1306_WriteCommand(0xAE);// 关闭显示SSD1306_WriteCommand(0xD5);// 设置时钟分频SSD1306_WriteCommand(0x80);SSD1306_WriteCommand(0xA8);// 设置多路复用率SSD1306_WriteCommand(0x3F);SSD1306_WriteCommand(0xD3);// 设置显示偏移SSD1306_WriteCommand(0x00);SSD1306_WriteCommand(0x40);// 设置起始行SSD1306_WriteCommand(0x8D);// 电荷泵设置SSD1306_WriteCommand(0x14);SSD1306_WriteCommand(0x20);// 内存地址模式SSD1306_WriteCommand(0x00);// 水平寻址模式SSD1306_WriteCommand(0xA1);// 段重映射SSD1306_WriteCommand(0xC8);// COM输出扫描方向SSD1306_WriteCommand(0xDA);// COM引脚配置SSD1306_WriteCommand(0x12);SSD1306_WriteCommand(0x81);// 对比度控制SSD1306_WriteCommand(0xCF);SSD1306_WriteCommand(0xD9);// 预充电周期SSD1306_WriteCommand(0xF1);SSD1306_WriteCommand(0xDB);// VCOMH电压SSD1306_WriteCommand(0x40);SSD1306_WriteCommand(0xA4);// 全屏点亮关闭SSD1306_WriteCommand(0xA6);// 正常显示SSD1306_WriteCommand(0xAF);// 开启显示}staticuint8_tSSD1306_Buffer[SSD1306_WIDTH*SSD1306_HEIGHT/8];voidSSD1306_Fill(uint8_tcolor){memset(SSD1306_Buffer,color?0xFF:0x00,sizeof(SSD1306_Buffer));}voidSSD1306_Update(void){for(uint8_tpage=0;page<8;page++){SSD1306_WriteCommand(0xB0+page);SSD1306_WriteCommand(0x00);SSD1306_WriteCommand(0x10);SSD1306_WriteData(&SSD1306_Buffer[page*SSD1306_WIDTH],SSD1306_WIDTH);}}

第二步:测试验证

intmain(void){HAL_Init();SystemClock_Config();SPI1_Init();SSD1306_Init();// 清屏SSD1306_Fill(0);SSD1306_Update();// 全白SSD1306_Fill(1);SSD1306_Update();while(1);}

第三步:迭代修正

如果屏幕不亮,添加调试:

voidSSD1306_Debug(void){printf("SSD1306 Debug:\r\n");printf("SPI CR1: 0x%04X\r\n",SPI1->CR1);printf("GPIOA CRL: 0x%08X\r\n",GPIOA->CRL);printf("GPIOB CRL: 0x%08X\r\n",GPIOB->CRL);}

三、TFT屏幕驱动(ST7735)

3.1 ST7735驱动

Prompt

生成STM32F103 ST7735 TFT驱动: - SPI1:PA5(SCK)、PA7(MOSI) - CS:PA4 - DC:PA6 - RST:PB0 - 屏幕:1.8寸,128x160 - 使用HAL库

AI生成核心代码

#defineST7735_WIDTH128#defineST7735_HEIGHT160voidST7735_WriteCommand(uint8_tcmd){ST7735_CS_LOW();ST7735_DC_LOW();HAL_SPI_Transmit(&hspi1,&cmd,1,100);ST7735_CS_HIGH();}voidST7735_WriteData(uint8_tdata){ST7735_CS_LOW();ST7735_DC_HIGH();HAL_SPI_Transmit(&hspi1,&data,1,100);ST7735_CS_HIGH();}voidST7735_SetWindow(uint8_tx0,uint8_ty0,uint8_tx1,uint8_ty1){ST7735_WriteCommand(0x2A);// 列地址设置ST7735_WriteData(0x00);ST7735_WriteData(x0);ST7735_WriteData(0x00);ST7735_WriteData(x1);ST7735_WriteCommand(0x2B);// 行地址设置ST7735_WriteData(0x00);ST7735_WriteData(y0);ST7735_WriteData(0x00);ST7735_WriteData(y1);ST7735_WriteCommand(0x2C);// 写内存}voidST7735_DrawPixel(uint8_tx,uint8_ty,uint16_tcolor){ST7735_SetWindow(x,y,x,y);uint8_tdata[2];data[0]=color>>8;data[1]=color&0xFF;ST7735_CS_LOW();ST7735_DC_HIGH();HAL_SPI_Transmit(&hspi1,data,2,100);ST7735_CS_HIGH();}voidST7735_FillColor(uint16_tcolor){ST7735_SetWindow(0,0,ST7735_WIDTH-1,ST7735_HEIGHT-1);uint8_tdata[2];data[0]=color>>8;data[1]=color&0xFF;ST7735_CS_LOW();ST7735_DC_HIGH();for(uint16_ti=0;i<ST7735_WIDTH*ST7735_HEIGHT;i++){HAL_SPI_Transmit(&hspi1,data,2,100);}ST7735_CS_HIGH();}

四、绘图功能实现

4.1 基础绘图函数

画线

voidSSD1306_DrawLine(uint8_tx0,uint8_ty0,uint8_tx1,uint8_ty1){int16_tdx=abs(x1-x0);int16_tdy=abs(y1-y0);int16_tsx=(x0<x1)?1:-1;int16_tsy=(y0<y1)?1:-1;int16_terr=dx-dy;while(1){SSD1306_DrawPixel(x0,y0,1);if(x0==x1&&y0==y1)break;int16_te2=2*err;if(e2>-dy){err-=dy;x0+=sx;}if(e2<dx){err+=dx;y0+=sy;}}}

画矩形

voidSSD1306_DrawRect(uint8_tx,uint8_ty,uint8_tw,uint8_th){SSD1306_DrawLine(x,y,x+w-1,y);SSD1306_DrawLine(x,y+h-1,x+w-1,y+h-1);SSD1306_DrawLine(x,y,x,y+h-1);SSD1306_DrawLine(x+w-1,y,x+w-1,y+h-1);}

画圆

voidSSD1306_DrawCircle(uint8_tx0,uint8_ty0,uint8_tr){int16_tf=1-r;int16_tddF_x=1;int16_tddF_y=-2*r;int16_tx=0;int16_ty=r;SSD1306_DrawPixel(x0,y0+r,1);SSD1306_DrawPixel(x0,y0-r,1);SSD1306_DrawPixel(x0+r,y0,1);SSD1306_DrawPixel(x0-r,y0,1);while(x<y){if(f>=0){y--;ddF_y+=2;f+=ddF_y;}x++;ddF_x+=2;f+=ddF_x;SSD1306_DrawPixel(x0+x,y0+y,1);SSD1306_DrawPixel(x0-x,y0+y,1);SSD1306_DrawPixel(x0+x,y0-y,1);SSD1306_DrawPixel(x0-x,y0-y,1);SSD1306_DrawPixel(x0+y,y0+x,1);SSD1306_DrawPixel(x0-y,y0+x,1);SSD1306_DrawPixel(x0+y,y0-x,1);SSD1306_DrawPixel(x0-y,y0-x,1);}}

4.2 显示文字

ASCII字符显示

// 5x7字体constuint8_tfont5x7[]={0x00,0x00,0x00,0x00,0x00,// 空格0x00,0x00,0x5F,0x00,0x00,// !// ... 字体数据};voidSSD1306_DrawChar(uint8_tx,uint8_ty,charc){for(uint8_ti=0;i<5;i++){uint8_tline=font5x7[(c-32)*5+i];for(uint8_tj=0;j<7;j++){if(line&(1<<j)){SSD1306_DrawPixel(x+i,y+j,1);}}}}voidSSD1306_DrawString(uint8_tx,uint8_ty,char*str){while(*str){SSD1306_DrawChar(x,y,*str);x+=6;str++;}}

五、常见问题与解决

5.1 屏幕不亮

原因

1. SPI配置错误 2. 初始化序列错误 3. 引脚配置错误 4. 复位时序错误

解决

// 验证SPI配置voidSPI_Debug(void){printf("SPI Configuration:\r\n");printf("Mode: %d\r\n",hspi1.Init.Mode);printf("BaudRate: %d\r\n",hspi1.Init.BaudRatePrescaler);printf("CLKPolarity: %d\r\n",hspi1.Init.CLKPolarity);printf("CLKPhase: %d\r\n",hspi1.Init.CLKPhase);}

5.2 显示异常

原因

1. 内存地址模式错误 2. 扫描方向错误 3. 颜色格式错误

解决

// 调整内存地址模式SSD1306_WriteCommand(0x20);// 内存地址模式SSD1306_WriteCommand(0x00);// 水平寻址模式// 调整扫描方向SSD1306_WriteCommand(0xA1);// 段重映射SSD1306_WriteCommand(0xC8);// COM输出扫描方向

六、本讲核心要点

6.1 记住这三句话

  1. SPI屏幕驱动:正确配置SPI、理解控制命令、实现绘图功能

  2. 快速试错:AI生成初始驱动→测试验证→迭代修正

  3. 常见问题:SPI配置、初始化序列、引脚配置、复位时序

6.2 实践建议

对于新手

  • 学习SPI配置
  • 理解屏幕控制命令
  • 实践绘图功能

对于有经验工程师

  • 建立屏幕驱动模板库
  • 优化绘图性能
  • 实现高级功能

6.3 下讲预告

第32讲将深入讲解:实战:I2C传感器极简驱动快速验证

I2C传感器驱动如何快速验证?下一讲将以具体传感器为例详细讲解。

http://www.jsqmd.com/news/1249547/

相关文章:

  • 2026年7月大金空调售后服务电话人工客服400受理热线升级公示 - AAA家电服务指南
  • 【Rust自学】13.2. 闭包 Pt.2:闭包的类型推断和标注
  • 三星 Galaxy Z Fold 8 Ultra 开启预购,可视性、耐用性、性能全面升级!
  • 重构建材获客逻辑:建材企业携手西安信之上,解锁 GEO 推广增长新通路
  • 2026 年下半年!肉牛后期冲刺靠谱产品推荐,出栏增重正规品牌深度解析 - 优企甄选
  • 威联通NAS部署openwrt软路由保姆级教程附镜像文件
  • AI驱动的课程论文写作工具:书匠策AI全解析
  • 【Python毕业设计】基于 Python 的校园闲置资源互动流转交易系统设计与实现 带互动交流功能的校园二手交易平台设计(源码+文档+远程调试,全bao定制等)
  • 2026年7月美的空调售后服务电话人工客服400受理热线升级公告 - AAA家电服务指南
  • 抖店一件代发物流单号怎么回传?新手发货软件操作步骤分享 - 电商分享
  • 2026年7月最新无锡市滨湖区亨得利名表服务中心电话公示 - 亨得利官方博客
  • RNN训练中的梯度问题与梯度裁剪实战解析
  • 2026年如何系统的入门大模型?
  • 【Rust自学】13.1. 闭包 Pt.1:什么是闭包、如何使用闭包
  • 超详细:Dify大语言模型工作流开发平台的安装与使用,deepseek知识库客服等
  • 基于MATLAB图像处理与神经网络的肺癌智能分类系统
  • 全文 - APB3
  • 禹州龙悦府首选装修设计公司推荐 - 猜不透的vv
  • [AG-UI详解-05]如何构建一个兼容AG-UI协议的客户端
  • V2G微电网多目标优化调度与改进灰狼算法研究
  • 惠州发电机回收推荐:2026严选评本土老牌高口碑推荐 - 广东再生资源回收
  • 【Rust自学】2.3. 猜数游戏Pt.3 输入数与随机数的对比
  • 宝玑苏州网点地址及售后服务热线电话2026年7月权威通告 - 亨得利官方服务中心
  • INT4 通俗完整讲解
  • 杭州管道疏通哪家靠谱?2026西湖区业主真实测评避坑指南 - 余生黄金回收
  • 智能体、AIGC与AGI:核心技术差异与应用解析
  • 2026年7月最新宝玑扬州江都吾悦广场维修保养服务电话 - 亨得利钟表维修中心
  • MCU FLASH读写的简单分析
  • DSP/BIOS内存优化实战:模块化裁剪与配置策略详解
  • 专科生论文写作AI工具对比:千笔与Checkjie实测分析