stm32模拟SPI协议

代码使用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();
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟寒凌风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值