74HC595A包括一个8位移位寄存器和一个8位D型锁存器和三态并行输出。移位寄存器接受串行数据并提供串行输出。移位寄存器也提供并行数据输出和8位锁存器。移位寄存器和锁存器都有独立的时钟输入。这个IC还具有异步复位的功能HC595A可以直接和CMOSMPU的和MCU的SPI接口进行连接。
电器参数:
引脚功能:
数码管原理图:
驱动时许
开发板与数码管链接:
原理:74HC595,这是一个8位串行输入到并行输出的移位寄存器,带有一个存储寄存器和三态输出)常用于驱动数码管,因为它能够有效减少微控制器(MCU)的I/O端口使用。下面是使用HC595驱动数码管的基本原理:
移位寄存器与存储寄存器:
HC595包含一个8位的移位寄存器和一个8位的存储寄存器。数据通过串行方式(一位一位)输入到移位寄存器中,每次在移位时钟脉冲(SH_CP)的上升沿,数据会向左移动一位。
当所有8位数据都串行输入完毕后,通过在存储器时钟脉冲(ST_CP)上产生一个脉冲,这些数据会被转移到并行输出的存储寄存器中。
并行输出:
移位寄存器中的数据被转移到存储寄存器后,会立即反映到Q0-Q7这8个并行输出端口上。这些输出通常连接到数码管的段选线上,以控制数码管显示哪个数字或字符。
级联扩展:
若要驱动多位数码管,可以通过级联多个HC595来扩展输出端口。第一个HC595的Q7'(第9脚)连接到下一个HC595的DS(数据输入)引脚,这样第二个芯片就会在第一个芯片数据传输完成后开始接收数据。每个额外的HC595可以增加8个输出,用于驱动更多数码管的公共端或段选线。
数码管的控制:
数码管通常有两种控制方式:共阴极和共阳极。对于共阴极数码管,要显示某个数字,需要将对应段选线(a-g及dp)设置为高电平;而对于共阳极,则需设置为低电平。位选线(用于选择要显示哪一位数码管)则直接由MCU或其他逻辑控制,或者也可以通过HC595的某些输出端控制。
GPIO配置;
程序设计:
#include "ti_msp_dl_config.h" //dat -- PA27 : 串行数据输入 //SCLK-- PA26 :移位时钟 //RCLK-- PA13 :并行寄存器锁存时钟 // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, b, C, d, E, F uint8_t Disp_DX[ 16 ]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //段显 uint8_t Disp_PX[ 8 ]={1,2,3,4,5,6,7,8}; //片选 //uint8_t Disp_DX[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x77, 0x83, 0xC6, 0xA1, 0x86, 0x8E, 0xFF, 0xBF } #define HC595_DAT(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_DIO_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_DIO_PIN))) #define HC595_CLK(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_SCLK_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_SCLK_PIN))) #define HC595_RCK(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_RCLK_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_RCLK_PIN))) #define LED(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_TEST_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_TEST_PIN))) uint8_t TimerCnt,TmpVal; void Display_Out() { HC595_RCK(0); delay_cycles(100); HC595_RCK(1); delay_cycles(100); } void HC595_WriteData(uint8_t data) { uint8_t i; for(i = 0; i < 8; i++) { if((data & 0x80)>0){ HC595_DAT(1); } else { HC595_DAT(0); } data <<= 1; delay_cycles(100); HC595_CLK(0); delay_cycles(100); HC595_CLK(1); delay_cycles(100); } } //发送一个数字(0-9)到指定位的数码管 //dis_num 发送的数字(0-9) //dis_bit 发送到第几个数码管,即:片选(0-7) void HC595_SEND_DATA(uint8_t disp_num, uint8_t disp_bit) { HC595_WriteData(disp_num); HC595_WriteData(1<<disp_bit); Display_Out(); } //数码管同时显示8位数字 void Disp_Data(uint16_t dataH, uint16_t dataL) { uint16_t tempH,tempL; uint8_t num_q, num_b,num_s,num_g; tempL = dataL; num_q = tempL/1000; num_b = tempL/100%10; num_s = tempL/10%10; num_g = tempL%10; HC595_SEND_DATA(Disp_DX[num_q],3); HC595_SEND_DATA(Disp_DX[num_b],2); HC595_SEND_DATA(Disp_DX[num_s],1); HC595_SEND_DATA(Disp_DX[num_g],0); tempH = dataH; num_q = tempH/1000; num_b = tempH/100%10; num_s = tempH/10%10; num_g = tempH%10; HC595_SEND_DATA(Disp_DX[num_q],7); HC595_SEND_DATA(Disp_DX[num_b],6); HC595_SEND_DATA(Disp_DX[num_s],5); HC595_SEND_DATA(Disp_DX[num_g],4); } void TIMER_0_INST_IRQHandler(void) { switch(DL_Timer_getPendingInterrupt(TIMER_0_INST)){ case DL_TIMER_IIDX_ZERO: TimerCnt ++; if(TimerCnt >= 2) { TimerCnt = 0; TmpVal --; if(TmpVal == 0) { TmpVal = 10; } } break; default: break; } } /* void TIMER_0_INST_IRQHandler(void) { switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMER_IIDX_ZERO: TimerCnt++; if(TimerCnt >= 100) { TimerCnt = 0; TmpVal++; if(TmpVal > 500)TmpVal=0; } break; default: break; } } */ /* This results in approximately 0.5s of delay assuming 32MHz CPU_CLK */ #define DELAY (16000000) int main(void) { TmpVal = 10; SYSCFG_DL_init(); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); while (1) { LED(0); Disp_Data(0000,TmpVal); // delay_cycles(1600000); delay_cycles(1600000); // LED(1); // delay_cycles(1600000); delay_cycles(1600000); // Disp_Data(8888,8888); } }
视频见回复!