赞
踩
数模管作为STM32的一个重要外设,由于其成本低、稳定,被用于许多场景中。本篇文章来介绍下四位数码管的使用方法。
数码管分为共阴数码管和共阳数码管,共阴和共阳的区别就在于,输出1还是输出0的时候,能点亮数码管的一小段。
在这篇文章中,所使用的是由两片74HC595芯片控制的4位数码管
挂几张图
该芯片是一个8位串行输入、并行输出的位移缓存器。(缓存器在控制数码管中具有重要作用)
Q0~Q7:并行输出
Q7’:串行输出
SH_CP:移位寄存器时钟输入
ST_CP:存储寄存器时钟输入
DS:串行输入
使用两片74HC595芯片,第一片74HC595芯片的Q7口,也就是串行输出口可以向下一片的74HC595芯片的串行输入口输入数据。
第二片74HC595芯片是用于控制数码管输出显示,而第一片74HC595芯片只使用了QA、QB、QC、QD四个管脚来储存信息。
对于4位的数码管模块,接线选择为
VCC------------>供电
DIO------------>PB13
RCLK------------>PB12 当八个数据完全传入缓冲区,此时拉高RCLK,八位数据便可以一次性全部输出。
SCLK------------>PB15 控制串入的时钟信号线,当有一个上升沿,便传入一个数据。
GND------------>接地
本文主要使用PB13 、PB12 、PB15 来控制数码管的显示数据。
以下使用数码管也是以这三个端口进行分析。
主要是由以下四个函数构成:
void HC595_GPIO_Configuration(void);
void HC595_Send_Data(unsigned char num, unsigned char show_bit);
void HC595_Send_Byte(unsigned char byte);
void display(unsigned int n);
该函数主要是使能接在4位数码管的主要GPIO口,如上文提到的一般:
/************************ VCC------------>供电 DIO------------>PB13 RCLK------------>PB12 SCLK------------>PB15 GND------------>接地 **************************/ unsigned int num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff, 0x00}; //创建一个数组,0-9所对应的十六进制数 void HC595_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_RESET); }
作用:使能相应管脚,并将其全部拉低。
/********************************* 参数:byte 所传入的数据, 是要显示的数字或者是对应显示的位数 **********************************/ /************************ VCC------------>供电 DIO------------>PB13 RCLK------------>PB12 SCLK------------>PB15 GND------------>接地 **************************/ //串入 void HC595_Send_Byte(unsigned char byte) { unsigned int i; for(i = 0; i < 8; i++) { if(byte & 0x80) GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_SET); else GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET); Delay_us(10); GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_SET); Delay_us(10); byte <<= 1; } }
作用:发送字节到74HC595芯片的缓冲器中。
分析:发送的过程很重要,需要搞清所使用的芯片是先低位发送还是先高位。
如图:
由74HC595的芯片手册可以知道:74HC595芯片的发送顺序是由QA,一直到QH,到目前为止,我们虽然清楚了该芯片的发送顺序,但是仍然不知道QA和QH究竟哪个是高位。
而在该数据手册中,还可以发现:
这张图很明显的说明了问题的关键——QA是高位,QH是低位。
由此我们知道了这个芯片是先写入最高位,再依次发送到最低位。所以在该段函数中,我们通过该数据与(&)0x80,取出最高位,通过DIO口输入1/0,由于之前所提到的,唯有SCLK到达上升沿的时候,数据才能传入,于是我们在每次循环输入数据的时候,都将SCLK(PB13)拉高10us ,然后再将所要输入的byte左移一位,继续循环。
由于两片74HC595芯片的作用,当第一片74HC595芯片的缓冲区八位都存在数据的时候,此时DIO口继续输入数据,则将会将已有数据顶置到下一片74HC595的缓冲区。
因此所要显示数字的数据传入完成后,继续传入其所要求显示的数码管位置,该过程也同理于数字数据的传输过程。
/********************************* 参数:num 所要显示的数字, show_bit 所显示的位数 **********************************/ /************************ VCC------------>供电 DIO------------>PB13 RCLK------------>PB12 SCLK------------>PB15 GND------------>接地 **************************/ //并出 void HC595_Send_Data(unsigned char num, unsigned char show_bit) { HC595_Send_Byte(num); HC595_Send_Byte(1 << show_bit); GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET); Delay_us(10); GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET); Delay_us(10); }
作用:控制4位数码管的显示位置以及显示的数字
分析:该函数使用之前所定义和编写的void HC595_Send_Byte(unsigned char byte)函数继续工作,需要注意的是,当数据和位置全部输入后,需要拉高RCLK(PB12)的电平,使其完成显示。
最为关键的显示函数
void display(unsigned int n) { static unsigned int thousand_bit, hundred_bit, ten_bit, single_bit; thousand_bit = n / 1000; hundred_bit = (n % 1000) / 100; ten_bit = n % 1000 % 100 / 10; single_bit = n % 10; HC595_Send_Data(num[thousand_bit], 3); HC595_Send_Data(num[hundred_bit], 2); HC595_Send_Data(num[ten_bit], 1); HC595_Send_Data(num[single_bit], 0); }
由于void HC595_Send_Data(unsigned char num, unsigned char show_bit)此函数的显示问题,一次只能显示一个位置的数字,因此需要搭配主函数中的while(1){ }
继续循环显示,利用人眼捕获的时间差,从而动态显示全部的数字。
以上便是4位数码管的显示方法以及其分析了。
如有不足,还希望指出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。