打印
[其他]

单片机 MM32 HAL 74hc595 例子 代码

[复制链接]
421|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这是74HC595芯片,如图1,它是一颗单片机IO口扩展芯片,使用它,我们可以很容易的将单片机的3个输出引脚扩展为8个。

这颗芯片通过串行数据输入,数据输出的方式为1路串行或8路并行。引脚有三种输出状态:高电平、低电平和高阻态。它的引脚驱动能力为35mA,

使用特权

评论回复
沙发
kmnqhaha|  楼主 | 2023-6-28 15:11 | 只看该作者
二、引脚图



14脚:DS(SER),串行数据输入引脚

13脚:OE, 输出使能控制脚,它是低电才使能输出,所以接GND

12脚:RCK,存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。

11脚:SCK,移位寄存器时钟引脚,上升沿时,移位寄存器中的bit 数据整体后移,并接受新的bit(从SER输入)。

10脚:MR,低电平时,清空移位寄存器中已有的bit数据,一般不用,接 高电平即可。

9 脚 :串行数据出口引脚。当移位寄存器中的数据多于8bit时,会把已有的bit“挤出去”,就是从这里出去的。用于595的级联。

Qx:并行输出引脚

使用特权

评论回复
板凳
kmnqhaha|  楼主 | 2023-6-28 15:12 | 只看该作者


使用特权

评论回复
地板
kmnqhaha|  楼主 | 2023-6-28 15:13 | 只看该作者
具体使用的步骤:
第一步:目的:将要准备输入的位数据移入74HC595数据输入端上。

方法:送位数据到_595。

第二步:目的:将位数据逐位移入74HC595,即数据串入

方法:SCK_595产生一上升沿,将PSI_595上的数据移入74HC595中.从低到高

第三步:目的:并行输出数据。即数据并出

方法:P1.1产生一上升沿,将由SI_595上已移入数据寄存器中的数据

送入到输出锁存器。

使用特权

评论回复
5
kmnqhaha|  楼主 | 2023-6-28 15:13 | 只看该作者
说明: 从上可分析:从SCK_595产生一上升沿(移入数据)和RCK_595产生一上升沿(输出数据)是二个独立过程,实际应用时互不干扰。即可输出数据的 同时移入数据。
#include "74hc595.h"

/******************
功  能:定义HC595的功能引脚
备  注:变更引脚,由MX配置完成
*******************/
const T_HC595_PIN hc595 =
{
    .sck_port   = HC595_SCK_GPIO_Port,
    .sck_pin    = HC595_SCK_Pin,      //数据输入时钟线

    .data_port  = HC595_SI_GPIO_Port,
    .data_pin   = HC595_SI_Pin,       //数据线

    .rck_port   = HC595_RCK_GPIO_Port,
    .rck_pin    = HC595_RCK_Pin,      //输出存储器锁存时钟线

    .en_port    = HC595_EN_GPIO_Port,
    .en_pin     = HC595_EN_Pin        //芯片使能
};

/******************
函数名:hc595Delay
功  能:实现us级延迟
形  参:cnt--us值
返回值:无
备  注:
*******************/
void hc595Delay(uint16_t cnt)
{
    while (--cnt);
}

/******************************
函数名:hc595Init
功  能:初始化hc595的使能脚(EN),默认工作状态
形  参:pin--hc595引脚结构体
返回值:
备  注:0--器件屏蔽  1--器件工作
*******************************/
void hc595Init(const T_HC595_PIN *pin)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin   =  GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  =  GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   =  GPIO_Pin_4 | GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  =  GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
}

/******************************
函数名:hc595DeInit
功  能:初始化hc595的使能脚(EN),默认休息状态
形  参:pin--hc595引脚结构体
返回值:
备  注:0--器件屏蔽  1--器件工作
*******************************/
void hc595DeInit(const T_HC595_PIN *pin)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);
}






/***************************************下面是对LED的应用*****************************************************/



