74HC595多组芯片多组级联代码

​自己做了一块74HC595的IO扩展板卡,出于灵活考虑,没有都采用级联的方式,而是2组多芯片级联的结构​。基于STM32平台设计​。

结构示意图

 74HV595内部结构图

头文件:

#ifndef __74HC595_H__
#define __74HC595_H__
​
#include "main.h"
​
typedef struct{
  GPIO_TypeDef* GPIOx;
  uint16_t GPIO_Pin;
}strHC595_Port;
​
//非级联74HC595芯片组数
#define HC595_GROUP_NUMBER  2
​
/* 第一组芯片 */
//使能
#define HC595_OE1_RCC_GPIOX_EN      __HAL_RCC_GPIOA_CLK_ENABLE()
#define HC595_OE1_GPIO          GPIOA
#define HC595_OE1_PIN          GPIO_PIN_4
//锁存
#define HC595_RCLK1_RCC_GPIOX_EN    __HAL_RCC_GPIOA_CLK_ENABLE()
#define HC595_RCLK1_GPIO        GPIOA
#define HC595_RCLK1_PIN          GPIO_PIN_6
//时钟
#define HC595_SRCLK1_RCC_GPIOX_EN    __HAL_RCC_GPIOA_CLK_ENABLE()
#define HC595_SRCLK1_GPIO        GPIOA
#define HC595_SRCLK1_PIN        GPIO_PIN_7
//清除
#define HC595_SRCLR1_RCC_GPIOX_EN    __HAL_RCC_GPIOA_CLK_ENABLE()
#define HC595_SRCLR1_GPIO        GPIOA
#define HC595_SRCLR1_PIN        GPIO_PIN_5
//数据
#define HC595_DATA1_RCC_GPIOX_EN    __HAL_RCC_GPIOC_CLK_ENABLE()
#define HC595_DATA1_GPIO        GPIOC
#define HC595_DATA1_PIN          GPIO_PIN_4
​
​
/* 第二组芯片 */
//使能
#define HC595_OE2_RCC_GPIOX_EN      __HAL_RCC_GPIOA_CLK_ENABLE()
#define HC595_OE2_GPIO          GPIOB
#define HC595_OE2_PIN          GPIO_PIN_3
//锁存
#define HC595_RCLK2_RCC_GPIOX_EN    __HAL_RCC_GPIOB_CLK_ENABLE()
#define HC595_RCLK2_GPIO        GPIOB
#define HC595_RCLK2_PIN          GPIO_PIN_5
//时钟
#define HC595_SRCLK2_RCC_GPIOX_EN    __HAL_RCC_GPIOB_CLK_ENABLE()
#define HC595_SRCLK2_GPIO        GPIOB
#define HC595_SRCLK2_PIN        GPIO_PIN_6
//清除
#define HC595_SRCLR2_RCC_GPIOX_EN    __HAL_RCC_GPIOB_CLK_ENABLE()
#define HC595_SRCLR2_GPIO        GPIOB
#define HC595_SRCLR2_PIN        GPIO_PIN_4
//数据
#define HC595_DATA2_RCC_GPIOX_EN    __HAL_RCC_GPIOB_CLK_ENABLE()
#define HC595_DATA2_GPIO        GPIOB
#define HC595_DATA2_PIN          GPIO_PIN_7
​
extern void HC595_Init(void);
extern uint8_t HC595_write(uint8_t group,uint8_t nbit,uint32_t datas);
​
#endif /*__74HC595_H__*/

源文件:

