74HC595驱动程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SheepTech/article/details/82697090

文章原始地址:http://feotech.com/?p=44
一. 74HC595芯片介绍
74HC595是串口转并口芯片,可输出三种状态:高电平、低电平和高组态。
一片74HC595芯片可实现3根口线扩展为8根口线.也可采用多片74HC595进行级联的方式扩展输出口线。
这里写图片描述
这里写图片描述
Q0~Q7: 并行数据数据输出端;
GND: 接地引脚;
Q7S: 串行数据输出(多芯片级联时使用);
MR: 复位引脚,当引脚接低电平时芯片内部数据存储寄存器数据清零复位.如不使用一般接高电平;
SHCP: 移位寄存器的时钟输入,当接收到上升沿时移位寄存器内部数据整体后移;
STCP: 数据存储寄存器时钟输入,当检测到上升沿时使能数据存储寄存器,将芯片接收到的数据输出到Q0~Q7 ,Q7S引脚.可以将其理解为锁存信号,当数据发送给芯片完成后对该引脚发送上升沿;
OE: 输出使能引脚,为高电平时芯片输出引脚为高组态,当为低电平时芯片输出引脚为高(低)电平.该引脚可用于同时控制并行输出引脚的电平,如控制LED闪烁等.当不使用该功能时通常接低电平;
DS: 串行数据输入端
VCC: 电源引脚
这里写图片描述
从功能框图中可以看出74HC595含有一个移位寄存器,一个存储寄存器和一个三态输出控制器。
这里写图片描述
这里写图片描述

在使用74HC595设计电路时应注意不同厂家生产的芯片对时钟最高频率和高电平保持时间范围都有不同要求.应查看对应厂家的芯片Data Sheet.本例程中使用的是Nexperia (NXP)所生产的74HCT595。

二. 74HC595硬件设计与74HC595驱动程序

1.单芯片工作模式
这里写图片描述

/**
  ******************************************************************************
  * @file    LED.c
  * @author  Ryan Zhao
  * @version V1.0.0
  * @date    2017-05-03
  * @brief   用于通过驱动芯片74HC595来控制LED.
  ******************************************************************************
  * @attention
  *  注意CPU引脚的频率应在74HC595正常工作所允许的范围.
  ******************************************************************************
**/
/**
* @brief  74HC595 的引脚初始化.
* @param  None.
* @retval None.
*/
void LED595Init(void)
{                
   GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
   //如果74HC595的驱动引脚为JTAG,则将JTAG引脚禁用并配置为通用GPIO引脚.
   //如果驱动引脚为通用GPIO则需要注释掉以下内容
   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//禁止JTAG功能,保留SWD
   GPIO_InitStructure.GPIO_Pin = LED595_DATA_PIN | LED595_LATCH_PIN;     
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     
   GPIO_Init(GPIOB, &GPIO_InitStructure);           
   GPIO_ResetBits(GPIOB,LED595_DATA_PIN | LED595_LATCH_PIN);
   //Data Pin
   GPIO_InitStructure.GPIO_Pin  = LED595_DATA_PIN;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(LED595_DATA_PORT, &GPIO_InitStructure);        
   //Clk Pin
   GPIO_InitStructure.GPIO_Pin  = LED595_CLK_PIN;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(LED595_CLK_PORT, &GPIO_InitStructure);  
   //Latch Pin
   GPIO_InitStructure.GPIO_Pin  = LED595_LATCH_PIN;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(LED595_LATCH_PORT, &GPIO_InitStructure);      
}
/**
  * @brief  将输入的数据输出到74HC595的引脚.
  * @param  Input 1 byte data.
  * @retval None.
**/
void LED595SendData(unsigned char OutData)
{
    unsigned char i; //发送数据时做循环使用临时变量
    for(i=0; i<8; i++) //将8位数据按位发送,先发送高字节后发送低字节
    {
        LED595_CLK_RESET;//时钟线低电平
        if( (OutData & 0x8000) == 0x8000)//判断数据高低位
        {
            LED595_DATA_SET;                   //数据线高电平
        }
        else
        {
             LED595_DATA_RESET;          //数据线低电平
        }
        OutData = OutData << 1;         //数据左移1位
        LED595_CLK_SET;                 //时钟线高电平
    }
    //上升沿输出数据
    LED595_LATCH_RESET;  
    LED595_LATCH_SET;
}
/**
  ******************************************************************************
  * @file    LED595.h
  * @author  Ryan Zhao
  * @version V1.0.0
  * @date    2017-05-03
  * @brief   用于通过驱动芯片74HC595来控制LED.
  ******************************************************************************
  * @attention
  *  注意CPU引脚的切换速度应在74HC595正常工作所允许的范围.
  ******************************************************************************
**/
//74HC595口线定义宏定义.当驱动74HC595引脚改变时,只需更改底层引脚宏定义即可
#define    LED595_DATA_PORT     GPIOB
#define    LED595_DATA_PIN      GPIO_Pin_3
#define    LED595_CLK_PORT      GPIOB
#define    LED595_CLK_PIN       GPIO_Pin_5
#define    LED595_LATCH_PORT    GPIOB
#define    LED595_LATCH_PIN     GPIO_Pin_4
//74HC595口线高低电平宏定义
#define    LED595_DATA_SET      GPIO_SetBits(LED595A_DATA_PORT,LED595A_DATA_PIN)
#define    LED595_DATA_RESET    GPIO_ResetBits(LED595A_DATA_PORT,LED595A_DATA_PIN)
#define    LED595_CLK_SET       GPIO_SetBits(LED595A_CLK_PORT,LED595A_CLK_PIN)
#define    LED595_CLK_RESET     GPIO_ResetBits(LED595A_CLK_PORT,LED595A_CLK_PIN)
#define    LED595_LATCH_SET     GPIO_SetBits(LED595A_LATCH_PORT,LED595A_LATCH_PIN)
#define    LED595_LATCH_RESET   GPIO_ResetBits(LED595A_LATCH_PORT,LED595A_LATCH_PIN)