/*********************************************
函数名:hc595LedOff
功  能:关闭全部LED
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
void hc595LedOff(const T_HC595_PIN *pin)
{
    hc595WriteData(pin, 0x00);
}
/*********************************************
函数名:hc595LedOn
功  能:开灯全部LED
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
void hc595LedOn(const T_HC595_PIN *pin)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    hc595WriteData(pin, 0xff);
}

/*********************************************
函数名:hc595WriteData
功  能:对hc595器件写入1字节,代表8个io口的输出状态
形  参:pin--hc595引脚结构体  pdata--数据字节
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
void hc595WriteData(const T_HC595_PIN *pin, uint8_t pdata)
{
    uint8_t i = 0;
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    for (i = 0; i < 8; i++)
    {
        if ((pdata << i) & 0x80)
        {
            GPIO_WriteBit(pin->data_port, pin->data_pin, Bit_SET);//HC595_SI=1
        }
        else
        {
            GPIO_WriteBit(pin->data_port, pin->data_pin, Bit_RESET);//HC595_SI=0
        }
        hc595Delay(1);
        GPIO_WriteBit(pin->sck_port, pin->sck_pin, Bit_RESET);//HC595_sck=0
        GPIO_WriteBit(pin->sck_port, pin->sck_pin, Bit_SET);//HC595_sck=1
    }
    hc595Delay(1);
    GPIO_WriteBit(pin->rck_port, pin->rck_pin, Bit_RESET);//HC595_rck=0
    GPIO_WriteBit(pin->rck_port, pin->rck_pin, Bit_SET);//HC595_rck=1
    hc595Delay(1);
    GPIO_WriteBit(pin->rck_port, pin->rck_pin, Bit_RESET);//HC595_rck=0
}



/*********************************************
函数名:LED_AnnularPipelineLamp
功  能:LED环形流水灯,0->7顺时针  7->0逆时针
形  参:pin--hc595引脚结构体  ch--通道
返回值:
备  注:8个led灯连接到HC595器件
作  者:薛建强
时  间:2019/06/22
**********************************************/
void LED_AnnularPipelineLamp(const T_HC595_PIN *pin, uint8_t ch)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    switch (ch)
    {
        case 0:
            hc595WriteData(pin, 0xF8);
            break;
        case 1:
            hc595WriteData(pin, 0xF1);
            break;
        case 2:
            hc595WriteData(pin, 0xE3);
            break;
        case 3:
            hc595WriteData(pin, 0xC7);
            break;
        case 4:
            hc595WriteData(pin, 0x8F);
            break;
        case 5:
            hc595WriteData(pin, 0x1F);
            break;
        case 6:
            hc595WriteData(pin, 0x3E);
            break;
        case 7:
            hc595WriteData(pin, 0x7C);
            break;
        default:
            break;
    }
}

/*********************************************
函数名:LED_AnnularPipelineLamp_3
功  能:LED环形流水灯,0->7顺时针  7->0逆时针  3个灯流水
形  参:pin--hc595引脚结构体  ch--通道
返回值:
备  注:8个led灯连接到HC595器件
作  者:薛建强
时  间:2019/06/22
**********************************************/
void LED_AnnularPipelineLamp_3(const T_HC595_PIN *pin, uint8_t ch)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    switch (ch)
    {
//        case 0:
//            hc595WriteData(pin, 0x07);
//            break;
//        case 1:
//            hc595WriteData(pin, 0x0E);
//            break;
//        case 2:
//            hc595WriteData(pin, 0x1C);
//            break;
//        case 3:
//            hc595WriteData(pin, 0x38);
//            break;
//        case 4:
//            hc595WriteData(pin, 0x70);
//            break;
//        case 5:
//            hc595WriteData(pin, 0xE0);
//            break;
//        case 6:
//            hc595WriteData(pin, 0xC1);
//            break;
//        case 7:
//            hc595WriteData(pin, 0x83);
//            break;
        case 0:
            hc595WriteData(pin, 0x03);
            break;
        case 1:
            hc595WriteData(pin, 0x06);
            break;
        case 2:
            hc595WriteData(pin, 0x0C);
            break;
        case 3:
            hc595WriteData(pin, 0x18);
            break;
        case 4:
            hc595WriteData(pin, 0x30);
            break;
        case 5:
            hc595WriteData(pin, 0x60);
            break;
        case 6:
            hc595WriteData(pin, 0x81);
            break;
//        case 7:
//            hc595WriteData(pin, 0x03);
//            break;
        default:
            break;
    }
}

