在SPI接口中,判断传输的数据位上电平的高低是通过时钟来衡量的,根据时钟的上升沿/下降沿和数据电平的保持/更改,可以组合出4种方式,具体如下图所示。

从上图中可以看出,时钟相位CPHA决定传输的数据电平什么时候被采样、什么时候可以更改,时钟极性CPOL决定时钟是低电平空闲还是高电平空闲。 在上图中,当CPHA=0时,当时钟从空闲状态发生跳变时(CPOL=0为上跳,CPOL=1为下跳),采样数据位的电平,当时钟跳变成空闲状态时(CPOL=0为下跳,CPOL=1为上跳),允许数据位上的电平更改。当CPHA=1时,当时钟从空闲状态发生跳变时(CPOL=0为上跳,CPOL=1为下跳),允许数据位上的电平更改,当时钟跳变成空闲状态时(CPOL=0为下跳,CPOL=1为上跳),采样数据位的电平。具体的4种模式见下表。

至于SPI要采用哪种模式,要看实际的SPI器件,一般来说,采用模式3的较为常见。

接下来看一个使用SPI接口的实际例子。通过LPC824驱动一块SPI接口的液晶屏进行图像显示,这里选用诺基亚的5110液晶屏,要求在屏幕上显示一个五角星的图形。
5110液晶屏具有4032个像数,可以同时显示15个汉字或84个ASCII码字符,具备简易的SPI接口,超低功耗、速度超快,因此很受欢迎。在实际连线时,由于在默认状态下LPC824的SPI0接口引脚并未引出到物理引脚上,所以在实际配置时可依据具体情况来灵活选择物理引脚。另外,5110液晶屏的SPI接口并没有MISO端,在连线时可不接此端口。在本例中,规定的连线方式定义如下:
SCK<——>SCK0(PIO0_20)
DIN<——>MOSI0(PIO0_21)
SCE<——>SSEL0(PIO0_14)
D\C<——>PIO0_6
RST<——>PIO0_22
最后还要给液晶屏接上电源,该液晶屏的工作电压为3.3V。

参考程序代码如下:

