之前一直对SPI通信一知半解,所以想抽空把它搞得明白一些。考虑到之前是结合Flash芯片来学的,十分不直观,而且主要把时间和精力都花在Flash芯片的datasheet和驱动上了,SPI通信也没学好。所以这次就考虑用4位数码管显示模块,模块是直接买的现成的,如下图所示,这样可以简化操作,把精力聚焦到学习的核心–SPI通信本身上来。
该模块是用2片74HC595串联驱动的,一片用来控制数码管的位选(U1),一片用来控制数码管的段选(U2)。接口比较简单,总共5个引脚,2个引脚分别接VCC和GND,DIO用来接收串行数据的输入,SCLK用来接收同步时钟,每个SCLK上升沿74HC595内部的移位寄存器会移一位,RCLK用来控制数据的输出,每个RCLK上升沿74HC595内部的移位寄存器的数据会被放进存储寄存器并输出到外部引脚QA~QH上。而QH’是串行输出引脚,该引脚会接收最高位的溢出,从而实现多片74HC595的级联。
当两片74HC595串联时,先发八位数据用于段选,再发八位数据用于位选,然后RCLK上升沿,就可以驱动某位数码管显示某个字符,通过动态扫描数码管,由于人眼的视觉暂停效果,就可以实现4位数码管的同时显示。先用通用I/O来实现该数码管的驱动,程序如下:
头文件74HC595.h
#ifndef __74HC595_H__
#define __74HC595_H__
#include"stm32f10x_lib.h" //包含所有的头文件
#include<stdio.h>
// 4-Bit LED Digital Tube Module
#define HC595_SCLK_PIN GPIO_Pin_5 // SPI1_SCK PA5
#define HC595_RCLK_PIN GPIO_Pin_12 // SPI1_NSS PA4
#define HC595_DIO_PIN GPIO_Pin_7 // SPI1_MOSI PA7
#define HC595_GPIO GPIOA
#define HC595_RCLK_GPIO GPIOB
#define HC595_RCC RCC_APB2Periph_GPIOA
#define HC595_RCLK_RCC RCC_APB2Periph_GPIOB
void HC595_Init(void);
void HC595_SendByte(u8 data);
u8 HC595_Display(u16 num, u8 dp);
#endif
源文件74HC595.c
// 用于HC595实现的4Bit-LED Digit Tube Module
// 注意:该4位数码管是共阳的!
#include "74HC595.h"
// 码表
const u8 digitTable[] =
{
// 0 1 2 3 4 5 6 7 8 9
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,
// A b C d E F -
0x8C, 0xBF, 0xC6, 0xA1, 0x86, 0xFF, 0xbf
};
/*******************************************************************************
* Function Name : HC595_Init
* Description : 初始化HC595
* Input : None
* Output : None
* Return : None
**********************************************************************