码迷,mamicode.com
首页 > 其他好文 > 详细

框架-SPI四种模式+通用设备驱动实现

时间:2020-11-01 10:26:11      阅读:22      评论:0      收藏:0      [点我收藏+]

标签:clock   个人   containe   草稿   ade   osi   enter   选择   搜集   


前言

  • SPI 介绍为搜集百度资料+个人理解
  • 其余为原创(有误请指正)
  • 集四种模式于一身

笔录草稿

SPI介绍

  • SPI 协议简介

    • SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。
    • 是一个环形总线结构
      • 由 ss(cs)、sck、sdi、sdo 构成
      • 其时序主要是在 sck 的控制下,两个双向移位寄存器进行数据交换。
  • 物理线说明

    • SS
      • 从设备选择信号线,常称为片选信号线,也称为NSS、CS。
      • 用于选择从机。
    • SCK (Serial Clock)
      • 时钟信号线
      • 用于通讯数据同步。
    • MOSI (Master Output, Slave Input)
      • 主设备输出/从设备输入引脚。
      • 主机发出,从机接收。
    • MISO (Master Input,,Slave Output)
      • 主设备输入/从设备输出引脚。
      • 从机发出,主机接收。
  • SPI 四种模式

    • 请移步到下面章节学习
  • SPI的协议层

    • SPI协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。
    • 基本通讯过程
    • 图解
      1. 标号1:NSS信号线由高变低,是SPI通讯的起始信号。
      2. 标号6:NSS信号由低变高,是SPI通讯的停止信号。
  • 简单时序图技术图片

  • 模式时序图技术图片

SPI四种模式 **

  • 四种模式由 CPOLCPHA 组合区分
  • CPOL
    • 时钟极性
    • 是指SPI通讯设备处于空闲状态时,SCK信号线的电平信号
    • 0
      • SCK 空闲状态为 低电平
    • 1
      • SCK 空闲状态为 高电平
  • CPHA
    • 时钟相位
    • 是指数据的采样的时刻
    • 0
      • MOSI或MISO数据线上的信号将会在SCK时钟线的“奇数边沿”被采样。(即是第一个边沿)
      • 这种模式适合那种从设备一旦被片选后就输出数据到MISO线上。
    • 1
      • 数据线在SCK的“偶数边沿”采样。(即是第二个边沿)
      • 这种模式适合那种从设备被片选后还需要一个时钟才能 输出数据到MISO线上。
  • 四种模式(CPOL, CPHA
    • 模式 0:(0, 0
      • SCK空闲为 低电平,数据在SCK的 上升沿 被采样
    • 模式 1:(0, 1
      • SCK空闲为 低电平,数据在SCK的 下降沿 被采样
    • 模式 2:(1, 0
      • SCK空闲为 高电平,数据在SCK的 下降沿 被采样
    • 模式 3:(1, 1
      • SCK空闲为 高电平,数据在SCK的 上升沿 被采样

SPI 驱动框架 **

框架

  • 实现方法参考 I2C设备驱动拆解
  • 自己先在写出四种模式的读写时序,便会发现以下规律
  • 读写的逻辑差不多都一样,只是 SCK 信号线出现的位置及高低电平会因不同模式而不同。(这里我就不分别写出4种模式的单独实现了,直接上规律表,然后实现统一的源码
R/W CPOL CPHA 位置1-SCK 位置2-SCK 位置3-SCK 位置4-SCK
R 0 0 X 0 1 0
R 0 1 X 1 0 0
R 1 0 X 1 0 1
R 1 1 X 0 1 1
- - - - - - -
W 0 0 X 0 1 0
W 0 1 0 1 0 X
W 1 0 X 1 0 1
W 1 1 1 0 1 X

由上规律得出 支持四种模式的 SPI 读写源码

  • SPI 写函数
/**
  * @brief  SPI 写函数
  * @param 
  * @retval 
  * @author lzm
  */
void spiWriteOneByte(eSPI_ID id, unsigned char data)
{
	unsigned char i;
	const spi_t * spi = &spiDriverElem[id];
	
    // 位置1
	if(spi->CPHA){
		spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL);
	}
	
	for(i=0; i<8; i++)
	{
        // 位置2
		spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL != spi->CPHA));
		if(data & 0x80){
			spiMosiOutHi(spi);
		}
		else{
			spiMosiOutLo(spi);
		}
		data <<= 1;
		spi->delayUsFun(spi->readDelayUsCnt);
        // 位置3
		spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL == spi->CPHA));
	}
    // 位置4
	if(!(spi->CPHA)){
		spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL);
	}
}
  • SPI 读函数
/**
  * @brief  SPI 读函数
  * @param 
  * @retval 
  * @author lzm
  */
unsigned char spiReadOneByte(eSPI_ID id)
{
	unsigned char i;
	unsigned char ret;
	const spi_t * spi = &spiDriverElem[id];
	
    // 位置1
    
	for(i=0; i<8; i++)
	{
        // 位置2
		spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL != spi->CPHA));	
		ret <<= 1;
		if(spiMisoIn(spi))
			ret |= 0x01;
		else
			ret &= 0xfe;
		spi->delayUsFun(spi->readDelayUsCnt);
        // 位置3
		spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL == spi->CPHA));
	}
    // 位置4
	spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL);
	return ret;
}
  • SPI 读写函数
/**
  * @brief  SPI 读写一体函数
  * @param 
  * @retval 
  * @author lzm
  */
unsigned char spiRWOneByte(eSPI_ID id, unsigned char data)
{
	unsigned char i;
	unsigned char ret;
	const spi_t * spi = &spiDriverElem[id];
	
    // 位置1
	if(spi->CPHA){
		spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL);
	}
	
	for(i=0; i<8; i++)
	{
        // 位置2
		spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL != spi->CPHA));
		if(data & 0x80){
			spiMosiOutHi(spi);
		}
		else{
			spiMosiOutLo(spi);
		}
		data <<= 1;
		spi->delayUsFun(spi->readDelayUsCnt);
        // 位置3
		spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL == spi->CPHA));
		ret <<= 1;
		if(spiMisoIn(spi))
			ret |= 0x01;
		else
			ret &= 0xfe;
		spi->delayUsFun(spi->readDelayUsCnt);
	}
    // 位置4
	if(!(spi->CPHA)){
		spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL);
	}
}

框架-SPI四种模式+通用设备驱动实现

标签:clock   个人   containe   草稿   ade   osi   enter   选择   搜集   

原文地址:https://www.cnblogs.com/lizhuming/p/13907267.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!