s5p6818裸机-spi

前言

写文章的目的是想通过记录自己的学习过程,以便以后使用到相关的知识点可以回顾和参考。

SPI简介

SPI 全称是 Serial Perripheral Interface,也就是串行外围设备接口。SPI 是 Motorola 公司推出的一种同步串行接口技术,是一种高速、全双工的同步通信总线,SPI 时钟频率相比 I2C 要高很多,最高可以工作在上百 MHz。SPI 以主从方式工作,通常是有一个主设备和一个或多个从设备,一般 SPI 需要4 根线,但是也可以使用三根线(单向传输),这四根线如下:
①、CS/SS,Slave Select/Chip Select,这个是片选信号线,用于选择需要进行通信的从设备。
I2C 主机是通过发送从机设备地址来选择需要进行通信的从机设备的,SPI 主机不需要发送从机
设备,直接将相应的从机设备片选信号拉低即可。
②、SCK,Serial Clock,串行时钟,和 I2C 的 SCL 一样,为 SPI 通信提供时钟。
③、MOSI/SDO,Master Out Slave In/Serial Data Output,简称主出从入信号线,这根数据线
只能用于主机向从机发送数据,也就是主机输出,从机输入。
④、MISO/SDI,Master In Slave Out/Serial Data Input,简称主入从出信号线,这根数据线只
能用户从机向主机发送数据,也就是主机输入,从机输出。
SPI 通信都是由主机发起的,主机需要提供通信的时钟信号。主机通过 SPI 线连接多个从
设备的结构如图所示:
在这里插入图片描述
SPI 有四种工作模式,通过串行时钟极性(CPOL)和相位(CPHA)的搭配来得到四种工作模式:
①、CPOL=0,串行时钟空闲状态为低电平。
②、CPOL=1,串行时钟空闲状态为高电平,此时可以通过配置时钟相位(CPHA)来选择具
体的传输协议。
③、CPHA=0,串行时钟的第一个跳变沿(上升沿或下降沿)采集数据。
④、CPHA=1,串行时钟的第二个跳变沿(上升沿或下降沿)采集数据。

实现流程

1、设置spi时钟,初始化spi
2、编写发送接收函数

具体实现

1、设置spi时钟,初始化spi

void spiclk_init(SPIClk_Type* Base)
{
    Base->SSPCLKENB &= ~(1<<2); /* 关闭时钟 */
    Base->SSPCLKEN0L &= ~(7<<2);    /* 选择PLL1作为时钟源,800MHz */
    Base->SSPCLKEN0L |= (1<<2);
    Base->SSPCLKEN0L &= ~(0xFF<<5);
    Base->SSPCLKEN0L |= (39<<5);    /* 80分频,800 / 40 = 20MHz ,内部经过2分频到spi_clk,即10MHz */ 
    Base->SSPCLKENB |= (1<<2); /* 打开时钟 */  
}

void spi_init(SPI_Type* Base)
{
    spiclk_init(SPI0_Clk);      /* 初始化时钟 */
    Base->CONFIGURE |= (1<<5);  /* 软复位 */
    Base->CONFIGURE &= ~(3<<0); /* 关闭SPI */
    Base->CONFIGURE &= ~(1<<2); /* 第一个时钟沿采集数据 */
    Base->CONFIGURE &= ~(1<<3); /* 空闲时为低电平 */
    Base->CONFIGURE &= ~(1<<4); /* 主机模式 */

    Base->FIFOCON = 0;  /* 清寄存器 */
    Base->FIFOCON &= ~(3<<29);  /* 1字节的数据宽 */

    //Base->SELSIGNALCON &= ~(1<<1); /* 手动控制片选信号 */
    Base->CONFIGURE |= (3<<0); /* 启动SPI */
}

2、编写发送接收函数

void spi_send(SPI_Type* Base, unsigned char data)
{
    //unsigned char temp; 
    while((Base->STATUS & (1<<0)) == 0);
    Base->TXDATA = data;

    while((Base->STATUS & (1<<1)) == 0);
    //temp = Base->RXDATA;
}


unsigned char spi_recv(SPI_Type* Base)
{
    unsigned char data;
    while((Base->STATUS & (1<<0)) == 0);
    Base->TXDATA = 0x00;

    while((Base->STATUS & (1<<1)) == 0);
    data = Base->RXDATA;

    return data;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值