函数使用

LED595SendData(0xFF); //74HC595输出端全部为高电平,LED全部熄灭
LED595SendData(0x00); //74HC595输出端全部为低电平,LED全部点亮

2.级联工作模式
这里写图片描述

/**
  ******************************************************************************
  * @file    LED.c
  * @author  Ryan Zhao
  * @version V1.1.0
  * @date    2017-06-05
  * @brief   用于通过驱动芯片74HC595来控制LED.
  ******************************************************************************
  * @attention
  *
  *  注意CPU引脚的切换速度应在74HC595正常工作所允许的范围.
  *
  ******************************************************************************
**/
/**
* @brief  74HC595 的引脚初始化.
* @param  None.
* @retval None.
*/
void LED595Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
    //Data Pin
    GPIO_InitStructure.GPIO_Pin = LED595_DATA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED595_DATA_PORT, &GPIO_InitStructure);
    //Clk Pin
    GPIO_InitStructure.GPIO_Pin = LED595_CLK_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED595_CLK_PORT, &GPIO_InitStructure);
    //Latch Pin
    GPIO_InitStructure.GPIO_Pin = LED595_LATCH_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED595_LATCH_PORT, &GPIO_InitStructure);
}

/**
  * @brief  LED显示函数.
  * @param  要显示的数据.
  * @retval None.
**/
void LED595SendData(unsigned int OutData)
{
    unsigned char i; //发送数据时做循环使用临时变量
    for (i = 0; i < 16; i++) //将16位数据按位发送
    {
        LED595_CLK_RESET;  //时钟线低电平
    if ((OutData & 0x8000) == 0x8000) //判断数据高低位
    {
        LED595_DATA_SET; //发送数据高位
    }
    else
    {
        LED595_DATA_RESET; //发送数据低位
    }
    OutData = OutData << 1; //数据左移1位
    LED595_CLK_SET;          //时钟线高电平
    }
    //上升沿输出数据
    LED595_LATCH_RESET;
    LED595_LATCH_SET;
}
/**
  ******************************************************************************
  * @file    LED595.h
  * @author  Ryan Zhao
  * @version V1.1.0
  * @date    2017-05-03
  * @brief   用于通过驱动芯片74HC595来控制LED.
  ******************************************************************************
  * @attention
  *
  *  注意CPU引脚的切换速度应在74HC595正常工作所允许的范围.
  *
  ******************************************************************************
**/

/**********************物理层定义******************************/
//74HC595口线定义宏定义.当驱动74HC595引脚改变时,只需更改底层引脚宏定义即可
#define    LED595_DATA_PORT   GPIOC
#define    LED595_DATA_PIN    GPIO_Pin_5
#define    LED595_CLK_PORT    GPIOB
#define    LED595_CLK_PIN     GPIO_Pin_0
#define    LED595_LATCH_PORT  GPIOB
#define    LED595_LATCH_PIN   GPIO_Pin_1

//74HC595口线高低电平宏定义
#define    LED595_DATA_SET     GPIO_SetBits(LED595_DATA_PORT,LED595_DATA_PIN)
#define    LED595_DATA_RESET   GPIO_ResetBits(LED595_DATA_PORT,LED595_DATA_PIN)
#define    LED595_CLK_SET      GPIO_SetBits(LED595_CLK_PORT,LED595_CLK_PIN)
#define    LED595_CLK_RESET    GPIO_ResetBits(LED595_CLK_PORT,LED595_CLK_PIN)
#define    LED595_LATCH_SET    GPIO_SetBits(LED595_LATCH_PORT,LED595_LATCH_PIN)
#define    LED595_LATCH_RESET  GPIO_ResetBits(LED595_LATCH_PORT,LED595_LATCH_PIN)
#define    LED595_DATA_PORT     GPIOC
#define    LED595_DATA_PIN      GPIO_Pin_5
#define    LED595_CLK_PORT      GPIOB
#define    LED595_CLK_PIN       GPIO_Pin_0
#define    LED595_LATCH_PORT    GPIOB
#define    LED595_LATCH_PIN     GPIO_Pin_1

//74HC595口线高低电平宏定义
#define    LED595_DATA_SET      GPIO_SetBits(LED595_DATA_PORT,LED595_DATA_PIN)
#define    LED595_DATA_RESET    GPIO_ResetBits(LED595_DATA_PORT,LED595_DATA_PIN)
#define    LED595_CLK_SET       GPIO_SetBits(LED595_CLK_PORT,LED595_CLK_PIN)
#define    LED595_CLK_RESET     GPIO_ResetBits(LED595_CLK_PORT,LED595_CLK_PIN)
#define    LED595_LATCH_SET     GPIO_SetBits(LED595_LATCH_PORT,LED595_LATCH_PIN)
#define    LED595_LATCH_RESET   GPIO_ResetBits(LED595_LATCH_PORT,LED595_LATCH_PIN)

函数使用

LED595SendData(0xFFFF); //74HC595输出端全部为高电平,LED全部熄灭
LED595SendData(0x0000);//74HC595输出端全部为低电平,LED全部点亮

猜你喜欢

转载自blog.csdn.net/SheepTech/article/details/82697090