/*********************************************
函数名:LED_TwowayDescent
功  能:双路流水灯
形  参:pin--hc595引脚结构体  ch--通道
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
void LED_TwowayDescent(const T_HC595_PIN *pin, uint8_t ch)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    switch (ch)
    {
        case 0:
            hc595WriteData(pin, 0x01);
            break;
        case 1:
            hc595WriteData(pin, 0x82);
            break;
        case 2:
            hc595WriteData(pin, 0x44);
            break;
        case 3:
            hc595WriteData(pin, 0x28);
            break;
        case 4:
            hc595WriteData(pin, 0x10);
            break;
        default:
            break;
    }
}

/*********************************************
函数名:LED_CyclicMode
功  能:DV循环模式下的效果
形  参:pin--hc595引脚结构体  ch--通道
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
void LED_CyclicMode(const T_HC595_PIN *pin, const uint8_t ch)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    switch (ch)
    {
        //  第一圈
        case  0:
            hc595WriteData(pin, 0xFE);
            break;
        case  1:
            hc595WriteData(pin, 0xFC);
            break;
        case  2:
            hc595WriteData(pin, 0xF8);
            break;
        case  3:
            hc595WriteData(pin, 0xF0);
            break;
        case  4:
            hc595WriteData(pin, 0xE0);
            break;
        case  5:
            hc595WriteData(pin, 0xC0);
            break;
        case  6:
            hc595WriteData(pin, 0x80);
            break;
        case  7:
            hc595WriteData(pin, 0x00);
            break;
        //  第二圈
        case  8:
            hc595WriteData(pin, 0x01);
            break;
        case  9:
            hc595WriteData(pin, 0x03);
            break;
        case 10:
            hc595WriteData(pin, 0x07);
            break;
        case 11:
            hc595WriteData(pin, 0x0F);
            break;
        case 12:
            hc595WriteData(pin, 0x1F);
            break;
        case 13:
            hc595WriteData(pin, 0x3F);
            break;
        case 14:
            hc595WriteData(pin, 0x7F);
            break;
        case 15:
            hc595WriteData(pin, 0xFF);
            break;
        default:
            break;
    }
}


/*********************************************
函数名:Batter_EleShow
功  能:电量显示
形  参:pin--hc595引脚结构体  Batter--电量的百分比
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
uint8_t  LedFlash_Tmr = 0;
void Batter_EleShow(const T_HC595_PIN *pin, const uint8_t Batter)
{
    GPIO_WriteBit(pin->en_port, pin->en_pin, Bit_SET);//打开使能脚
    if (Batter < 12)                //   1格
    {
        if (Batter <= 10)            //   低电量提示,蜂鸣器开启
        {
            if (LedFlash_Tmr < 250 &&  ++LedFlash_Tmr < 2) //   指示灯闪烁
            {
                hc595WriteData(pin, 0x01);
            }
            else if (LedFlash_Tmr >= 2 && LedFlash_Tmr < 3)
            {
                hc595WriteData(pin, 0x00);
            }
            else
            {
                LedFlash_Tmr = 0;
            }
        }
        else // 5% ~ 12% 显示最后一格电量
        {
            LedFlash_Tmr = 0;
            hc595WriteData(pin, 0x01);
        }
    }
    else if (Batter >= 12 && Batter < 24) // 2格
    {
        hc595WriteData(pin, 0x03);
    }
    else if (Batter >= 24 && Batter < 36) // 3格
    {
        hc595WriteData(pin, 0x07);
    }
    else if (Batter >= 36 && Batter < 48) // 4格
    {
        hc595WriteData(pin, 0x0F);
    }
    else if (Batter >= 48 && Batter < 60) // 5格
    {
        hc595WriteData(pin, 0x1F);
    }
    else if (Batter >= 60 && Batter < 72) // 6格
    {
        hc595WriteData(pin, 0x3F);
    }
    else if (Batter >= 72 && Batter < 84) // 7格
    {
        hc595WriteData(pin, 0x7F);
    }
    else                                 // 8格
    {
        hc595WriteData(pin, 0xFF);
    }
}


/*********************************************
函数名:Batter_ChargeShow
功  能:电池充电显示
形  参:pin--hc595引脚结构体  Batter--电量的百分比
返回值:
备  注:
作  者:薛建强
时  间:2019/06/22
**********************************************/
#define ChargeValue 3    // 充电时间值
uint8_t  time = 0;      // 充电指示电路
void Batter_ChargeShow(const T_HC595_PIN *pin, const uint8_t Batter)
{
    if (Batter < 12)                             //    1格
    {
        if (time < 250 && ++time < ChargeValue)
        {
            hc595WriteData(pin, 0x00);
        }
        else if (time >= ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x01);
        }
        else
        {
            time = 0;
        }
    }
    else if (Batter >= 12 && Batter < 24)       //    2格
    {
        if (time < 250 && ++time <= ChargeValue)
        {
            hc595WriteData(pin, 0x01);
        }
        else if (time > ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x03);
        }
        else
        {
            time = 0;
        }
    }
    else if (Batter >= 24 && Batter < 36)     //    3格
    {
        if (time < 250 && ++time <= ChargeValue)
        {
            hc595WriteData(pin, 0x03);
        }
        else if (time > ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x07);
        }
        else
        {
            time = 0;
        }
    }
    else if (Batter >= 36 && Batter < 48)                        //    4格
    {
        if (time < 250 && ++time <= ChargeValue)
        {
            hc595WriteData(pin, 0x07);
        }
        else if (time > ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x0F);
        }
        else
        {
            time = 0;
        }
    }
    else if (Batter >= 48 && Batter < 60)                         //    5格
    {
        if (time < 250 && ++time <= ChargeValue)
        {
            hc595WriteData(pin, 0x0F);
        }
        else if (time > ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x1F);
        }
        else
        {
            time = 0;
        }
    }
    else if (Batter >= 60 && Batter < 72)                         //    6格
    {
        if (time < 250 && ++time <= ChargeValue)
        {
            hc595WriteData(pin, 0x1F);
        }
        else if (time > ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x3F);
        }
        else
        {
            time = 0;
        }
    }
    else if (Batter >= 72 && Batter < 95)                       //    7格
    {
        if (time < 250 &&  ++time < ChargeValue)
        {
            hc595WriteData(pin, 0xFF);
        }
        else if (time >= ChargeValue && time < 2 * ChargeValue)
        {
            hc595WriteData(pin, 0x7F);
        }
        else
        {
            time = 0;
        }
    }
    else                                                       //     8格
    {
        time = 0;
        hc595WriteData(pin, 0xFF);
    }
}