#include "74HC595.h"
​
strHC595_Port HC595_OE_Port[HC595_GROUP_NUMBER]=
{        
  {HC595_OE1_GPIO,HC595_OE1_PIN},
  {HC595_OE2_GPIO,HC595_OE2_PIN},
  //元素个数与HC595_GROUP_NUMBER对应
};
​
strHC595_Port HC595_RCLK_Port[HC595_GROUP_NUMBER]=
{        
  {HC595_RCLK1_GPIO,HC595_RCLK1_PIN},
  {HC595_RCLK2_GPIO,HC595_RCLK2_PIN},
  //元素个数与HC595_GROUP_NUMBER对应
};
​
strHC595_Port HC595_SRCLK_Port[HC595_GROUP_NUMBER]=
{        
  {HC595_SRCLK1_GPIO,HC595_SRCLK1_PIN},
  {HC595_SRCLK2_GPIO,HC595_SRCLK2_PIN},
  //元素个数与HC595_GROUP_NUMBER对应
};
​
strHC595_Port HC595_SRCLR_Port[HC595_GROUP_NUMBER]=
{        
  {HC595_SRCLR1_GPIO,HC595_SRCLR1_PIN},
  {HC595_SRCLR2_GPIO,HC595_SRCLR2_PIN},
  //元素个数与HC595_GROUP_NUMBER对应
};
​
strHC595_Port HC595_DATA_Port[HC595_GROUP_NUMBER]=
{        
  {HC595_DATA1_GPIO,HC595_DATA1_PIN},
  {HC595_DATA2_GPIO,HC595_DATA2_PIN},
 //元素个数与HC595_GROUP_NUMBER对应
};
//操作接口宏定义
#define HC595_OE_PIN(X)      HC595_OE_Port[X].GPIO_Pin
#define HC595_OE_GPIO(X)    HC595_OE_Port[X].GPIOx  
#define HC595_OE_H(X)      HAL_GPIO_WritePin(HC595_OE_GPIO(X), HC595_OE_PIN(X), GPIO_PIN_SET)
#define HC595_OE_L(X)      HAL_GPIO_WritePin(HC595_OE_GPIO(X), HC595_OE_PIN(X), GPIO_PIN_RESET)
​
#define HC595_RCLK_PIN(X)    HC595_RCLK_Port[X].GPIO_Pin
#define HC595_RCLK_GPIO(X)    HC595_RCLK_Port[X].GPIOx  
#define HC595_RCLK_H(X)      HAL_GPIO_WritePin(HC595_RCLK_GPIO(X), HC595_RCLK_PIN(X), GPIO_PIN_SET)
#define HC595_RCLK_L(X)      HAL_GPIO_WritePin(HC595_RCLK_GPIO(X), HC595_RCLK_PIN(X), GPIO_PIN_RESET)
​
#define HC595_SRCLK_PIN(X)    HC595_SRCLK_Port[X].GPIO_Pin
#define HC595_SRCLK_GPIO(X)    HC595_SRCLK_Port[X].GPIOx  
#define HC595_SRCLK_H(X)    HAL_GPIO_WritePin(HC595_SRCLK_GPIO(X), HC595_SRCLK_PIN(X), GPIO_PIN_SET)
#define HC595_SRCLK_L(X)    HAL_GPIO_WritePin(HC595_SRCLK_GPIO(X), HC595_SRCLK_PIN(X), GPIO_PIN_RESET)
​
#define HC595_SRCLR_PIN(X)    HC595_SRCLR_Port[X].GPIO_Pin
#define HC595_SRCLR_GPIO(X)    HC595_SRCLR_Port[X].GPIOx  
#define HC595_SRCLR_H(X)    HAL_GPIO_WritePin(HC595_SRCLR_GPIO(X), HC595_SRCLR_PIN(X), GPIO_PIN_SET)
#define HC595_SRCLR_L(X)    HAL_GPIO_WritePin(HC595_SRCLR_GPIO(X), HC595_SRCLR_PIN(X), GPIO_PIN_RESET)
​
#define HC595_DATA_PIN(X)    HC595_DATA_Port[X].GPIO_Pin
#define HC595_DATA_GPIO(X)    HC595_DATA_Port[X].GPIOx  
#define HC595_DATA_H(X)      HAL_GPIO_WritePin(HC595_DATA_GPIO(X), HC595_DATA_PIN(X), GPIO_PIN_SET)
#define HC595_DATA_L(X)      HAL_GPIO_WritePin(HC595_DATA_GPIO(X), HC595_DATA_PIN(X), GPIO_PIN_RESET)
​
void HC595_delay_us(uint8_t t_us)
{
  //修改为系统中对应的微秒级延时函数,根据实际需求可以换成更小的ns级延时
  delay_us(t_us);
}
/*
*描述:初始化HC595_GROUP_NUMBER组芯片对应的控制引脚
*/
void HC595_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  uint8_t i = 0;
  
  /* GPIO Ports Clock Enable */
  //第一组芯片引脚时钟
  HC595_OE1_RCC_GPIOX_EN;
  HC595_RCLK1_RCC_GPIOX_EN;
  HC595_SRCLK1_RCC_GPIOX_EN;
  HC595_SRCLR1_RCC_GPIOX_EN;
  HC595_DATA1_RCC_GPIOX_EN;
  //第二组芯片引脚时钟
  HC595_OE2_RCC_GPIOX_EN;
  HC595_RCLK2_RCC_GPIOX_EN;
  HC595_SRCLK2_RCC_GPIOX_EN;
  HC595_SRCLR2_RCC_GPIOX_EN;
  HC595_DATA2_RCC_GPIOX_EN;
  /*Configure GPIO pin */
  for(i=0; i<HC595_GROUP_NUMBER; i++)
  {
    GPIO_InitStruct.Pin = HC595_OE_PIN(i);
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HC595_OE_GPIO(i), &GPIO_InitStruct);
    HC595_OE_L(i);
    
    GPIO_InitStruct.Pin = HC595_RCLK_PIN(i);
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HC595_RCLK_GPIO(i), &GPIO_InitStruct);
    HC595_RCLK_H(i);
    
    GPIO_InitStruct.Pin = HC595_SRCLK_PIN(i);
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HC595_SRCLK_GPIO(i), &GPIO_InitStruct);
    HC595_SRCLK_H(i);
    
    GPIO_InitStruct.Pin = HC595_SRCLR_PIN(i);
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HC595_SRCLR_GPIO(i), &GPIO_InitStruct);
    HC595_SRCLR_H(i);
    
    GPIO_InitStruct.Pin = HC595_DATA_PIN(i);
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HC595_DATA_GPIO(i), &GPIO_InitStruct);
    HC595_DATA_L(i);
  }
}
​
/*
*描述:向第group块HC595芯片写入datas的低nbit位比特
*/
uint8_t HC595_write(uint8_t group,uint8_t nbit,uint32_t datas)
{
  uint16_t i = 0;
  
  if(group >= HC595_GROUP_NUMBER)
  {
    return 0;
  }
  //可以在写入新数据前将原有的状态清空
  //HC595_SRCLR_L(group);
  //HC595_delay_us(1);
  //HC595_SRCLR_H(group);
  
  i++;
  while(i < nbit)
  {
    if(datas & 0x01)
    {
      HC595_DATA_H(group);
    }
    else
    {
      HC595_DATA_L(group);
    }
    datas >>= 1;
    HC595_SRCLK_L(group);
    HC595_delay_us(1);
    HC595_SRCLK_H(group);
    HC595_delay_us(1);
    i++;
  }
  
  HC595_RCLK_L(group);
  HC595_delay_us(1);
  HC595_RCLK_H(group); 
  
  return 1;
}

关注公众号,获取更多硬件知识:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值