STM8硬件SPI配置比较简单。主要CR1 CR2的配置
其中核心的地方是波特率 时钟极性 和初始相位
下面是SPI的代码配置
#include "spi.h"
void SPI_Init( )
{
CLK_PCKENR1 |= 0x02; //打开SPI时钟
/*PC6、PC5设置为输出,最大10MHz*/
PC_DDR_DDR5 = 1;//输入方向选择 0: 输入模式 1: 输出模式
PC_CR1_C15 = 1;//输出模式控制 推挽输出
PC_CR2_C25 =1;//在输出模式下,0:输出速度最大为2MHZ.1:输出速度最大为10MHZ
PC_DDR_DDR6 = 1;//输入方向选择 0: 输入模式 1: 输出模式
PC_CR1_C16 = 1;//输出模式控制 推挽输出
PC_CR2_C26 =1;//在输出模式下,0:输出速度最大为2MHZ.1:输出速度最大为10MHZ
PC_DDR_DDR7 = 0;//输入方向选择 0: 输入模式 1: 输出模式
PC_CR1_C17 = 1;//输出模式控制 推挽输出 输入模式 0:浮空输入 1 带上拉电阻输入
PC_CR2_C27 =0;//在输出模式下,0:输出速度最大为2MHZ.1:输出速度最大为10MHZ
SPI_CR1=0;
/*MSB、1MHz、主设备、CPOL空闲为高、CPHA第一个时钟开始*/
SPI_CR1_LSBFIRST=0;//0:先发送MSB;
SPI_CR1_MSTR=1; //主设备
SPI_CR1_CPOL=0; //CPOL空闲为高
SPI_CR1_CPHA =0; //数据从第一个时钟边沿开始采样
SPI_CR1_BR=0; //8M Hz
/*双线单向视距传输、CRC计算禁止、软件NSS、主模式*/
SPI_CR2_SSM=1 ; //1:使能软件从设备管理
SPI_CR2_SSI=1; //0:从模式; 1:主模式。 NSS引脚上电平决定于该位的值,而不是NSS引脚上I/O端口的值。
SPI_CR2_RXONLY=0; //0:全双工(同时发送和接收);1:输出禁止(只接收)。
SPI_CR2_CRCNEXT=0; //0:下一个发送的数据来自Tx缓冲区 1:下一个发送的数据来自Tx CRC计数器
SPI_CR2_CECEN=0; //0:CRC计算禁止; 1:CRC计算使能。
SPI_CR2_BDOE =0; //0:输入使能(只接收模式); 1:输出使能(只发送模式)。
SPI_CR2_BDM =0; //0:选择双线单向数据模式; 1:选择单线双向数据模式
SPI_ICR_RXIE=0; //发送完成中断 禁止
/*开启SPI*/
SPI_CR1_SPE=1;
}
uint8_t Write_char_SPI(uint8_t date )
{
uint8_t retry=0;
while(SPI_SR_TXE==0)
{
retry++;
if(retry>=0XFE)return 0; //超时退出
}
retry=0;
SPI_DR=date;
while(SPI_SR_RXNE==0)
{
retry++;
if(retry>=0XFE)return 0; //超时退出
}
return SPI_DR;
}
//返回值1 为发送失败 0为成功
uint8_t Write_SPI(const uint8_t *date ,uint8_t size)
{
uint8_t retry=0;
for(;size>0;size--)
{
while(SPI_SR_TXE==0)
{
retry++;
if(retry>=0XFE)return 1; //超时退出
}
retry=0;
SPI_DR=*date;
date++;
/* while(SPI_SR_RXNE==0)
{
retry++;
if(retry>=0XFE)break ; //超时退出
}
test= SPI_DR;
*/
}
if(retry>=0XFE)
return 1;
else return 0; //发送成功
}
void SPI_SetSpeed(uint8_t SpeedSet)
{
SpeedSet&=0X07; //限制范围
SPI_CR1_SPE=0; //SPI设备失能
SPI_CR1_BR=SpeedSet;
SPI_CR1_SPE=1;