博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SPI
阅读量:6967 次
发布时间:2019-06-27

本文共 4779 字,大约阅读时间需要 15 分钟。

一原理和初始化过程:

SPI(Serial Peripheral Interface),串行外围设备接口。SPI是一种高速的、全双工、同步的通信总线。

SPI接口一般使用4条线通信:

  MISO 主设备数据输入,从设备数据输出

  MOSI 主设备数据输出,从设备数据输入

  SCLK 时钟信号,有主设备产生

  CS 从设备片选信号,有主设备控制

  SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置。SPI_CR寄存器的CPOL(时钟极性)位,控制在没有数据传输时时钟的空闲状态电平,此位对主模式和从模式下的设备都有效。CPOL=0,串行同步时钟的空闲状态为低电平;CPOL=1,串行同步时钟的空闲状态为高电平。SPI_CR寄存器的CPHA(时钟相位)位,能配置用于选择两种不同的传输协议之一进行数据传输。CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。

 

1.SPI主模式配置步骤

①使能SPI时钟,配置PA口

  APB2外设时钟使能寄存器(RCC_APB2ENR)

  APB1外设复位寄存器 (RCC_APB1RSTR)

  Eg:RCC->APB2ENR|=1<<2; //PORTA时钟使能 

     RCC->APB2ENR|=1<<12; //SPI1时钟使能 

     //这里只针对SPI口初始化
       GPIOA->CRL&=0X000FFFFF; 
     GPIOA->CRL|=0XBBB00000;//PA5.6.7复用 
     GPIOA->ODR|=0X7<<5; //PA5.6.7上拉

 

②开全双工模式并软件管理NSS

  SPI控制寄存器1(SPI_CR1)(I2S模式下不使用)

 

  Eg:SPI1->CR1|=0<<10;//全双工模式 

     SPI1->CR1|=1<<9; //软件nss管理
     SPI1->CR1|=1<<8;

 

 

③设置SPI为主机并设置数据帧格式

  Eg:SPI1->CR1|=1<<2; //SPI主机

     SPI1->CR1|=0<<11;//8bit数据格式

 

 

④设置时钟极性和相位极性

 

   Eg:SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1

      SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1

 

⑤传输速率和LSBFIRST帧格式设置

  Eg:SPI1->CR1|=7<<3; //Fsck=Fcpu/256

     SPI1->CR1|=0<<7; //MSBfirst

 

 

⑥使能SPI

 

  Eg:SPI1->CR1|=1<<6; //SPI设备使能

 

二:初始化 库函数操作

void SPI2_Init(void)

{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTBʱÖÓʹÄÜ

RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2ʱÖÓʹÄÜ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15¸´ÓÃÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯GPIOB

GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); 

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  

SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; 
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; 
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; 
SPI_InitStructure.SPI_CRCPolynomial = 7; 
SPI_Init(SPI2, &SPI_InitStructure); 
SPI_Cmd(SPI2, ENABLE);
SPI2_ReadWriteByte(0xff);

}

寄存器操作。。。

 

