以下为.h文件:
#ifndef __74HC595_H__
#define __74HC595_H__
#include "stm32f10x.h"
#define SHCP_GPIO_PORT GPIOA
#define SHCP_GPIO_CLK RCC_APB2Periph_GPIOA
#define SHCP_GPIO_PIN GPIO_Pin_1
#define STCP_GPIO_PORT GPIOA
#define STCP_GPIO_CLK RCC_APB2Periph_GPIOA
#define STCP_GPIO_PIN GPIO_Pin_0
#define DS_GPIO_PORT GPIOB
#define DS_GPIO_CLK RCC_APB2Periph_GPIOB
#define DS_GPIO_PIN GPIO_Pin_1
#define HC595_SHCP_Low() GPIO_ResetBits( SHCP_GPIO_PORT, SHCP_GPIO_PIN )
#define HC595_SHCP_High() GPIO_SetBits( SHCP_GPIO_PORT, SHCP_GPIO_PIN )
#define HC595_STCP_Low() GPIO_ResetBits( STCP_GPIO_PORT, STCP_GPIO_PIN )
#define HC595_STCP_High() GPIO_SetBits( STCP_GPIO_PORT, STCP_GPIO_PIN )
#define HC595_Data_Low() GPIO_ResetBits( DS_GPIO_PORT, DS_GPIO_PIN )
#define HC595_Data_High() GPIO_SetBits( DS_GPIO_PORT, DS_GPIO_PIN )
void HC595_GPIO_Config(void);
void HC595_Send_Byte(u8 byte);
void HC595_CS(void);
void HC595_Send_Multi_Byte(u8 *data, u16 len);
#endif
以下为.c文件:
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "74HC595.h"
void delay(uint16_t t);
/******** 74HC595 GPIO 配置 *************************/
void HC595_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( SHCP_GPIO_CLK | STCP_GPIO_CLK | DS_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SHCP_GPIO_PIN;
GPIO_Init(SHCP_GPIO_PORT, &GPIO_InitStructure); // 初始化 SHCP 引脚
GPIO_InitStructure.GPIO_Pin = STCP_GPIO_PIN;
GPIO_Init(STCP_GPIO_PORT, &GPIO_InitStructure); // 初始化 STCP 引脚
GPIO_InitStructure.GPIO_Pin = DS_GPIO_PIN;
GPIO_Init(DS_GPIO_PORT, &GPIO_InitStructure); // 初始化 DS 引脚
GPIO_ResetBits(SHCP_GPIO_PORT, SHCP_GPIO_PIN); // 引脚初始状态为高,便于产生上升沿
GPIO_ResetBits(STCP_GPIO_PORT, STCP_GPIO_PIN);
GPIO_ResetBits(DS_GPIO_PORT, DS_GPIO_PIN);
}
/***
*74HC595 发送一个字节
*即往74HC595的DS引脚发送一个字节
*/
void HC595_Send_Byte(u8 byte)
{
u8 i;
for (i = 0; i < 8; i ++) //一个字节8位,传输8次,一次一位,循环8次,刚好移完8位
{
/**** 步骤1:将数据传到DS引脚 ****/
if (byte & 0x80) //先传输高位,通过与运算判断第八是否为1
HC595_Data_High(); //如果第八位是1,则与 595 DS连接的引脚输出高电平
else //否则输出低电平
HC595_Data_Low();
/*** 步骤2:SHCP每产生一个上升沿,当前的bit就被送入移位寄存器 ***/
HC595_SHCP_Low(); // SHCP拉低
delay(1); // 适当延时
HC595_SHCP_High(); // SHCP拉高, SHCP产生上升沿
delay(1);
byte <<= 1; // 左移一位,将低位往高位移,通过 if (byte & 0x80)判断低位是否为1
}
}
/**
*74HC595输出锁存 使能
**/
void HC595_CS(void)
{
/** 步骤3:STCP产生一个上升沿,移位寄存器的数据移入存储寄存器 **/
HC595_STCP_Low(); // 将STCP拉低
delay(1); // 适当延时
HC595_STCP_High(); // 再将STCP拉高,STCP即可产生一个上升沿
delay(1);
}
/**
*发送多个字节
*便于级联时数据的发送
*级联N级,就需要发送N个字节控制HC595
***/
void HC595_Send_Multi_Byte(u8 *data, u16 len)
{
u8 i;
for (i = 0; i < len; i ++ ) // len 个字节
{
HC595_Send_Byte(data[i]);
}
HC595_CS(); //先把所有字节发送完,再使能输出
}
void delay(uint16_t t)
{
for (; t != 0; t --);
}
关于HC595_Send_Multi_Byte函数的使用要根据实际的硬件情况来,以下为一个例子,可以参考一下:
程序中的相关数据:
u8 Led_Buf[2] = {0xff, 0xff}; //存储要发送的指令字节,也就是灯的状态 Led_Buf[0]控制灯6-10;Led_Buf[1]控制灯1-5
u8 Led_All_Off[2] = {0xff, 0xff}; //LED灯全灭
u8 Led_All_On[2] = {0x00, 0x00}; //LED灯全亮
HC595_Send_Multi_Byte(Led_All_On,2);//10路灯全开
HC595_Send_Multi_Byte(Led_All_Off,2);//10路灯全关
实现流水灯效果:
/******************************************************
*流水灯程序
*******************************************************/
void LED_ShowOneToOne(void)
{
u8 pos; // led位置
u8 Led_Show[2] = {0xff, 0xff}; //存储要发送的指令字节, Led_Show[0]控制灯6-10; Led_Show[1]控制灯1-5
//第X个led亮 :1 2 3 4 5
u8 Waterfall_Led[20] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, //控制第一级74HC595
0xff, 0xff, 0xff, 0xff, 0xff,
//第X个led亮 :6 7 8 9 10
0xff, 0xff, 0xff, 0xff, 0xff, //控制第二级74HC595
0xfe, 0xfd, 0xfb, 0xf7, 0xef };
for (pos = 0; pos < 10; pos ++) //第pos个灯,实现流水灯效果
{
Led_Show[1] = Waterfall_Led[pos]; //存放第一级74HC595数据,因为先进先出,所以第一级放在Led_Pos_Buf[1],而不是Led_Pos_Buf[0]
Led_Show[0] = Waterfall_Led[pos+10]; //存放第二级74HC595的数据
HC595_Send_Multi_Byte(Led_Show,2); //将当前数据发送到595
delay_ms(500);
}
}
上一篇:STM32 TM1640芯片驱动程序
下一篇:STM32 MFRC522 IC读卡 程序及原理图
推荐阅读
史海拾趣
Emmoco公司成立于XXXX年,由一群富有远见和创新精神的电子工程师创立。公司自创立之初就明确了以技术创新为核心的发展道路,专注于研发高性能的电子元器件和模块。经过初期的不懈努力,Emmoco成功推出了一系列具有竞争力的产品,为公司的后续发展奠定了坚实的基础。
随着全球汽车产业的不断发展,国际合作已成为企业拓展市场、提升竞争力的重要途径。菲斯克也深刻认识到了这一点,积极寻求与全球各地的汽车制造商和供应商建立合作关系。通过与国际巨头的合作,菲斯克不仅获得了先进的技术和管理经验,还成功进入了多个国际市场,实现了全球布局的目标。这一系列的国际合作不仅提升了公司的知名度和影响力,还为公司的长期发展提供了有力的支持。
随着市场竞争的加剧,CMDS意识到仅仅依靠技术创新是不够的,还需要提供差异化的服务。于是,公司推出了定制化MMIC设计服务,根据客户的具体需求和应用场景,量身定制解决方案。这种服务模式不仅提高了客户满意度,也增强了CMDS的市场竞争力。通过不断优化服务流程和提高设计质量,CMDS逐渐在定制化服务市场上树立了良好的口碑。
Analog Power公司成立于XXXX年,创立初期主要专注于电源管理解决方案的研发。面对当时竞争激烈的市场环境,公司创始人凭借对电源管理技术的深刻理解和坚定信念,带领团队克服了种种困难,逐步在市场中找到了自己的定位。他们深入研究客户需求,不断优化产品设计,逐渐赢得了客户的信任和认可。
品质是电子行业的生命线,BCD Semi公司深知这一点。因此,公司始终将品质管理放在首位,建立了完善的品质管理体系和质量控制流程。公司从原材料采购、生产制造到产品出厂,每一个环节都进行严格的质量把控,确保产品的高品质和稳定性。同时,BCD Semi还不断引进先进的生产设备和技术,优化生产流程,提高生产效率,为客户提供更优质的产品和服务。
AD574A是美国模拟数字公司(Analog)推出的单片高速12位逐次比较型A/D转换器,内置双极性电路构成的混合集成转换显片,具有外接元件少,功耗低,精度高等特点,并且具有自动校零和自动极性转换功能,只需外接少量的阻容件即可构成一个完整的A/D ...… 查看全部问答∨ |
|
小弟请教各位一个问题: 在GSM或者EVDO模块在焊接到手机电路板上之前,据说需要经过一个板级测试,目的是保证线路正常以及GSM/EVDO模块的基本功能及性能是正常的。 据说这种板级测试是有行业标准的,不知各位有没有 ...… 查看全部问答∨ |
按钮事件 void CleakerDlg::OnBnClickedButton1() { HANDLE a = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadData, NULL, 0, NULL); } 线程函数 void WINAPI ...… 查看全部问答∨ |
home screen plugin如何部署到device上? WM5,开发了一个home screen的plugin,生成了dll文件,我应该如何部署到device上呢? 在PPC上的today screen可以进行注册表修改,将plugin部署进去。 那么sp的home screen应该怎么做呢?… 查看全部问答∨ |
|
大哥大姐们好~! 我在EVC中,想用CreateThread()这个函数创建一个线程。我程序是这样字写的 hReadThread = CreateThread(0,0,ReadThread,this,0,&m_dwReadThreadID); 其中,hReadThread是HANDLE类 ...… 查看全部问答∨ |
|
基于STM32的噪声监测分析仪,大致过程是这样的:噪声信号通过电容式话筒被采集,经过一步放大,再经AD转换就成为电信号,通过FFT就可以实现分析。只知道这些,不知道电容式话筒怎样和ARM板子联系,都需要什么工作,尽量具体点,新手,求各位大侠指 ...… 查看全部问答∨ |