STM32F410RB HAL SPI驱动数码管模块,求指导
本帖最后由 疯影17 于 2017-11-5 23:00 编辑新手上路,请教了{:3_41:}
开发板用的 NUCLEO-f410rb ,数码管用的4位共阳极的能串联的静态显示模块。
首先配置spi2模式为“全双工主模式”
连线
STM32 -> 数码管
SPI2_MOSI -> SDI
SPI2_SCK -> SCLK
SPI2_LOAD -> LOAD
5V -> VCC
GND -> GND
SPI2_MOSI是SPI2主机输出, SPI2_SCK是主机时钟,其中SPI2_LOAD是普通引脚PA5,只用了这三个引脚。主机输入没用,因为数码管驱动不需要。
在main.c文件中添加两个变量
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint16_t add_num = 0;
uint8_t data[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f};// 数码管的段码0-f 最后一位0x7f是小数点
/* USER CODE END PV */led.h头文件
#ifndef LED_H
#define LED_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "main.h"
/* 数码管位枚举 */
typedef enum{
GE_BIT,
SHI_BIT,
BAI_BIT,
QIAN_BIT
}LedBIT;
extern uint8_t data[];
extern SPI_HandleTypeDef hspi2;
void hc74959_display(uint16_t num);
#endif
led.c
#include "led.h"
/* 数码管显示函数 spi2驱动
*数码管模块是74hc595驱动的,静态显示所以有每位数码管单独一个74hc595
*/
void hc74959_display(uint16_t num){
uint16_t qian = num / 1000; // 解析后的千位数字
uint16_t bai = num / 100 % 10;// 解析后的百位数字
uint16_t shi = num /10 %10; // 解析后的十位数字
uint16_t ge = num %10; // 解析后的个位数字
for (uint8_t j=0;j<4;j++){
switch (j){
case GE_BIT:
// 个位
HAL_SPI_Transmit(&hspi2, &data, 1, 1000); // SPI 输出
break;
case SHI_BIT:
// 十位
HAL_SPI_Transmit(&hspi2, &data, 1, 1000);
break;
case BAI_BIT:
// 百位
HAL_SPI_Transmit(&hspi2, &data, 1, 1000);
break;
case QIAN_BIT:
// 千位
HAL_SPI_Transmit(&hspi2, &data, 1, 1000);
break;
default:
break;
}
} // end for
/* 让锁存输出一个高电平脉冲 */
HAL_GPIO_WritePin(SPI2_LOAD_GPIO_Port, SPI2_LOAD_Pin, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(SPI2_LOAD_GPIO_Port, SPI2_LOAD_Pin, GPIO_PIN_RESET);
} /* end --------- hc74959_display functions ---------------- */
main.c 文件中的主循环
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(1000); // 每隔1秒add_num加1
add_num ++;
if (add_num >=1000){// 当add_num 大于1000时,从新赋值为0
add_num = 0;
}
hc74959_display(add_num); 调用led.c中的数码管显示函数
}
/* USER CODE END 3 */以上是所有代码。
最主要的是SPI的发送数据函数HAL_SPI_Transmit(&hspi2, &data, 1, 1000);,使用方法对不对,第三个参数的意思不是很明白。
配置的是全双工主模式,但是用的HAL_SPI_Transmit()是发送函数,会不会有什么影响?
HAL_SPI_Transmit()是最后的驱动数码管的选择吗?
逻辑分析仪的显示情况
看显示状况是没什么问题。
支持一下 :) 驱动数码管是啥芯片? 楼主下次请发求助帖! 本帖最后由 toofree 于 2018-3-8 01:34 编辑
HAL_SPI_Transmit(&hspi2, &data, 1, 1000);
原型是这样的,
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)。
第三个参数是一次要连续发送的数据个数;第四个参数为最大延时时间,单元为us。
假设SPI时钟为1MHz,即1us;发送的数据长度Size为N,发送数据类型为uint8_t,那么一共要传输 N*8位。
整个传输时间就是 1us * N * 8位 =8N us,那么这个Timeout的时间就设为 N*8 us。如果数据类型是uint16_t,那么延时就是 N*16 us Timeout是ms单位的,根本无所谓的,一般直接设为0xFFFF就行了。
另外不用1个字节1个字节发,可以4个字节一起发
HAL_SPI_Transmit(&hspi2, data, 4, 0xFFFF);
还有就是不用设为全双工的,设为master_transmit就可以了,你只发不收的。没必要全双工。
数据发送完毕,在LOAD端口给个信号就会把数字显示出来了。
jjbboox 发表于 2018-3-8 11:03
Timeout是ms单位的,根本无所谓的,一般直接设为0xFFFF就行了。
另外不用1个字节1个字节发,可以4个字节一 ...
知道了,确实是只发送就够了:lol MrJiu 发表于 2017-11-7 11:33
驱动数码管是啥芯片?
74hc595 jjbboox 发表于 2018-3-8 11:03
Timeout是ms单位的,根本无所谓的,一般直接设为0xFFFF就行了。
另外不用1个字节1个字节发,可以4个字节一 ...
0xffff肯定是不行的。。。万一SPI错误,会导致程序卡死在那个SPI传输里!!! 本帖最后由 jjbboox 于 2018-4-6 10:11 编辑
MrJiu 发表于 2018-4-5 09:37
0xffff肯定是不行的。。。万一SPI错误,会导致程序卡死在那个SPI传输里!!! ...
不会卡死的,0xffff也不是什么大数字,也就是65秒,像类似的应用,发送不会失败的,所以这里随便设一个值就行了,除非你要发送一个巨大的数量,确定多少ms内无法发送完成,那么尽量设一个大一点的通常没啥毛病。一般都用DMA或者IT方式发送,都不需要设这个TIMEOUT的。
页:
[1]
2