小学生
最后登录1970-1-1
在线时间 小时
注册时间2025-7-3
|
本帖最后由 lyf123 于 2025-7-3 15:39 编辑
使用Proteus仿真,用STM32和74HC595级联控制64个LED,形成特定图案。while循环中,(1)如果使用自动切换模式,则6幅图案可正常切换;(2)如果使用按键切换时,前3幅图案正常切换,第4至第6幅图案则异常。相关代码,原理图及按键切换的6幅图案如下:
1、按键代码Key.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
/**
* 函 数:按键初始化
* 参 数:无
* 返 回 值:无
*/
void Key_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*获取键码函数*/
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0; //定义变量,默认键码值为0
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
Delay_ms(20); //延时消抖
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
Delay_ms(20); //延时消抖
KeyNum = 1; //置键码为1
}
return KeyNum; //返回键码值
}
2、主函数代码main.c
#include "stm32f10x.h"
#include "Delay.h"
#include "Key.h"
#define HC595_Num 8
uint8_t Data1[HC595_Num] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
uint8_t Data2[HC595_Num] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
uint8_t Data3[HC595_Num] = {0xFC,0x3F,0xF8,0x1F,0xE0,0x0F,0x80,0x01};
uint8_t Data4[HC595_Num] = {0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00};
uint8_t Data5[HC595_Num] = {0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF};
uint8_t Data6[HC595_Num] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// 定义74HC595控制引脚
#define HC595_LATCH_PIN GPIO_Pin_7 // ST_CP /RCK
#define HC595_CLK_PIN GPIO_Pin_6 // SH_CP /SCK
#define HC595_DATA_PIN GPIO_Pin_5 // SER /DS
#define HC595_PORT GPIOA
/*GPIO初始化*/
void HC595_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
// 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置引脚为推挽输出
GPIO_InitStruct.GPIO_Pin = HC595_LATCH_PIN | HC595_CLK_PIN | HC595_DATA_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(HC595_PORT, &GPIO_InitStruct);
// 初始状态:拉低所有引脚
GPIO_ResetBits(HC595_PORT, HC595_LATCH_PIN | HC595_CLK_PIN | HC595_DATA_PIN);
}
/*74HC595发送数据,多个字节,低位先发*/
void HC595_SendMultipleBytes(uint8_t *data, uint16_t length) {
// 锁存引脚拉低,准备接收数据
GPIO_ResetBits(HC595_PORT, HC595_LATCH_PIN);
// 从最后一个字节开始发送(低位优先LSB)
for (int16_t byte = length - 1; byte >= 0; byte--) {
for (int8_t bit = 0; bit <= 7; bit++) {
GPIO_ResetBits(HC595_PORT, HC595_CLK_PIN); // 时钟拉低
// 发送当前位
if (data[byte] & (1 << bit)) {
GPIO_SetBits(HC595_PORT, HC595_DATA_PIN);
} else {
GPIO_ResetBits(HC595_PORT, HC595_DATA_PIN);
}
GPIO_SetBits(HC595_PORT, HC595_CLK_PIN); // 时钟上升沿
}
}
// 所有数据发送完毕后,触发锁存
GPIO_SetBits(HC595_PORT, HC595_LATCH_PIN);
}
/*主函数*/
int main(void) {
HC595_GPIO_Init(); // 初始化GPIO
Key_Init();
uint8_t *mydata[] = {Data1,Data2,Data3,Data4,Data5,Data6};
while (1) {
/****1.图案自动切换****/
// HC595_SendMultipleBytes(Data1,HC595_Num);
// Delay_ms(500);
// HC595_SendMultipleBytes(Data2,HC595_Num);
// Delay_ms(500);
// HC595_SendMultipleBytes(Data3,HC595_Num);
// Delay_ms(500);
// HC595_SendMultipleBytes(Data4,HC595_Num);
// Delay_ms(500);
// HC595_SendMultipleBytes(Data5,HC595_Num);
// Delay_ms(500);
// HC595_SendMultipleBytes(Data6,HC595_Num);
// Delay_ms(500);
/****2.按键切换图案****/
uint8_t KeyNum = Key_GetNum();
if(KeyNum == 1){
static uint8_t pattern = 0;
HC595_SendMultipleBytes(mydata[pattern], HC595_Num);
pattern = (pattern + 1 ) % 6;
Delay_ms(100);
}
}
}
|
-
原理图,第1次按键
-
第2次按键
-
第3次按键
-
第4次按键
-
第5次按键
-
第6次按键
|