74HC595芯片——单芯片控制代码示例

1.关于74HC595

                                                                      

                         

                 芯片示意图                                                                  TSSOP封装

引脚说明

符号

引脚

描述

Q0--Q7

第15脚,第1-7脚

8位并行数据输出

GND

第8脚

Q7’

第9脚

串行数据输出

/MR

第10脚

主复位(低电平有效)

SH_CP

第11脚

数据输入时钟线

ST_CP

第12脚

输出存储器锁存时钟线

/OE

第13脚

输出有效(低电平有效)

DS

第14脚

串行数据输入

VCC

第16脚

电源

2.关于此芯片具体原理参考:

快速上手移位寄存器74HC595,并使用ATTiny13A的三个IO口驱动数码管【IC原来如此】 

3.代码示例

       关于芯片,我们关注的是SH、ST、DS引脚。所以代码主要从从这3个引脚的控制入手。

代码流程:一个字节(8个位)的数据写入BUFF数组→将数组的数据写入芯片缓存区→全部写入后发送到引脚→将BUFF数组全部清零→循环上述步骤

/*    编程平台:keil 5
      编程芯片:STC15W204S (89C51同样适用) 
*/

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;

sbit ST=P3^0;     //引脚映射
sbit SH=P3^1;
sbit DS=P3^2 ;

#define SH_L SH=0  //宏定义引脚高低电平
#define SH_H SH=1
#define ST_L ST=0
#define ST_H ST=1
#define DS_L DS=0
#define DS_H DS=1
/*ST_L  为ST引脚电平置低  
  ST_H  为ST引脚电平置高,DS_L/DS_L/SH_L/SH_H 同理  */

u8 BUFF[8] = {0};  //用于缓存发送数据的数组,一个595芯片一次可发送8个位

void Delay(u16 num);
void HC595_Init();
void HC595_Clear();
void HC595_control(u8 A);
void HC595_Sent(u8 BUFF[8]);
void DS_H_Sent();
void DS_L_Sent();



void Delay(u16 num)  //ms延时   @晶振35M
{
    unsigned char k, j;
    u16 n;
    for (n = 0; n < num; n++)
    {        
        k = 33;
        j = 66;
        do
        {
            while (--j)
                ;
        } while (--k);
    }
}

void HC595_Init()  //ST引脚一个上升沿将数据发送到引脚上,初始化将ST引脚模拟一个上升沿,                                   
                   //将原有数据发送出去  
{
    ST_L;            //ST引脚拉低
    Delay(10);    
    ST_H;             //ST引脚拉高,完成一个上升沿操作
    Delay(10);
    ST_L;            //之后将3个引脚全部拉低
    SH_L;
    DS_L;
    Delay(10);
}
void HC595_Clear()  //BUFF数组全部位清零
{
    u8 k;
    for (k = 0; k < 8; k++)
    {
        BUFF[k] = 0;
    }
}
void HC595_control(u8 A)    //将要发送的数据写入BUFF数组
{


    for (i = 0; i < 8; i++) 
    {
        if (A & 0x80)             //0X80==1000 0000  数据最高位和1相与
            BUFF[i] =1;           //最高位是1则写1进BUFF数组,若为0,因BUFF数组
                                  //本身开始时全部置零,故不用处理

        A <<= 1;                   //数据左移一位
    }
                                   //整个for循环完成了一个8位数据从高位到低位写入BUFF数组
  HC595_Sent(BUFF);                // 该函数如下↓↓↓
}


void HC595_Sent(u8 BUFF[8])   //将BUFF数组的数据写入芯片缓存区,发送完8位后,ST引脚完成一次上 
                              //升沿操作,将芯片内部缓存区的数据发送到对应引脚上面
{
    for (i = 0; i < 8; i++)
    {
        if (BUFF[7 - i] == 1)       
             DS_H_Sent( );
        else DS_L_Sent( ); 
    }

    ST_L;                //ST引脚的上升沿操作
    Delay(1);
    ST_H;
   HC595_Clear();       //完成一个字节数据发送后将BUFF数组清零
}
//以下2个函数完成了将数据发送到缓存区的操作
//数据位为1,则DS置1,然后SH引脚完成一个上升沿操作即可将数据位发送到内部缓存区
void DS_H_Sent()
{
    DS_H;
    SH_L;
    Delay(1);
    SH_H;
}
//数据位为0,则DS置0,然后SH引脚完成一个上升沿操作即可将数据位发送到内部缓存区
void DS_L_Sent()
{
    DS_L;
    SH_L;
    Delay(1);
    SH_H;
}


