代码使用HAL库实现。
话不多说,直接看代码
//GPIO初始化
void MX_IO_Init(void)
{
//本例中引脚端口是GPIOB,使能时钟为__HAL_RCC_GPIOB_CLK_ENABLE();
//如果移植,请注意此处的更改
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pins : PBPin PBPin PBPin PBPin */
GPIO_InitStruct.Pin = SET_PIN|SCK_PIN|MOSI_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = MISO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
#define SET_PIN GPIO_PIN_12 //433模块选择管脚,PB12
#define SCK_PIN GPIO_PIN_13 //spi时钟管脚,PB13
#define MOSI_PIN GPIO_PIN_15 //MOSI主发从收管脚,PB15
#define MISO_PIN GPIO_PIN_14 //MISO主收从发管脚,PB14
#define SEL_L() HAL_GPIO_WritePin(GPIOB,SET_PIN,GPIO_PIN_RESET); //设置选择引脚为高电平
#define SEL_H() HAL_GPIO_WritePin(GPIOB,SET_PIN,GPIO_PIN_SET); //设置选择引脚为低电平
#define SDI_L() HAL_GPIO_WritePin(GPIOB,MOSI_PIN,GPIO_PIN_RESET) //主器件发出低电平
#define SDI_H() HAL_GPIO_WritePin(GPIOB,MOSI_PIN,GPIO_PIN_SET) //主器件发出高电平
#define SDO_READ() (HAL_GPIO_ReadPin(GPIOB,MISO_PIN)==GPIO_PIN_SET) //主器件接收
#define CLK_L() HAL_GPIO_WritePin(GPIOB,SCK_PIN,GPIO_PIN_RESET) //设置时钟线低电平
#define CLK_H() HAL_GPIO_WritePin(GPIOB,SCK_PIN,GPIO_PIN_SET) //设置时钟线高电平
/* 用于控制SPI总线速率,根据不同的MCU速度来调整;当前为MCU主频为48MHz */
#define TIME 4 //该参数用来设置延时效果
//延时一小段时间
void dellayus(unsigned int i)
{
unsigned int j,k;
for (j = 0; j <1; j++){
for (k = 0; k < i; k++);
}
}
//SPI发送字节函数.一次发送一个字节
void SpiInOut(unsigned char senddata)
{
unsigned char i;
for(i=0;i<8;i++)
{
dellayus(TIME);
CLK_L();
if((senddata<<i)&0x80)
{
dellayus(TIME);
SDI_H();
}
else
{
dellayus(TIME);
SDI_L();
}
dellayus(TIME);
CLK_H();
}
dellayus(TIME);
CLK_L();
SDI_L();
}
//SPI接收字节函数,一次返回一个字节
unsigned char SpiRCVaByte(void)
{
unsigned char i,temp;
temp = 0;
for(i=0;i<8;i++)
{
CLK_L();
dellayus(TIME);
temp=(temp<<1);
CLK_H();
dellayus(TIME);
if(SDO_READ())
temp++;
else
temp = temp+0;
dellayus(TIME);
}
CLK_L();
dellayus(TIME);
return temp;
}
//SPI写数据函数,addr:从器件寄存器地址,*buffer数据数组,size数据长度
void SPIwriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SEL_L();
SpiInOut( addr | 0x80 );
for( i = 0; i < size; i++ )
{
SpiInOut( buffer[i] );
}
SEL_H();
}
//SPI读数据函数,addr:从器件寄存器地址,*buffer数据数组,size数据长度
void SPIreadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SEL_L();
SpiInOut( addr & 0x7F );
for( i = 0; i < size; i++ )
{
buffer[i] = SpiRCVaByte();
}
SEL_H();
}