赞
踩
CPOL和CPHA决定模式x
(Clock Polarity时钟极性)(Clock Phase 时钟相位(是表示第一个时钟采样移入还是第二个移入,不是规定上升沿采样还是下降沿采样))
模式0(比模式1提前半个SCK时钟,相当于把SS的第一个变化当作时钟下降沿作用(在此时移出数据))用的最多
模式1(SCK上升沿输入数据,下降沿输出)
模式2(SCK的极性时模式0的取反)
模式3(SCK的极性时模式1的取反)
- 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);
- }
SS空闲时为1.
- void MySPI_Start(void)
- {
- MySPI_W_SS(0);
- }
-
- void MySPI_Stop(void)
- {
- MySPI_W_SS(1);
- }
- uint8_t MySPI_SwapByte(uint8_t SendByte)//模式0
- {
- uint8_t ByteReceive = 0x00;
-
- //SS下降沿,移出数据(就是Start)
- for(uint8_t i = 0; i<8; ++i)
- {
- MySPI_W_MOSI(SendByte & (0x80 >> i));
- MySPI_W_SCK(1);//SCK上升沿,移入数据
- if(MySPI_R_MISO() == 1 ){ByteReceive |= (0x80 >> i);}
- MySPI_W_SCK(0);//SCK下降沿,移出数据
- }
- return ByteReceive;
- }
STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担
可配置8位/16位数据帧、高位先行/低位先行(串口是低位先行)
时钟频率: fPCLK / (2, 4, 8, 16, 32, 64, 128, 256)
支持多主机模型、主或从操作
可精简为半双工/单工通信
支持DMA(有大量数据传输时可以用DMA,少量数据没必要用)
兼容I2S协议(主要传输数字音频信号)
STM32F103C8T6 硬件SPI资源:SPI1、SPI2
SPI框图
简化框图
1.初始化。NSS配置麻烦,所以用软件模拟
- void MySPI_Init(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
-
- /*SPI SS输出GPIO设置为推挽输出*/
- 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);
-
- /*SPI输入GPIO设置为上拉输入*/
- 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 SS输出GPIO设置为复用推挽输出*/
- 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);
-
- SPI_InitTypeDef SPI_InitStructure;
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//时钟分频
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
- SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC校验位
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//传输的数据时多少位的
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//高位先行
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//STM32是主机
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS不管,靠软件模拟SS
- SPI_Init(SPI1, &SPI_InitStructure);
-
- SPI_Cmd(SPI1, ENABLE);
-
-
- /*空闲状态为 SS:1 */
- MySPI_W_SS(1);
-
- }
2. SS模拟。Start 和Stop。 发送一个字节
- void MySPI_Start(void)
- {
- MySPI_W_SS(0);
- }
-
- void MySPI_Stop(void)
- {
- MySPI_W_SS(1);
- }
-
- uint8_t MySPI_SwapByte(uint8_t SendByte)
- {//TXE
- while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);
-
- SPI_I2S_SendData(SPI1, SendByte);
- //RXNE
- while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);
-
- return SPI_I2S_ReceiveData(SPI1);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。