void SPI1_Init(void) 4 {      5     RCC->APB2ENR|=1<<2;       //PORTA时钟使能       6     RCC->APB2ENR|=1<<12;      //SPI1时钟使能  7             8     //这里只针对SPI口初始化 9     GPIOA->CRL&=0X000FFFFF; 10     GPIOA->CRL|=0XBBB00000;//PA5.6.7复用         11     GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉12         13     SPI1->CR1|=0<<10;//全双工模式    14     SPI1->CR1|=1<<9; //软件nss管理15     SPI1->CR1|=1<<8;  16 17     SPI1->CR1|=1<<2; //SPI主机18     SPI1->CR1|=0<<11;//8bit数据格式    19     SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=120     SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1  21     SPI1->CR1|=7<<3; //Fsck=Fcpu/25622     SPI1->CR1|=0<<7; //MSBfirst   23     SPI1->CR1|=1<<6; //SPI设备使能24     SPI1_ReadWriteByte(0xff);//启动传输(主要作用:维持MOSI为高)         25 }   26 //SPI1 速度设置函数27 //SpeedSet:0~728 //SPI速度=fAPB2/2^(SpeedSet+1)29 //APB2时钟一般为72Mhz30 void SPI1_SetSpeed(u8 SpeedSet)31 {32     SpeedSet&=0X07;            //限制范围33     SPI1->CR1&=0XFFC7; 34     SPI1->CR1|=SpeedSet<<3;    //设置SPI1速度  35     SPI1->CR1|=1<<6;         //SPI设备使能 36 } 37 //SPI1 读写一个字节38 //TxData:要写入的字节39 //返回值:读取到的字节40 u8 SPI1_ReadWriteByte(u8 TxData)41 {        42     u16 retry=0;                 43     while((SPI1->SR&1<<1)==0)//等待发送区空    44     {45         retry++;46         if(retry>0XFFFE)return 0;47     }              48     SPI1->DR=TxData;           //发送一个byte 49     retry=0;50     while((SPI1->SR&1<<0)==0) //等待接收完一个byte  51     {52         retry++;53         if(retry>0XFFFE)return 0;54     }                                  55     return SPI1->DR;                        56 } 四 main函数

#include "led.h"

#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "flash.h"

const u8 TEXT_Buffer[]={0x21,0x23};

#define SIZE sizeof(TEXT_Buffer)
int main(void)
{
u8 key;
u16 i=0;
u8 datatemp[SIZE];
u32 FLASH_SIZE;
delay_init();
NVIC_Configuration();
uart_init(9600);
LED_Init();
KEY_Init();
SPI_Flash_Init();
while(SPI_Flash_ReadID()!=W25Q64)
{
LED0=!LED0;
}
FLASH_SIZE=8*1024*1024;
while(1)
{
datatemp[0] = 0;
datatemp[1] = 0;
key=KEY_Scan(0);
if(key==KEY_UP)
{
SPI_Flash_Write((u8*)TEXT_Buffer,FLASH_SIZE-100,SIZE);
printf("spi write data is=\r\n");
printf("data0: %x data1: %x\n",datatemp[0],datatemp[1]);

}
if(key==KEY_DOWN)
{
SPI_Flash_Read(datatemp,FLASH_SIZE-100,SIZE);
printf("spi reding data is=\r\n");
printf("data0: %x data1: %x\n",datatemp[0],datatemp[1]);

}
i++;
delay_ms(100);
if(i==20)
{
LED1=!LED1;//system runing
i=0;
}
}
}

五 实验结果

六 扩展  还需要发送不同的数据类型。

转载于:https://www.cnblogs.com/huangbaobaoi/p/6058325.html

你可能感兴趣的文章
微信还没开始付费订阅 但帮你变现的工具已经有了
查看>>
福州启动国家健康医疗大数据中心与产业园建设
查看>>
记录下IE7下的input标签bug
查看>>
把整体性思维运用到智慧城市建设中
查看>>
土豪逆袭:中国移动反超联通成为第二大宽带运营商
查看>>
包头市城市管理有了“智慧大脑”
查看>>
澳大利亚计划兴建首个海上风电场
查看>>
诺基亚创新科技总裁姆齐离职 在职时负责专利授权工作
查看>>
瑞典安讯士数字化安防挖掘实时商业智能
查看>>
你所了解的物联网都是错的吗?
查看>>
硅谷亿万富翁彼得·泰尔的神秘大数据公司在新西兰遭审查
查看>>
AT&T转型云端软件公司 员工:必须改变自己
查看>>
实现LoadRunner多个场景的顺序执行
查看>>
B/S架构测试环境搭建_Teradata篇(Win32系统)
查看>>
参加工业软件与制造业融合发展高峰论坛 用友3.0加速落地
查看>>
赌Impinj就是赌RFID行业
查看>>
亚马逊数据专家十年经验总结:成为数据科学家的关键四步
查看>>
普京签订反恐法:互联网公司将增加数十亿美元成本
查看>>
为什么很难保持云计算安全
查看>>
董明珠下台 格力还能一统智能家居吗?
查看>>