#include <LPC82x.h>
#define SPI_CFG_ENABLE (0x1)
#define SPI_CFG_MASTER (0x4)
#define SPI_STAT_RXRDY (0x1)
#define SPI_STAT_TXRDY (0x2)
#define SPI_STAT_SSD (0x20)
#define SPI_STAT_MSTIDLE (0x100)
#define SPI_TXDATCTL_SSEL_N(s) ((s) << 16)
#define SPI_TXDATCTL_EOT (1 << 20)
#define SPI_TXDATCTL_EOF (1 << 21)
#define SPI_TXDATCTL_RXIGNORE (1 << 22)
#define SPI_TXDATCTL_FLEN(l) ((l) << 24) uint8_t const bmp[]={0xE0,0xF0,0xF0,0xF0,0xF0,0xFC,0xFE,0xFF,0xFF,0xFF,0xFC,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x01,0x7B,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x7F,0x7F,0xFF,0xFF,0x7F,0x01,0x00}; void Port_init(void)
{
LPC_GPIO_PORT->DIR0 |= 0x400040; //设置端口为输出方向
} void Spi0_init(void)
{
LPC_SYSCON->SYSAHBCLKCTRL|=1<<7; //开启SWM时钟
LPC_SWM->PINASSIGN3 &= ~0xFFFFFFFF;
LPC_SWM->PINASSIGN3 |= 0x14<<24;
LPC_SWM->PINASSIGN4 &= ~0xFFFFFFFF;
LPC_SWM->PINASSIGN4 |= 0x15 | (0x0e<<16);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<7); //关闭SWM时钟(使用完之后记得关闭,节省功耗)
LPC_SYSCON->SYSAHBCLKCTRL |= 1<<11; //开启SPI0时钟
LPC_SYSCON->PRESETCTRL &= ~(1<<0); //开启复位SPI0
LPC_SYSCON->PRESETCTRL |= (1<<0); //关闭复位SPI0
LPC_SPI0->DIV = 6;
LPC_SPI0->CFG = SPI_CFG_MASTER | SPI_CFG_ENABLE;
} void SPI_MasterTransmit(uint8_t Data)
{
while(~LPC_SPI0->STAT & SPI_STAT_TXRDY);
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FLEN(7) | SPI_TXDATCTL_RXIGNORE | SPI_TXDATCTL_EOT | SPI_TXDATCTL_SSEL_N(0xe) | Data;
while(~LPC_SPI0->STAT & SPI_STAT_MSTIDLE);
} void LCD_write_byte(uint8_t dat,uint8_t command)
{
if(command==0)
LPC_GPIO_PORT->PIN0 &= ~(1<<6);
else
LPC_GPIO_PORT->PIN0 |= (1<<6);
SPI_MasterTransmit(dat); //发送数据
} void LCD_set_XY(uint8_t X,uint8_t Y)
{
LCD_write_byte(0x40|Y,0); //写纵坐标地址(参看基本命令,须写第6位为1,所以要或上0x40)
LCD_write_byte(0x80|X,0); //写横坐标地址(参看基本命令,须写第7位为1,所以要或上0x80)
} void LCD_draw_bmp_pixel(uint8_t X,uint8_t Y,uint8_t const *map,uint8_t Pix_x,uint8_t Pix_y)
{
uint16_t i,n;
uint8_t row;
if(Pix_y%8 == 0)
row = Pix_y/8; //若纵向上的像数坐标小于8,则行的值取1
else
row = Pix_y/8+1; //若纵向上的像数坐标大于8,则行的值取8的倍数加1
LCD_set_XY(X,Y);
for(n=0;n<row;n++) //纵向上的地址增加
{
for(i=0;i<Pix_x;i++) //在横向上依次增加显示区域
{
LCD_set_XY(X+i,Y+n); //设定显示区域的坐标
LCD_write_byte(map[i+n*Pix_x],1); //从图像数组中依次取值进行显示
}
}
} void LCD_clear(void)
{
uint8_t t,k;
LCD_set_XY(0,0); //从最左上角开始
for(t=0;t<=6;t++)
{
for(k=0;k<84;k++) //一直到最右下角结束
LCD_write_byte(0,1); //写显示数据0,以清屏
}
} void delay_us(uint32_t us)
{
SysTick->LOAD = (((12)*us)-1); //载入初始值
SysTick->VAL = 0; //写当前值寄存器使其清零
SysTick->CTRL |= (1<<0); //启动定时器,选择半系统时钟
while(!(SysTick->CTRL & 0x10000)); //循环查询,等待定时时间到
SysTick->CTRL &= ~(1<<0); //关闭定时器
} void delay_ms(uint32_t ms)
{
SysTick->LOAD = (((12000)*ms)-1); //载入初始值
SysTick->VAL = 0; //写当前值寄存器使其清零
SysTick->CTRL |= (1<<0); //启动定时器,选择半系统时钟
while(!(SysTick->CTRL & 0x10000)); //循环查询,等待定时时间到
SysTick->CTRL &= ~(1<<0); //关闭定时器
} void LCD_init(void)
{
LPC_GPIO_PORT->PIN0 &= ~(1<<22);
delay_us(5); //复位宽度
LPC_GPIO_PORT->PIN0 |= (1<<22);
LCD_write_byte(0x21,0); //上电模式、水平寻址、扩展指令集
LCD_write_byte(0xbe,0); //设置偏置电压
LCD_write_byte(0x06,0); //设置温度系数
LCD_write_byte(0x13,0); //设置1:48混合比例
LCD_write_byte(0x20,0); //恢复到基本指令集方式
LCD_clear(); //清屏
LCD_write_byte(0x0c,0); //正常显示模式
} int main(void)
{
Port_init(); //端口初始化
Spi0_init(); //SPI初始化
LCD_init(); //LCD初始化
delay_ms(15); //延时
LCD_draw_bmp_pixel(0,0,bmp,16,16); //在左上角显示一颗五角星
while(1)
;
}

把上述程序编译后下载到LPC824中,5110液晶屏按上面的要求接好连线,给系统上电,可在显示屏上看到如下的图案,说明SPI接口工作正常。

