赞
踩
四根通信线:SCK(Serial Clock)(时钟线)、MOSI(Master Output Slave Input)、MISO(Master Input Slave Output)、SS(Slave Select)
同步、全双工
支持总线挂载多设备(一主多从)
所有SPI设备的SCK、MOSI、MISO分别连在一起
主机另外引出多条SS控制线(低电平有效),分别接到各从机的SS引脚
输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
起始条件:SS从高电平切换到低电平
终止条件:SS从低电平切换到高电平
交换一个字节(模式0)
CPOL = 0:空闲状态,SCK为低电平
CPHA = 0:SCK第一个边沿移入数据,第二个边沿移出数据
交换一个字节(模式1)
CPOL = 0:空闲状态,SCK为低电平
CPHA = 1:SCK第一个边沿移出数据,第二个边沿移入数据
交换一个字节(模式2)
CPOL = 1:空闲状态,SCK为高电平
CPHA = 0:SCK第一个边沿移入数据,第二个边沿移出数据
交换一个字节(模式3)
CPOL = 1:空闲状态,SCK为高电平
CPHA = 1:SCK第一个边沿移出数据,第二个边沿移入数据
STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担
可配置8位/16位数据帧、高位先行/低位先行
时钟频率: / (2,4,8,16,32,64,128,256)
支持多主机模型、主或从模式
可精简为半双工/单工通信
支持DMA
兼容I2S协议
- //恢复缺省配置
- void SPI_I2S_DeInit(SPI_TypeDef* SPIx);
-
- //初始化
- void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
-
- //给结构体变量默认值
- void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);
-
- //SPI使能
- void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
-
- //中断使能
- void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
-
- //DMA使能
- void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);

- //写DR数据寄存器
- void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
-
- //读DR数据寄存器
- uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
- //获取标志位
- FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
-
- //清除标志位
- void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
-
- //获取中断标志位
- ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
-
- //清除中断标志位
- void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
- #include "stm32f10x.h" // Device header
-
- void MySPI_W_SS(uint8_t BitValue)
- {
- GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
- }
-
- void MySPI_W_SCK(uint8_t BitValue)
- {
- GPIO_WriteBit(GPIOA,GPIO_Pin_5,(BitAction)BitValue);
- }
-
- void MySPI_W_MOSI(uint8_t BitValue)
- {
- GPIO_WriteBit(GPIOA,GPIO_Pin_7,(BitAction)BitValue);
- }
-
- uint8_t MySPI_R_MISO(void)
- {
- return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6);
- }
-
- void MySPI_Init(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
-
- MySPI_W_SS(1);
- MySPI_W_SCK(0);
- }
-
- void MySPI_Start(void)
- {
- MySPI_W_SS(0);
- }
-
- void MySPI_Stop(void)
- {
- MySPI_W_SS(1);
- }
-
- uint8_t MySPI_SwapByte(uint8_t ByteSend)
- {
- uint8_t ByteReceive = 0x00;
-
- for(uint8_t i = 0;i < 8;i++)
- {
- MySPI_W_MOSI(ByteSend & (0x80 >> i));
- MySPI_W_SCK(1);
- if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}
- MySPI_W_SCK(0);
- }
-
- return ByteReceive;
- }
-
- //uint8_t MySPI_SwapByte(uint8_t ByteSend)
- //{
- // uint8_t ByteReceive = 0x00;
- //
- // for(uint8_t i = 0;i < 8;i++)
- // {
- // MySPI_W_MOSI(ByteSend & (0x80 >> i));
- // ByteSend <<= 1;
- // MySPI_W_SCK(1);
- // if (MySPI_R_MISO() == 1){ByteReceive |= 0x01;}
- // MySPI_W_SCK(0);
- // }
-
- // return ByteReceive;
- //}
-

- #include "stm32f10x.h" // Device header
- #include "MySPI.h"
- #include "W25Q64_Ins.h"
-
-
- void W25Q64_Init(void)
- {
- MySPI_Init();
- }
-
- void W25Q64_ReadID(uint8_t *MID,uint16_t *DID)
- {
- MySPI_Start();
- MySPI_SwapByte(W25Q64_JEDEC_ID);
- *MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
- *DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
- *DID <<= 8;
- *DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);
- MySPI_Stop();
- }
-
- void W25Q64_WriteEnable(void)
- {
- MySPI_Start();
- MySPI_SwapByte(W25Q64_WRITE_ENABLE);
- MySPI_Stop();
- }
-
- void W25Q64_WaitBusy(void)
- {
- uint32_t Timeout = 100000;
-
- MySPI_Start();
- MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);
- while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)
- {
- Timeout --;
- if(Timeout == 0)
- {
- break;
- }
- }
- MySPI_Stop();
- }
-
- void W25Q64_PageProgram(uint32_t Address,uint8_t *DataArray,uint16_t Cout)
- {
- W25Q64_WriteEnable();
-
- MySPI_Start();
- MySPI_SwapByte(W25Q64_PAGE_PROGRAM);
- MySPI_SwapByte(Address >> 16);
- MySPI_SwapByte(Address >> 8);
- MySPI_SwapByte(Address);
- for (uint16_t i = 0;i < Cout;i++)
- {
- MySPI_SwapByte(DataArray[i]);
- }
- MySPI_Stop();
-
- W25Q64_WaitBusy();
- }
-
- void W25Q64_SectorErase(uint32_t Address)
- {
- W25Q64_WriteEnable();
-
- MySPI_Start();
- MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);
- MySPI_SwapByte(Address >> 16);
- MySPI_SwapByte(Address >> 8);
- MySPI_SwapByte(Address);
- MySPI_Stop();
-
- W25Q64_WaitBusy();
- }
-
- void W25Q64_ReadData(uint32_t Address,uint8_t *DataArray,uint32_t Cout)
- {
- MySPI_Start();
- MySPI_SwapByte(W25Q64_READ_DATA);
- MySPI_SwapByte(Address >> 16);
- MySPI_SwapByte(Address >> 8);
- MySPI_SwapByte(Address);
- for(uint32_t i = 0;i < Cout;i++)
- {
- DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
- }
- MySPI_Stop();
- }

- #include "stm32f10x.h" // Device header
-
- void MySPI_W_SS(uint8_t BitValue)
- {
- GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
- }
-
-
- void MySPI_Init(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
-
- SPI_InitTypeDef SPI_InitStructure;
- //SPI模式
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
- //配置SPI裁剪引脚,当前选择为双线全双工
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
- //配置8位还是16位数据帧
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
- //选择低位先行还是高位先行
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
- //波特率预分频器,配置SCK时钟的频率
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
- //配置SPI模式
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
- //配置SPI模式
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
- //CRC校验,当前所给为默认值
- SPI_InitStructure.SPI_CRCPolynomial = 7;
- SPI_Init(SPI1,&SPI_InitStructure);
-
- SPI_Cmd(SPI1,ENABLE);
-
- MySPI_W_SS(1);
- }
-
- void MySPI_Start(void)
- {
- MySPI_W_SS(0);
- }
-
- void MySPI_Stop(void)
- {
- MySPI_W_SS(1);
- }
-
- uint8_t MySPI_SwapByte(uint8_t ByteSend)
- {
- while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) != SET);
-
- SPI_I2S_SendData(SPI1,ByteSend);
-
- while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) != SET);
-
- return SPI_I2S_ReceiveData(SPI1);
- }
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。