0%

HAL库 - SPI

向从机发送数据

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
参数hspi:SPI句柄的指针,例如&hspi1
参数pData:要发送数据的指针
参数Size:要发送数据的量,单位字节
参数Timeout:超时时间,单位ms。HAL_MAX_DELAY表示无限长超时时间

从从机接收数据

HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
参数hspi:SPI句柄的指针,例如&hspi1
参数pData:接收缓冲区的指针
参数Size:要接收数据的量,单位字节
参数Timeout:超时时间,单位ms。HAL_MAX_DELAY表示无限长超时时间

发送同时接收数据

HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
参数hspi:SPI句柄的指针,例如&hspi1
参数pTxData:要发送数据的指针
参数pRxData:接收缓冲区的指针
参数Size:要发送=接收数据的量,单位字节
参数Timeout:超时时间,单位ms。HAL_MAX_DELAY表示无限长超时时间

示例:LED亮灭状态保存在Flash中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void SaveLEDStatus(uint8_t ledstatus)//保存LED状态
{
//1.写使能
uint8_t writeEnableCmd[] = {0x06};//写使能命令
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);//向CS引脚发送低电压
HAL_SPI_Transmit(&hspi1, writeEnableCmd, 1, HAL_MAX_DELAY);//发送写使能命令
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);//向CS引脚发送高电压
//2.扇区擦除
uint8_t sectorEraseCmd[] = {0x20,0x00,0x00,0x00};//擦除扇区命令
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);//向CS引脚发送低电压
HAL_SPI_Transmit(&hspi1, sectorEraseCmd, 4, HAL_MAX_DELAY);//发送擦除扇区命令
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);//向CS引脚发送高电压
//3.延迟100ms
HAL_Delay(100);
//4.写使能
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);//向CS引脚发送低电压
HAL_SPI_Transmit(&hspi1, writeEnableCmd, 1, HAL_MAX_DELAY);//发送写使能命令
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);//向CS引脚发送高电压
//5.页编程
uint8_t pageProgCmd[5];//页编程
pageProgCmd[0] = 0x02;//页编程指令码
pageProgCmd[1] = 0;//24位地址
pageProgCmd[2] = 0;//24位地址
pageProgCmd[3] = 0;//24位地址
pageProgCmd[4] = ledstatus;//要写入的数据
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);//向CS引脚发送低电压
HAL_SPI_Transmit(&hspi1, pageProgCmd, 5, HAL_MAX_DELAY);//发送页编程命令
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);//向CS引脚发送高电压
//6.延迟10ms
HAL_Delay(100);
}

uint8_t LoadLEDStatus(void)//加载LED状态,开机时使用
{
uint8_t readDataCmd[] = {0x03, 0x00, 0x00, 0x00};//读数据指令码
uint8_t ledState = 0xff;//用于接收读取到的数据
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);//向CS引脚发送低电压

HAL_SPI_Transmit(&hspi1, readDataCmd, 4, HAL_MAX_DELAY);//发送读数据命令
HAL_SPI_Receive(&hspi1, &ledState, 1, HAL_MAX_DELAY);//读取数据

HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);//向CS引脚发送高电压
return ledState;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
HAL_Delay(1000);   // 等待外部 Flash 上电稳定
uint8_t pre = 1, cur = 1;
uint8_t LEDState = 0;//LED亮灭状态
LEDState = LoadLEDStatus();//从Flash读取LED关机前状态
if(LEDState == 1)
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET);
}

while (1)
{
pre = cur;//把当前电平给到上一次记录的电平
if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3) == GPIO_PIN_SET)//按下按钮,当前值是1,否则为0
{
cur = 1;
}
else
{
cur = 0;
}

if (cur != pre)//当前值和上一次记录的值不相等
{
HAL_Delay(10);//延迟10ms,消抖
if(cur == 0)//当前值是0,还处于按下没松手的状态
{
//不做任何操作
}
else//当前值是1,松手了
{
if(LEDState == 1)//LED记录值为1,现在是点亮状态,要熄灭
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET);
LEDState = 0;//更新LED记录值
}
else//LED记录值是0,现在是熄灭状态,要点亮
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET);
LEDState = 1;//更新LED记录值
}
SaveLEDStatus(LEDState);
}
}