实验原理
打开扩展板原理图对照扩展板可以看到扩展板上四位数码管原理图如下:
![](https://i-blog.csdnimg.cn/blog_migrate/e90da55fdb20f6a57f8bc83d2596acef.png)
由图中可以确定数码管为共阴极数码管,DS_A、DS_B、DS_C、DS_D、DS_E、DS_F、DS_G、DS_DP 分别对应数码管的每个段,对应管脚为高电平时对应的部位会被电量,因为只有一组数据信号,但是有四个数码管,所以需要通过控制 DS_G1、DS_G2、DS_G3 和DS_G4 选择某个数码管显示内容,然后通过轮询刷新让四个数码管正常显示。
![](https://i-blog.csdnimg.cn/blog_migrate/7402c01fb3ae9b189c327f76a4c9ae51.png)
M74HC595 是一个传入并出的移位寄存器,如果有多个芯片级联也可串行输出控制下一级芯片,QA~QH 为并行输出,QH’为串行输出;如果本例四个 LED 数码管由两个M74HC595 控制,第一级控制数码管显示什么,第二级控制哪个数码管显示。
![](https://i-blog.csdnimg.cn/blog_migrate/83b69e14e101aed2641636dbdd3b0151.png)
所以当需要第 2个数码管显示 8时,只需要通过 SER连续输入 02 7F两个字节数据即可。
原理图中 RCLK、SRCLK、SER 分别和 STM32MP157 的 SPI4_NSS、SPI4_CLK、SPI4_MOSI 连接,74HC595 芯片手册中对于 RCLK、SRCLK 及 SER 的描述为:
![](https://i-blog.csdnimg.cn/blog_migrate/665db77fc2c3cb606cf2a448bfc69f17.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3e6381043dfba75ca14c42c5df0e8846.png)
SPI 中 NSS、CLK、MOSI 描述为:
![](https://i-blog.csdnimg.cn/blog_migrate/577a81857a6279a761af578028f9419f.png)
根据上述描述在编写驱动是可以通过GPIO模拟74HC595的时钟完成控制,因为74H595时序和 SPI 时序兼容,所以也可通过 SPI 控制器控制 74HC595。
![](https://i-blog.csdnimg.cn/blog_migrate/d2376d2c6412c0ed7bc4af32751f617d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/15ac23ef1eb413964aaf0067734966f8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c061dd947d80023b621a2687cbedeec8.png)
查看芯片手册,管脚对应关系如下:
![](https://i-blog.csdnimg.cn/blog_migrate/a1a9077b6cc4e3e30d2dec924c85182a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bc96776ade68d8c29e2a57bbea46a8c0.png)
实验步骤
打开 STM32CubeIDE,配置 CubeMX。
根据 21.1 节,使用的是 SPI 默认引脚,分别对 PE11、PE12、PE13 和 PE14 配置为SPI_NSS、SPI_SCK、SPI_MISO 和 SPI_MOSI。切换到 SPI4 标签,勾选给“M4”,“Mode”选择“Full-Duplex-Master”,使用硬件片选,选择“Hardware NSS Output Signal”,其配置如下图所示。
![](https://i-blog.csdnimg.cn/blog_migrate/350dca3100477b6723ee5c6b74afb7f9.png)
代码设计
本次使用的是硬件 SPI,就不需要自己写程序实现 SPI 时序,需要做的仅仅是调用 HAL 提
供的 SPI 硬件操作函数,其中,调用“HAL_SPI_Transmit”函数实现主机向从机发送数据,创
建 driver_sm74hc.c 文件,在文件中实现数码管的控制代码如下。
void M74HC595_ReadDataTest(void)
{
rw_595_Register(0X02,0X66);
HAL_Delay(1);
rw_595_Register(0X04,0X07);
HAL_Delay(1);
}
uint8_t rw_595_Register(uint8_t reg,uint8_t data)
{
uint8_t txdata[2] = {reg, data};
if(HAL_SPI_Transmit(&hspi4, txdata ,2,300) != HAL_OK)
{
Error_Handler();
}
return 0;
}
其中,参数“reg”表示第几个数码管显示,参数“data”表示数码管显示的内容。
第一个参数是SPI对应的句柄,这个可以在SPI的初始化函数中找到相关变量名称,一般是hspix(其中x为具体的SPI序号),第二个参数是数据缓存,第三个是需要发送的数据个数,第四个是超时等待数单位视毫秒。
在主函数中循环调用“rw_595_Register”函数即可以实现在数码管上显示特定内容
实验现象
![](https://i-blog.csdnimg.cn/blog_migrate/d7e0deb295b88f69fb97e7927a668d80.png)
代码解析
driver_m74hc.h
#ifndef __DRIVER_M74HC_H
#define __DRIVER_M74HC_H
#include "main.h"
#include "stm32mp1xx_hal.h"
#include "spi.h"
/**SPI4 GPIO Configuration
PE13 ------> SPI4_MISO
PE14 ------> SPI4_MOSI
PE11 ------> SPI4_NSS
PE12 ------> SPI4_SCK
*/
#define SDO_ON HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14,GPIO_PIN_SET);
#define SDO_OFF HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14,GPIO_PIN_RESET);
#define SCK_ON HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12,GPIO_PIN_SET);
#define SCK_OFF HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12,GPIO_PIN_RESET);
//
#define NSS_ON HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11,GPIO_PIN_SET);
#define NSS_OFF HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11,GPIO_PIN_RESET);
extern uint8_t M74HC595_Init(void);
extern void M74HC595_ReadDataTest(void);
extern uint8_t rw_595_Register(uint8_t reg,uint8_t data);
#endif
driver_m74hc.c
#include "driver_m74hc.h"
#include "stm32mp1xx_hal.h"
void M74HC595_ReadDataTest(void)
{
rw_595_Register(0X02,0X66);
HAL_Delay(1);
rw_595_Register(0X04,0X07);
HAL_Delay(1);
}
uint8_t rw_595_Register(uint8_t reg,uint8_t data)
{
uint8_t txdata[2] = {reg, data};
if(HAL_SPI_Transmit(&hspi4, txdata ,2,300) != HAL_OK) //发送数据
{
Error_Handler();
}
return 0;
}