使用特权

评论回复
6
kmnqhaha|  楼主 | 2023-6-28 15:14 | 只看该作者
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __74HC595_HEADER__
#define __74HC595_HEADER__


/* USER CODE BEGIN Includes */
#include "main.h"

/* USER CODE END Includes */

#define HC595_SCK_Pin       GPIO_Pin_1
#define HC595_SCK_GPIO_Port GPIOB
#define HC595_RCK_Pin       GPIO_Pin_2
#define HC595_RCK_GPIO_Port GPIOB
#define HC595_SI_Pin        GPIO_Pin_8
#define HC595_SI_GPIO_Port  GPIOA
#define HC595_EN_Pin        GPIO_Pin_4
#define HC595_EN_GPIO_Port  GPIOA


typedef struct
{
    GPIO_TypeDef* sck_port;
    uint16_t      sck_pin;
    GPIO_TypeDef* data_port;
    uint16_t      data_pin;
    GPIO_TypeDef* rck_port;
    uint16_t      rck_pin;
    GPIO_TypeDef* en_port;
    uint16_t      en_pin;
} T_HC595_PIN;

extern const T_HC595_PIN hc595;

/* Exported functions prototypes ---------------------------------------------*/
void hc595Init(const T_HC595_PIN *pin);
void hc595DeInit(const T_HC595_PIN *pin);
void hc595WriteData(const T_HC595_PIN *pin, uint8_t pdata);


/*流水灯的应用*/
void hc595LedOn(const T_HC595_PIN *pin);
void hc595LedOff(const T_HC595_PIN *pin);
void LED_AnnularPipelineLamp(const T_HC595_PIN *pin,uint8_t ch);
void LED_TwowayDescent(const T_HC595_PIN *pin, uint8_t ch);
void LED_CyclicMode(const T_HC595_PIN *pin, const uint8_t ch);

void Batter_EleShow(const T_HC595_PIN *pin, const uint8_t Batter);
void Batter_ChargeShow(const T_HC595_PIN *pin, const uint8_t Batter);
void LED_AnnularPipelineLamp_3(const T_HC595_PIN *pin, uint8_t ch);


void hc595Delay(uint16_t cnt);
#endif

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

198

帖子

1

粉丝