if(mode)key_up=1; //支持连按 if(key_up&&(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0||GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0||GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==0||GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)) { delay_ms(10);//去抖动 key_up=0; if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0)return KEY0_PRES; else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0)return KEY1_PRES; else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==0)return KEY2_PRES; else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)return WKUP_PRES;//本来是1 }else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==1&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==1&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==1&&GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)key_up=1; return 0;// 无按键按下 解释
时间: 2023-07-15 08:14:07 浏览: 70
这段代码是一个检测按键按下的函数,主要作用是判断哪个按键被按下。其中,mode是一个变量,如果为1,则支持连按;key_up是一个标志位,用于判断是否松开了按键。
如果key_up为1,表示上一次按键已经松开,这时候会检测四个按键的状态(分别是GPIOB的5、8、9号引脚和GPIOA的0号引脚)。如果有任意一个按键被按下,则会进行去抖动处理,然后设置key_up为0,表示当前有按键被按下。
如果key_up为0,则表示上一次还没有松开按键,这时候会检测四个按键的状态。如果四个按键都没有被按下,则会将key_up设置为1,表示当前没有按键被按下。
最后,如果有按键被按下,则会返回对应的按键值,如果没有按键被按下,则返回0。
相关问题
u8 KEY_Scan(u8 mode) { static u8 key_up=1;//按键按松开标志 if(mode)key_up=1; //支持连按 if(key_up&&(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0||GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0||GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==0||GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)) { delay_ms(10);//去抖动 key_up=0; if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0)return KEY0_PRES; else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0)return KEY1_PRES; else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==0)return KEY2_PRES; else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)return WKUP_PRES;//本来是1 }else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==1&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==1&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==1&&GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)key_up=1; return 0;// 无按键按下 } 请帮我优化一下这段代码
这段代码可以进行如下优化:
1.使用位运算代替逻辑运算
由于逻辑运算可能会导致浪费时间,可以通过位运算来优化代码。例如,使用“&”运算符代替“&&”运算符,使用“|”运算符代替“||”运算符。这样可以减少运算次数,提高效率。
2.使用宏定义代替数字常量
在代码中使用数字常量不够直观,可以使用宏定义来代替。这样可以提高代码的可读性和可维护性。
3.使用枚举类型代替数字常量
将数字常量改为枚举类型可以使代码更加清晰易懂。
4.使用函数封装代码
可以将代码封装到函数中,提高代码的可重用性和可维护性。
经过以上优化,代码可以改写为:
```
typedef enum {
KEY0_PRES = 1,
KEY1_PRES,
KEY2_PRES,
WKUP_PRES
} KEY_TypeDef;
#define KEY0_GPIO_PIN GPIO_Pin_5
#define KEY1_GPIO_PIN GPIO_Pin_8
#define KEY2_GPIO_PIN GPIO_Pin_9
#define WKUP_GPIO_PIN GPIO_Pin_0
u8 KEY_Scan(u8 mode) {
static u8 key_up = 1; //按键按松开标志
if (mode)
key_up = 1; //支持连按
if (key_up && ((GPIOB->IDR & KEY0_GPIO_PIN) == 0 ||
(GPIOB->IDR & KEY1_GPIO_PIN) == 0 ||
(GPIOB->IDR & KEY2_GPIO_PIN) == 0 ||
(GPIOA->IDR & WKUP_GPIO_PIN) != 0)) {
delay_ms(10); //去抖动
key_up = 0;
if ((GPIOB->IDR & KEY0_GPIO_PIN) == 0)
return KEY0_PRES;
else if ((GPIOB->IDR & KEY1_GPIO_PIN) == 0)
return KEY1_PRES;
else if ((GPIOB->IDR & KEY2_GPIO_PIN) == 0)
return KEY2_PRES;
else if ((GPIOA->IDR & WKUP_GPIO_PIN) == 0)
return WKUP_PRES;
} else if ((GPIOB->IDR & KEY0_GPIO_PIN) != 0 &&
(GPIOB->IDR & KEY1_GPIO_PIN) != 0 &&
(GPIOB->IDR & KEY2_GPIO_PIN) != 0 &&
(GPIOA->IDR & WKUP_GPIO_PIN) == 0)
key_up = 1;
return 0; // 无按键按下
}
```
其中,使用了枚举类型定义按键类型,使用宏定义代替数字常量,使用位运算代替逻辑运算。同时,将代码封装到函数中,增加了代码的可重用性和可维护性。
float speed; int main(void) { Breath_Init (); KEY_InitU(); OLED_Init(); Motor_init(); OLED_ShowString(1,1,"Rspeed:"); while (1) { Motor_derection(20); } } #include "stm32f10x.h" // Device header void Breath_Init () { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); GPIO_InitTypeDef GPIO_Initstucture; GPIO_Initstucture.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽 GPIO_Initstucture.GPIO_Pin=GPIO_Pin_0; GPIO_Initstucture.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_Initstucture); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstucture; TIM_TimeBaseInitstucture.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitstucture.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitstucture.TIM_Period=100-1;//72M/TIM_Period为频率也是ARR TIM_TimeBaseInitstucture.TIM_Prescaler=72-1;//分频也是PSC TIM_TimeBaseInitstucture.TIM_RepetitionCounter=0;//周期数 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitstucture); TIM_OCInitTypeDef TIM_OCInitstructure; TIM_OCStructInit(&TIM_OCInitstructure); TIM_OCInitstructure.TIM_OCMode=TIM_OCMode_PWM1; TIM_OCInitstructure.TIM_OCPolarity=TIM_OCPolarity_High; TIM_OCInitstructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitstructure.TIM_Pulse=0;//CCR TIM_OC1Init(TIM2,&TIM_OCInitstructure); TIM_Cmd(TIM2,ENABLE); } void TIM_Compare(uint16_t compare) { TIM_SetCompare1(TIM2,compare); } void KEY_InitD (void)//下拉 { //GPIOB初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_Initstructure; GPIO_Initstructure.GPIO_Mode =GPIO_Mode_IPD ; GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Initstructure); } void KEY_InitU (void)//上拉 { //GPIOB初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_Initstructure; GPIO_Initstructure.GPIO_Mode =GPIO_Mode_IPU ; GPIO_Initstructure.GPIO_Pin = GPIO_Pin_1; GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Initstructure); } uint16_t Key_GetNum () { uint8_t KeyNum = 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; } } void Motor_init () { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5; GPIO_Init(GPIOA, &GPIO_InitStructure); } void Motor_derection (float speed) { if(speed>0) { GPIO_SetBits(GPIOA,GPIO_Pin_4);//in1 GPIO_ResetBits(GPIOA,GPIO_Pin_5);//in2 TIM_Compare(speed); } else GPIO_ResetBits(GPIOA,GPIO_Pin_4);//in1 GPIO_SetBits(GPIOA,GPIO_Pin_5);//in2 TIM_Compare(-speed); } 为什么直流电机不转
根据给出的代码,直流电机不转的可能原因有以下几点:
1. 未正确初始化引脚:在`Motor_init()`函数中,需要将GPIOA的引脚4和5初始化为输入上拉模式。但是,在给出的代码中,并没有调用`Motor_init()`函数进行引脚的初始化。因此,需要在`main()`函数中添加`Motor_init()`函数的调用。
2. 未设置合适的方向和速度:在`Motor_derection()`函数中,根据`speed`的正负来设置电机的方向以及使用`TIM_Compare()`函数设置PWM的占空比。需要确保`speed`的值是正确设置且适合驱动电机的范围。
3. 未启动定时器:在`Breath_Init()`函数中,需要使用`TIM_Cmd(TIM2,ENABLE);`启动定时器2。但是,在给出的代码中,并没有调用该函数来启动定时器。因此,需要在`main()`函数中添加该函数的调用。
如果以上问题都已解决,并且硬件连接正确,但直流电机仍然不转动,则可能是其他硬件或电路问题。需要仔细检查硬件连接、电源供应等方面的问题。
阅读全文