欢迎光临散文网 会员登陆 & 注册

江科大学习笔记 _15.硬件SPI

2023-06-30 09:03 作者:自闭选手的Z23  | 我要投稿

 


W25Q64:地址宽度24位,3字节 8M->块->扇区->页

  8 * 1024 *1024 范围:00 00 00H--7F FF FFH (8MB)

 

8M分为128个块,每个块(64K) 块0-块127,

(8*1024 *1024 /64*1024) = 128 范围:xx 00 00 H--xx FF FFH(64KB)

 

64K分为16个扇区,每个扇区(4k),扇区0--扇区15

(64*1024/4*1024) = 16 范围:xx x0 00h -- xx xF FFh (4KB)

 

4K分为16个页,每个页(256字节),页0--页15

(4*1024/256) = 16 范围:xx xx 00h -- xx xx FFh (256)

 

 

 

 

 

 


STM32单片机为主机,W25Q64为从机

CS:片选

DO:从机输出

CLK:时钟

DI:从机输入

 

 

 

 


SPI和IIC都是高位先行

串口是低位先行

 

每次交换8或16位数据

SPI时钟 = fPCLK/分频系数(2,4,8,16,32,64,128,256),

SPI1和SPI2挂载总线不同SPI1->APB2(72M),SPI2>APB1(36M)

 


 


TDR/RDR/TXE/RXNE

TXE:TDR数据全部移入移位寄存器,置1

RXNE:移位寄存器数据全部移入RDR,置1

 


CPOL = 1;CPHA = 1,SPI模式3 SCK默认高电平

 

检测到TXE = 1,TDR为空  ->  软件写入0XF1至SPI_DR -> TDR的值变为F1,TXE变为0

RXNE置1后,读出接收到的第一个数据, 再写入下一个字节数据

交换字节时序

1. 等待TXE为1

2. 写入发送的数据至TDR

3. 等待RXNE为1

4. 读取RDR接收的数据,重复这4步

 

 

 

硬件SPI配置步骤

1. 开始时钟SPI、GPIO

2. 初始化GPIO口,SCK/MOSI推挽输出,MISO为上拉输入,SS通用推挽输出

3. 配置SPI外设

4. SPI_Cmd

 

void MySPI_Init(void)

{

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);

 

    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStruct.GPIO_Pin = SS;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(SPI_Port, &GPIO_InitStruct);

 

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStruct.GPIO_Pin = SCK|MOSI;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(SPI_Port, &GPIO_InitStruct);

 

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;

    GPIO_InitStruct.GPIO_Pin = MISO;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(SPI_Port, &GPIO_InitStruct);

 

    SPI_InitTypeDef SPI_InitStruct;

    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//主机or从机

    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//交换数据8位or16位

    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; //高位开始or低位开始  

    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工    

    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//预分频

    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;//第一个边沿采样or第二个边沿采样

    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;//默认时钟极性低or高

    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;    

    SPI_InitStruct.SPI_CRCPolynomial = 7;

    SPI_Init(SPI1,&SPI_InitStruct);

    SPI_Cmd(SPI1, ENABLE);

    MySPI_W_SS(1);//默认不选中从机

}

 

 

交换字节时序

1.等待TXE为1

2.写入发送的数据至TDR

3.等待RXNE为1

4.读取RDR接收的数据,重复这4步

 

uint8_t MySPI_SwapByte(uint8_t ByteSend)

{

    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);

    //等待TXE为1

    SPI_I2S_SendData(SPI1, ByteSend);

    //写发送的数据至TDR

 

    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET);

    //等待RXNE为1(发送完成即接收完成)

    return SPI_I2S_ReceiveData(SPI1);

    //读取RDR接收数据

}

 

需要考虑标志位是否会自动清除,如果不自动清除,则要手动清除

 


江科大学习笔记 _15.硬件SPI的评论 (共 条)

分享到微博请遵守国家法律