在嵌入式设计中,您可能会在微控制器中没有足够的I / O引脚。这可能是由于任何原因造成的,可能是您的应用程序需要多个LED或您想使用多个7段显示器,但是您的微控制器中不需要I / O引脚。这是一个完美的组件,移位寄存器。移位寄存器接受串行数据并提供并行输出。仅需3个引脚即可与您的微控制器连接,您将从中获得8个以上的输出引脚。最受欢迎的移位寄存器之一是74HC595。它具有8位存储寄存器和8位移位寄存器。在此处了解有关移位寄存器的更多信息。
您将提供串行数据到移位寄存器,并将其锁存到存储寄存器中,然后存储寄存器将控制8个输出。如果需要更多输出,只需添加另一个移位寄存器。通过级联两个移位寄存器,您将获得额外的8个输出,总共16位输出。
移位寄存器74HC595:
这是根据数据表74HC595的引脚排列图-
HC595具有16针;如果我们看到数据表,我们将了解引脚功能-
的QA到QH,从引脚编号1至7和15用作输出8位从移位寄存器,其中,作为所述销14被用于接收串行数据。关于如何使用其他引脚以及如何利用移位寄存器的其他功能,还有一个真值表。
当我们编写用于连接74HC595的代码时,将应用此真值表以获得所需的输出。
现在,我们将74HC595与PIC16F877A接口并控制8个LED。我们已经将74HC595移位寄存器与其他微控制器接口:
- 将74HC595串行移位寄存器与Raspberry Pi接口
- 如何在Arduino Uno中使用移位寄存器74HC595?
- 使用移位寄存器将LCD与NodeMCU接口
所需组件:
- PIC16F877A
- 2个33pF陶瓷圆盘电容器
- 20Mhz晶体
- 4.7k电阻
- 8颗LED
- 1k电阻-1个(如果每个LED上需要单独的电阻,则需要8个1k电阻)
- 74HC595集成电路
- 5V墙上适配器
- PIC编程环境
- 面包板和电线
电路原理图:
在电路图中,我们已经连接了串行数据引脚。分别在微控制器的RB0,RB1和RB2引脚上的时钟和选通(锁存)引脚。在这里,我们为8个LED使用了一个电阻。根据真值表,我们通过将74HC595的引脚13接地来启用输出。该QH因为我们不会级联其它引脚悬空,74HC595它。我们通过将移位寄存器的引脚10与VCC连接来禁用清除输入标志。
晶体振荡器连接在微控制器的OSC引脚上。PIC16F877A没有任何内部振荡器。在这个项目中,我们将使用班次混响器从Q0到Q7逐一点亮LED。
我们已经将电路构建在面包板上,
代码说明:
本文末尾给出了使用移位寄存器控制LED的完整代码。与往常一样,我们需要在PIC微控制器中设置配置位。
#pragma config FOSC = HS //振荡器选择位(HS振荡器) #pragma config WDTE = OFF //看门狗定时器使能位(禁止WDT) #pragma config PWRTE = OFF //上电定时器使能位(禁止PWRT) # pragma config BOREN = ON //欠压复位使能位(使能BOR) #pragma config LVP = OFF //低压(单电源)在线串行编程使能位(RB3 / PGM引脚具有PGM功能;低电平电压编程) #pragma config CPD = OFF //数据EEPROM存储器代码保护位(Data EEPROM编码保护关闭) #pragma config WRT = OFF //闪存程序存储器写使能位(写保护关闭;所有程序存储器可能是由EECON控件写入) #pragma config CP = OFF //闪存程序存储器代码保护位(代码保护关闭)
之后,我们声明了延迟所需的晶振频率,并声明了74HC595的引脚分配。
#包括
接下来,我们声明 system_init() 函数来初始化引脚方向。
void system_init(void){ TRISB = 0x00; }
我们使用两个不同的函数创建了时钟脉冲和锁存脉冲
/ * *此功能将启用时钟。 * / void clock(void){ CLK_595 = 1; __delay_us(500); CLK_595 = 0; __delay_us(500); }
和
/ * *此功能将选通并启用输出触发。 * / void strobe(void){ STROBE_595 = 1; __delay_us(500); STROBE_595 = 0; }
在这两个函数之后,我们声明了 data_submit(unsigned int data) 函数将串行数据提交到74HC595。
void data_submit(unsigned int data){ for(int i = 0; i <8; i ++){ DATA_595 =(data >> i)&0x01; 时钟(); } strobe(); //数据最终提交 }
在此函数中,我们接受8位数据,并使用两个左移运算符和AND运算符发送每个位。我们首先将数据一一移位,然后使用AND运算符0x01找出确切的位是0还是1。每个数据由时钟脉冲存储,最终数据输出由锁存或选通脉冲完成。在此过程中,数据输出将首先是MSB(最高有效位)。
在 main 函数中,我们提交了二进制文件,并使输出引脚一一变高。
system_init(); //系统准备就绪 while(1){ data_submit(0b00000000); __delay_ms(200); data_submit(0b10000000); __delay_ms(200); data_submit(0b01000000); __delay_ms(200); data_submit(0b00100000); __delay_ms(200); data_submit(0b00010000); __delay_ms(200); data_submit(0b00001000); __delay_ms(200); data_submit(0b00000100); __delay_ms(200); data_submit(0b00000010); __delay_ms(200); data_submit(0b00000001); __delay_ms(200); data_submit(0xFF); __delay_ms(200); } return; }
这就是移位寄存器可用于在任何微控制器中获取更多空闲I / O引脚以连接更多传感器的方式。