赞
踩
74HC595是一个8位串行输入、并行输出的位移缓存器:并行输出为三态输出。在SCK 的上升沿,串行数据由数据脚(A)输入到内部的8位位移缓存器,并由Q7’输出,而并行输出则是在LCK的上升沿将在8位位移缓存器的数据存入到8位并行输出缓存器。当串行数据输入端OE的控制信号为低使能时,并行输出端的输出值等于并行输出缓存器所存储的值
由真值表可知:
当移位寄存器时钟线为上升沿时,会获取当时数据引脚的数据 ,即SDA当时的电平状态,存入移位寄存器中,若 SER引脚为低电平,则从低位开始存储。如果SER引脚为高电平,则从高位开始存储。
由于移位寄存器只有八位,当数据超过8位时,多出的位数将会通过SQH串行输出,一般将SQH与下一级的数据输入引脚(SDA)相连,实现级联。
当存储寄存器时钟线为上升沿时,会将移位寄存器中的数据存储到存储寄存器当中。
当OE脚为低电平时,会将存储寄存器中的数据输出至总线,通过存储寄存器的数据实现对 QA-QH的控制。
根据以上信息,可以得出结论,如果要控制QA-QH的电平输出,控制分为四个步骤:
SDA输入数据。
SCK给一个上升沿,将SDA的一个数据移入移位寄存器,循环八次。
RCK给一个上升沿,将移位寄存器的数据转存到存储寄存器。
OE脚置低,将存储寄存器中的数据输入至数据总线
#include <stdio.h> #include <stdint.h> #include <string.h> #include <stdlib.h> #include "mdf_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "gpio.h" #include "stdint.h" #define SCK_GPIO_PIN 13 // 移位寄存器时钟线引脚 #define RCK_GPIO_PIN 15 //存储寄存器时钟线引脚 #define SDA_GPIO_PIN 2 //数据引脚 #define _74HC595_LEVEL 2 //74HC595级联数 #define HC595_SCK_Low() gpio_set_level(SCK_GPIO_PIN,0) //SCK置低 #define HC595_SCK_High() gpio_set_level(SCK_GPIO_PIN,1) //SCK置高 #define HC595_RCK_Low() gpio_set_level(RCK_GPIO_PIN,0) //RCK置低 #define HC595_RCK_High() gpio_set_level(RCK_GPIO_PIN,1) //RCK置高 #define HC595_Data_Low() gpio_set_level(SDA_GPIO_PIN,0) //输入低电平 #define HC595_Data_High() gpio_set_level(SDA_GPIO_PIN,1) //输入高电平 /* @brief : 74HC595控制引脚初始化 */ void _74hc595_init(void) { gpio_config_t io_conf = { .intr_type = GPIO_PIN_INTR_DISABLE, .mode = GPIO_MODE_OUTPUT, .pin_bit_mask = (1ULL<<SCK_GPIO_PIN)|(1ULL<<RCK_GPIO_PIN)|(1ULL<<SDA_GPIO_PIN), .pull_down_en = 1, .pull_up_en = 0, }; gpio_config(&io_conf); HC595_SCK_Low(); HC595_RCK_Low(); HC595_Data_Low(); } /* @brief:74HC595输出锁存 使能 */ void HC595_Save(void) { /** 步骤3:RCK产生一个上升沿,移位寄存器的数据移入存储寄存器 **/ HC595_RCK_Low(); // 将RCK拉低 delay(10); HC595_RCK_High(); // 再将RCK拉高,RCK即可产生一个上升沿 } /*** *74HC595 发送一个字节 *即往74HC595的SDA引脚发送一个字节 */ void HC595_Send_Byte(uint8_t byte) { uint8_t i; for (i = 0; i < 8; i ++) //一个字节8位,传输8次,一次一位,循环8次,刚好移完8位 { /**** 步骤1:将数据传到DS引脚 ****/ HC595_SCK_Low(); // SCK拉低 if (byte & 0x80){ //先传输高位,通过与运算判断第八是否为1 HC595_Data_High(); //如果第八位是1,则与 595 DS连接的引脚输出高电平 }else{ //否则输出低电平 HC595_Data_Low(); } /*** 步骤2:SCK每产生一个上升沿,当前的bit就被送入移位寄存器 ***/ byte <<= 1; // 左移一位,将低位往高位移,通过 if (byte & 0x80)判断低位是否为1 HC595_SCK_High(); // SHCP拉高, SHCP产生上升沿 } } /** *发送多个字节 *便于级联时数据的发送 *级联N级,就需要发送N个字节控制HC595 ***/ void HC595_Send_Multi_Byte(uint8_t *data, uint16_t len) { uint8_t i; // len 个字节 for (i = 0; i < len; i ++ ) { HC595_Send_Byte(data[i]); debug_i("leve :%d data:%x",i,data[i]); } HC595_Save(); } /* @brief: 测试函数 */ void _74hc595_test(void) { uint8_t place=0; //级联位置 uint8_t floor=0; //级联层级 uint8_t ele[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; while(1) { uint8_t led_Pos_Buf[_74HC595_LEVEL]; int max_num=_74HC595_LEVEL*8; for (int i=1;i<num+1;i++){ vTaskDelay(300); //延时500毫秒 memset(ele_Pos_Buf,0,_74HC595_LEVEL); floor=(i-1)/8; if(0!=i%8){ place=i%8-1; }else{ place=7; } ele_Pos_Buf[_74HC595_LEVEL-floor-1] = ele[7-place]; debug_w("floor :%d place:%d ",floor+1,place); HC595_Send_Multi_Byte(ele_Pos_Buf,_74HC595_LEVEL);//将当前数据发送到595 } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。