void main()
{
  HC595_Init() ;
  HC595_control(0x30);
}



注:上述代码需自行整理可用

调用函数HC595_control(u8 A)  即可完成芯片的控制

语句  HC595_control(0x30);达成的效果   

CH595引脚对应电平
Q0Q1Q2Q3Q4Q5Q6Q7
00110000

可见,与0X30二进制展开  0b 0011 000 一一对应

<< 要为74HC595驱动的数码管编写C语言程序,我们首先需要了解其基本操作原理: ### 原理概述: 1. **74HC595** 是一种8位串行输入/并行输出移位寄存器芯片。 - 数据通过 `DS`(数据引脚)一位一位地传入。 - 使用时钟信号 `SH_CP` 控制数据传输速度。 - 最后使用存储寄存器锁存信号 `ST_CP` 将数据从内部缓冲区转移到输出。 2. 对于 74HC595M/TR 和普通 74HC595 的区别主要在于封装和电气特性上,功能本质上没有差别。因此两者的控制逻辑相同。 下面是两个例子:一个是显示数字“0”到“F”的简单示例程序;另一个是对多个数码管进行动态扫描显示。 --- #### 单个数码管显示字符 'A' 示例 ```c #include <stdio.h> #include <stdint.h> #define DS_PIN (1 << 0) // 模拟连接到微控制器上的实际引脚定义, 如 GPIO PA0 #define SHCP_PIN (1 << 1) #define STCP_PIN (1 << 2) // 宏用于模拟设置或清除指定GPIO状态 void digitalWrite(uint8_t pin, uint8_t value){ if(value){ printf("Set Pin %d HIGH\n", __builtin_ctz(pin)); } else { printf("Set Pin %d LOW\n", __builtin_ctz(pin)); } } // 移位发送函数 void shiftOut(uint8_t dataPin,uint8_t clockPin,unsigned char val){ for(int i=0;i<8;i++) { // 发送8bit数据 digitalWrite(clockPin,LOW); // 先拉低时钟线 digitalWrite(dataPin,(val & (1 <<(7-i)) ) ? HIGH : LOW ); // 设置当前位值 digitalWrite(clockPin,HIGH); // 上升沿触发数据写入 } } // 数码管段选表(A-G+小数点), 注意顺序与具体硬件有关 const unsigned char SEGMENT_CODE[] = { 0xC0,'1'=0xF9,'2'=0xA4,'3'=0xB0, '4'=0x99,'5'=0x92,'6'=0x82,'7'=0xF8, '8'=0x80,'9'=0x90,'A'=0x88,'b'=0x83, 'C'=0xC6,'d'=0xA1,'E'=0x86,'F'=0x8E}; int main(void){ unsigned char digit='A'; shiftOut(DS_PIN , SHCP_PIN ,SEGMENT_CODE[digit-'0']); // 显示 A 字符对应编码 digitalWrite(STCP_PIN,HIGH); return 0; } ``` 上述代码展示了一个简单的单片机如何通过软件方式将‘A’传递给74hc595,并点亮相应模式下的LED灯组构成字母形状“A”。 --- #### 动态扫描多位数码管示例 当您想用同一个74HC595驱动多个数码管时,则需采用快速切换的方式来产生视觉暂留效果——即所谓的"动态刷新技术" 这里假设已经正确连线了四个共阴极型七段数码显示器并与单一SPI接口相连: ```c unsigned int digits[4] = {'1','2','3','4'}; uint8_t segment_codes[]={...}; // 同前略... void refreshDisplay(){ static int index=0; while(index<4){ shiftOut(DS_PIN,SHCP_PIN,digits[index]); selectDigit(index++); // 只打开某个特定位置的公共端口电平使能该显示屏 delayMicroseconds(2000); } index=0; // 循环回滚开始下一轮刷新周期 } ``` 请注意以上伪代码片段中的细节可能因具体的MCU平台而异。 --- ### 解释: - 在第一个示例中,我们直接调用了`shiftOut()` 函数来传送一个字节的数据至74HC595 中控单元然后激活它以便更新所有链接好的发光二极管(LED). - 第二种情况涉及到更复杂的计时机制确保每个单独的部分都能按照预期呈现出来同时又不影响其他部分的状态变化频率太快导致闪烁现象发生. 如果您正在寻找更加精确的时间管理方案建议考虑硬实时操作系统RTOS支持的任务调度模型或者利用外部中断服务例程ISR 来完成同步任务处理过程.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式创客工坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值