一、SPI概述
SPI(Serial Peripheral Interface,串行外设接口)是一种同步串行通信接口,主要用于处理器与各种外设之间的数据通信。
常见应用:
LCD显示屏
Flash
触摸屏控制器
ADC/DAC
传感器
SD卡等
SPI最大的特点是:
由主设备产生时钟,通过时钟信号控制数据传输。
二、SPI通信接口
SPI通常使用4根信号线:
| 信号 | 全称 | 作用 |
|---|---|---|
| SCLK | Serial Clock | 串行时钟 |
| MOSI | Master Out Slave In | 主机发送,从机接收 |
| MISO | Master In Slave Out | 主机接收,从机发送 |
| CS/SS | Chip Select | 片选信号 |
例如:
i.MX6ULL 主设备 Master ┌──────────┐ SCLK ──┤ ├── SCLK MOSI ──┤ ├── MOSI MISO ──┤ SPI ├── MISO CS ──┤ ├── CS └──────────┘ │ │ ┌──────────┐ │ 从设备 │ │ Slave │ └──────────┘其中:
SCLK:主设备产生时钟
MOSI:主设备向从设备发送数据
MISO:从设备向主设备发送数据
CS:选择具体的从设备
三、SPI通信特点
SPI属于:
1. 同步通信
SPI具有专门的时钟线 SCLK。
主设备通过SCLK控制通信节奏。
SCLK: ─┐ ┌─┐ ┌─┐ ┌─┐ └─┘ └─┘ └─┘ └─ ↑ ↑ ↑ 数据 数据 数据因此SPI属于同步串行通信。
2. 全双工通信
SPI可以同时进行发送和接收。
Master ───── MOSI ─────→ Slave Master ←──── MISO ────── Slave因此SPI具有全双工通信的特点。
3. 主从结构
SPI通常采用:
Master │ ┌─────┼─────┐ │ │ │ CS0 CS1 CS2 │ │ │ Slave1 Slave2 Slave3一个主设备可以连接多个从设备。
通过不同的CS片选信号选择不同的从设备。
四、SPI数据传输过程
假设主设备需要向从设备发送一个字节:
1010 0101主设备产生SCLK。
每产生一个时钟周期,就传输一位数据。
SCLK: ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ 1 2 3 4 5 6 7 8 MOSI: 1 0 1 0 0 1 0 1经过8个时钟周期后:
10100101一个字节发送完成。
五、SPI的四种工作模式
SPI有4种工作模式:
| 模式 | CPOL | CPHA |
|---|---|---|
| Mode 0 | 0 | 0 |
| Mode 1 | 0 | 1 |
| Mode 2 | 1 | 0 |
| Mode 3 | 1 | 1 |
其中:
CPOL:Clock Polarity,时钟极性
CPHA:Clock Phase,时钟相位
1. CPOL
CPOL决定SCLK在空闲状态下的电平。
CPOL = 0
空闲状态:
SCLK = 0CPOL = 1
空闲状态:
SCLK = 12. CPHA
CPHA决定数据在哪一个时钟边沿采样。
可以简单理解为:
CPOL决定时钟默认是高还是低,CPHA决定在哪个边沿读取数据。
因此:
CPOL + CPHA ↓ 确定SPI具体通信模式使用某个SPI设备时,主设备和从设备必须采用匹配的SPI模式。
六、SPI与IIC的区别
SPI和IIC都是常见的串行通信方式。
| 对比 | SPI | IIC |
|---|---|---|
| 时钟 | 有 | 有 |
| 通信方式 | 同步 | 同步 |
| 双工方式 | 全双工 | 通常半双工 |
| 信号线 | 通常4根 | 2根 |
| 速度 | 通常较高 | 相对较低 |
| 地址方式 | CS片选 | 设备地址 |
| 多设备 | CS选择 | 地址选择 |
SPI:
SCLK MOSI MISO CSIIC:
SCL SDA七、GT9147简介
GT9147是一款常见的电容式触摸屏控制器。
它负责检测触摸屏上的触摸位置,并将触摸坐标等信息提供给处理器。
整体结构可以理解为:
手指 ↓ 触摸屏 ↓ GT9147 ↓ 通信接口 ↓ i.MX6ULL ↓ LCD显示GT9147本身主要负责:
检测触摸
获取触摸坐标
判断触摸状态
向主控制器提供触摸数据
八、电容式触摸基本原理
电容式触摸屏利用人体与触摸屏之间的电容变化检测触摸。
没有触摸时:
触摸屏 ↓ 电容状态基本稳定手指触摸后:
手指 ↓ 改变局部电场 ↓ 改变电容 ↓ GT9147检测变化 ↓ 计算触摸位置最终得到:
X坐标 Y坐标 触摸状态九、GT9147与LCD的关系
LCD负责:
显示
GT9147负责:
检测触摸
两者功能不同。
例如:
┌─────────────┐ │ i.MX6ULL │ └──────┬──────┘ │ ┌─────────┴─────────┐ ↓ ↓ LCD GT9147 ↓ ↓ 显示图像 检测触摸 ↓ X/Y坐标例如LCD分辨率为:
800 × 480那么触摸位置可能得到:
X = 350 Y = 200程序就可以根据这个坐标判断用户触摸了屏幕上的哪个区域。
十、GT9147通信
GT9147通常通过IIC接口与主控制器进行通信。
因此:
i.MX6ULL │ │ IIC │ ├── SCL └── SDA │ ↓ GT9147这里需要注意:
GT9147主要使用IIC与主控制器交换触摸数据,而不是SPI。
所以学习GT9147时,需要重点掌握:
IIC ↓ GT9147寄存器 ↓ 读取触摸状态 ↓ 读取X/Y坐标 ↓ LCD响应十一、GT9147触摸数据
GT9147检测到触摸后,主控制器需要读取相关寄存器。
一般过程:
① 查询触摸状态 ↓ ② 判断是否有触摸 ↓ ③ 获取触摸点数量 ↓ ④ 读取X坐标 ↓ ⑤ 读取Y坐标 ↓ ⑥ 根据坐标执行相应操作例如:
触摸点: X = 300 Y = 150程序可以判断:
if(x > 200 && x < 400 && y > 100 && y < 200) { /* 执行对应操作 */ }十二、X/Y坐标
假设LCD分辨率为:
800 × 480通常可以理解为:
X → 0 ─────────────────── 799 │ │ │ 触摸点 │ ● │ (X,Y) │ │ ↓ Y 0 │ │ 479因此:
X范围:0 ~ 799 Y范围:0 ~ 479实际使用时还需要根据具体屏幕的安装方向和驱动配置进行坐标方向处理。
十三、坐标高低字节
触摸坐标通常需要使用两个字节保存。
例如:
X_L:X坐标低8位 X_H:X坐标高8位组合成完整坐标:
x = X_L | (X_H << 8);Y坐标同理:
y = Y_L | (Y_H << 8);例如:
X_H = 0x01 X_L = 0x2C那么:
X = 0x012C转换成十进制:
X = 300十四、GT9147驱动基本结构
实际开发时,可以将GT9147驱动单独进行封装。
例如:
bsp/ ├── gt9147.c ├── gt9147.h ├── i2c.c ├── i2c.h ├── lcd.c └── lcd.h其中:
gt9147.h
保存:
GT9147寄存器定义
函数声明
数据结构
例如:
#ifndef __GT9147_H #define __GT9147_H void gt9147_init(void); unsigned char gt9147_scan(void); #endif十五、GT9147初始化
初始化的主要目的:
配置IIC ↓ 配置GT9147 ↓ 检测GT9147 ↓ 准备读取触摸数据程序结构可以设计成:
void gt9147_init(void) { /* IIC初始化 */ /* GT9147相关初始化 */ /* 检测GT9147 */ }十六、GT9147触摸扫描
可以设计一个触摸扫描函数:
unsigned char gt9147_scan(void) { unsigned char touch_num; /* 读取GT9147触摸状态 */ /* 获取触摸点数量 */ return touch_num; }主函数中:
while(1) { if(gt9147_scan()) { /* 获取触摸坐标 */ /* 根据坐标执行操作 */ } }整体流程:
开始 ↓ GT9147初始化 ↓ LCD初始化 ↓ 进入循环 ↓ 读取触摸状态 ↓ 是否检测到触摸? ↙ ↘ 否 是 │ ↓ │ 读取X/Y坐标 │ ↓ │ 判断触摸区域 │ ↓ │ 执行操作 │ │ └──────←──────┘十七、GT9147实现触摸按键
例如LCD上显示一个按钮:
┌────────────────────────┐ │ │ │ │ │ ┌────────┐ │ │ │ 按钮 │ │ │ └────────┘ │ │ │ └────────────────────────┘假设按钮区域:
X:200 ~ 400 Y:150 ~ 250读取触摸坐标:
if(x >= 200 && x <= 400 && y >= 150 && y <= 250) { /* 按钮被按下 */ }这样就可以实现:
触摸屏 ↓ 获取坐标 ↓ 判断坐标区域 ↓ 执行功能例如:
触摸“LED ON” ↓ i.MX6ULL检测到坐标 ↓ 判断属于LED ON按钮区域 ↓ 点亮LED十八、LCD + GT9147完整应用
LCD和GT9147组合起来,可以形成一个简单的触摸界面。
i.MX6ULL │ ┌─────────┴─────────┐ │ │ ↓ ↓ LCD GT9147 │ │ ↓ ↓ 显示界面 读取触摸 │ ↓ X/Y坐标 │ ↓ 判断按钮区域 │ ↓ 执行对应功能例如:
LCD显示: ┌───────────────────────┐ │ LED控制 │ │ │ │ ┌──────────┐ │ │ │ LED ON │ │ │ └──────────┘ │ │ │ │ ┌──────────┐ │ │ │ LED OFF │ │ │ └──────────┘ │ └───────────────────────┘用户点击:
LED ON ↓ GT9147检测 ↓ 获得X/Y ↓ 判断区域 ↓ LED打开Mode 0:CPOL=0,CPHA=0 Mode 1:CPOL=0,CPHA=1 Mode 2:CPOL=1,CPHA=0 Mode 3:CPOL=1,CPHA=1