SPI接口(续三)的更多相关文章

  1. SPI、I2C、UART三种串行总线协议的区别和SPI接口介绍(转)

    SPI.I2C.UART三种串行总线协议的区别 第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART( ...

  2. flash读写学习笔记与spi接口及简单测试验证(三)

    FPGA中的视频图像资源,以及想要永久存储的程序都是要存储在flash中,flash是FPGA一个不可缺少的部分,flash的种类有很多,根据winbond公司的128Mbit Qual SPI接口的 ...

  3. CC3000 SPI接口编程介绍

    CC3000 SPI 操作: CC3000的SPI 是基于五根线CLCK,CSn,IRQ,MISO,MOSI:通信模式如下图: CLCK:时钟频率0-26M从主机到从机,提供SPI接口时钟 CSn:低 ...

  4. 自定义AXI总线形式SPI接口IP核,点亮OLED

    一.前言 最近花费很多精力在算法仿真和实现上,外设接口的调试略有生疏.本文以FPGA控制OLED中的SPI接口为例,重新夯实下基础.重点内容为SPI时序的RTL设计以及AXI-Lite总线分析.当然做 ...

  5. SPI接口扫盲 SPI定义/SPI时序(CPHA CPOL)

    SPI接口扫盲   douqingl@gmail.com   为何要写这篇文档?百度上找出来的SPI接口中文描述都说的太过简略,没有一篇文档能够详尽的将SPI介绍清楚的.wikipedia英文版[注释 ...

  6. linux驱动基础系列--Linux下Spi接口Wifi驱动分析

    前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...

  7. STC8A8K64S4A12通过SPI接口操作基于ST7920的LCD12864液晶模块

    文章地址:https://www.cnblogs.com/jqdy/p/12665430.html 1. 硬件连接 1.1 64引脚的STC8A8K64S4A12 使用的是最小核心板,所以引脚皆引出可 ...

  8. SPI接口在LCD上的应用

    ​小分辨率的LCD,比如QQVGA,QCIF,QVGA等,广泛应用于功能手机和穿戴设备(比如手表)上.这类小分辨率的LCD,除了支持并行接口(比如i80),一般也会支持串行接口.在实际产品中广泛运用的 ...

  9. 嵌入式物联网之SPI接口原理与配置

    本实验采用W25Q64芯片 W25Q64是华邦公司推出的大容量SPI FLASH产品,其容量为64Mb.该25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件.W25Q64将8M字节的容量分为 ...

  10. STC8H开发(六): SPI驱动ADXL345三轴加速度检测模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

随机推荐

  1. 手算推导BP神经网络

    一.神经元 下图的蓝色区域被称为一个"感知机"(Perceptron), 感知机是对信息进行编码.压缩.集成.融合的计算机智能接口系统. 说白了,就是在输入端输入X1~X7这7个输 ...

  2. Mybatis学习笔记【狂神说】

    环境 Jdk 1.8 Mysql 5.7 Maven 3.6.1 IDEA 回顾 JDBC Mysql java基础 Maven Junit SSM框架:都是有配置文件的.最好的学习方式:看官方文档. ...

  3. Educational Codeforces Round 112 E、Boring Segments

    原题网址 https://codeforces.com/contest/1555/problem/E 题目大意 有n个区间.每个区间是[1,m]的子区间.从a可以一步走到b的充要条件是存在区间同时覆盖 ...

  4. 2022-05-13内部群每日三题-清辉PMP

    1.一个运营团队认为他们的技能在项目上是不必要的,团队士气低落,且团队成员试图阻止项目实现目标.项目经理应该怎么做? A.建议公司改变战略,并立即停止项目 B.要求工会的支持来激励团队 C.根据项目成 ...

  5. 性能测试工具locust压测介绍

    官方文档:https://docs.locust.io/en/stable/index.html 1.初识locust Locust 完全基本 Python 编程语言,采用python 编写压测脚本, ...

  6. 【Shell】DBeaver Enterprise Edition 5.1.1 Download

    DBeaver Enterprise Edition 5.1.1 Download mkdir -p /opt/downloads/dbeaver/dbeaver-ee-5.1.1 mkdir -p ...

  7. web开发(2): html标签/web语义化

    chapter2 html 标签 在sublime中敲入!, 按tab 进行拓展,得到如下框架 <!DOCTYPE html> <html lang="en"&g ...

  8. Linux网络第五章:yum仓库的灵活部署及NFS共享服务

    目录 一.yum仓库的灵活部署 1.yum基础知识及命令 2.本地yum仓库搭建 3.通过httpd服务建立yum仓库 4.建立国内yum源 二.NFS共享服务 1.NFS基础知识 2.搭建NFS服务 ...

  9. JustAuth-第三方登录组件

    1.新增依赖 <dependency> <groupId>me.zhyd.oauth</groupId> <artifactId>JustAuth< ...

  10. sql常用系统存储过程

    -- 更详细的介结参考联机帮助文档 xp_cmdshell --*执行DOS各种命令,结果以文本行返回. xp_fixeddrives --*查询各磁盘/分区可用空间 xp_loginconfig - ...