m0_71661142 2023-12-01 22:28 采纳率: 40%
浏览 5
已结题

stm32单片机实现按键电子琴,但是代码功能有问题

用keil vision5编程的stm32单片机,对应的芯片是STM32F103R6.
想要实现的功能是用两行四列按键的前7个按键控制蜂鸣器发出对应音符,并能用最后一个按键调音调,且可以在蜂鸣器发声时亮起相应LED灯。
以下程序在下载进单片机后,蜂鸣器发出间歇性的声音并伴有长鸣,只有后四个按键按下有效果,且按键按下后不能切换音符和音调,同时LED灯全亮。
希望各位能帮忙看看代码有哪些错误,求指点一二。


#include <stm32f10x_conf.h>
#include <SysTick.h>
#define PBeep PCout(0)
//定义A-G音调低音音符频率
int yinfu[7][7]={{262,294,330,349,392,440,494},{294,330,370,392,440,494,554},{330,370,415,440,494,554,622},
{349,392,440,466,523,587,659},{392,440,494,523,587,659,740},{440,494,554,587,659,740,831},{494,554,622,659,740,831,932}};
//定义按键映射表
int button_map[2][4]={{1,2,3,4},{5,6,7,8}};
//初始化IO接口
void IO_init(void){
    GPIO_InitTypeDef  GPIOA_Init,GPIOB_Init,GPIOC_Init;
    //使能A、B、C三组端口时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); 
    //PB-推挽输出-连接LED灯
    GPIOB_Init.GPIO_Pin=GPIO_Pin_All;
    GPIOB_Init.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIOB_Init.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIOB_Init);
    //PC0-推挽输出-连接蜂鸣器
    GPIOC_Init.GPIO_Pin=GPIO_Pin_0;
    GPIOC_Init.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIOC_Init.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOC,&GPIOC_Init);
    //PA-上拉输入-连接按键
    GPIOA_Init.GPIO_Pin=GPIO_Pin_All;
    GPIOA_Init.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_Init(GPIOA,&GPIOA_Init);
}
int Button_Scan(void){
    int i,j;
    for(i=0;i<2;i++){
        GPIO_ResetBits(GPIOA, (1 << i)); // 输出低电平
        for(j=0;j<4;j++){
            if (!GPIO_ReadInputDataBit(GPIOA, (1 << (j + 4)))) { // 判断是否有按键按下
                    return button_map[i][j]; // 返回按键编号
            }
        
        }
        GPIO_SetBits(GPIOA, (1 << i)); // 恢复高电平
    }
}
void Sound(int frq){
    int n;
    if(frq != 1000){ //如果频率不为1000则按频率输出,否则只延时
        n = 10000000/(frq);
        PBeep = 0;
    delay_us(n);
    PBeep = 1;
        delay_us(n);
    }else{
    delay_us(1000);

}
}

int main(void){
    int button_id,yinjie=0;
    IO_init();
    while(1){
        button_id=Button_Scan();
        switch(button_id){
            case 1:Sound(yinfu[yinjie][0]);break;
            case 2:Sound(yinfu[yinjie][1]);break;
            case 3:Sound(yinfu[yinjie][2]);break;
            case 4:Sound(yinfu[yinjie][3]);break;
            case 5:Sound(yinfu[yinjie][4]);break;
            case 6:Sound(yinfu[yinjie][5]);break;
            case 7:Sound(yinfu[yinjie][6]);break;
            case 8:
                if(yinjie<7){
                    yinjie++;
                }else{
                    yinjie=0;
                }
                break;
        }
    
    }
}
  • 写回答

2条回答 默认 最新

  • 她嫌我菜呜呜呜 2023-12-01 23:00
    关注

    在你的代码中,存在几个潜在的问题:

    1. 按键扫描函数Button_Scan中应该对GPIOA的第0和第1位进行拉低,而不是第i位,因为第0和第1位是引脚PA0和PA1,即按键连接的引脚。
    2. 蜂鸣器触发函数Sound中,用于延时的delay_us函数可能没有按预期工作。你需要确保延时函数能够提供正确的延时时间。
    3. 初始化IO接口时,GPIOB的初始化应该只针对LED灯连接的引脚,而不是全部引脚。
    4. 没有在按键按下时控制LED灯的亮灭,这可能会导致LED全亮。

    因此,你需要仔细检查和调试这些部分,并确保每个函数都按照预期进行操作。特别是需要确保按键扫描函数和蜂鸣器触发函数运行正确,以及正确处理LED灯的控制。

    另外,检查和确保按键连接正确,引脚的电气特性符合预期,以及确保蜂鸣器的驱动方式和电气特性正确。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月6日
  • 创建了问题 12月1日