c - AVR 控制器,按钮问题
问题描述
我有问题,当我按下按钮时,微控制器根本没有注册。因为它没有发生。这是我的代码。
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#define bit_is_clear(byte, bit) (!(byte & (1 << bit)))
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
typedef enum { false, true } boolean;
boolean clicked = false;
int sigurno_pritisnut = 0;
void pressed();
void unpressed();
int main(void)
{
//LED OUTPUT
DDRB |= (1 << PINB0) | (1 << PINB1) | (1 << PINB2);
//LED LOW
PORTB &= ~((1 << PINB0) | (1 << PINB1) | (1 << PINB2));
//BUTTON INPUT
DDRC &= ~(1 << PINC5);
//BUTTON HIGH
PORTC |= (1 << PINC5);
/* Replace with your application code */
while (1)
{
if(bit_is_clear(PINC, PINC5)){
sigurno_pritisnut++;
if(sigurno_pritisnut > 400){
clicked = !clicked;
sigurno_pritisnut = 0;
}
}
if(clicked){
pressed();
}else{
unpressed();
}
}
}
void pressed(){
PORTB ^= (1 << PINB0);
_delay_ms(500);
PORTB ^= (1 << PINB1);
_delay_ms(500);
PORTB ^= (1 << PINB2);
_delay_ms(500);
sigurno_pritisnut = 0;
}
void unpressed(){
PORTB ^= (1 << PINB0);
_delay_ms(500);
PORTB ^= (1 << PINB0);
PORTB ^= (1 << PINB1);
_delay_ms(500);
PORTB ^= (1 << PINB1);
PORTB ^= (1 << PINB2);
_delay_ms(500);
PORTB ^= (1 << PINB2);
}
..................................................... .....................我尝试过其他按钮,尝试过其他引脚但没有。..................................................... .....................
解决方案
问题似乎是你的延迟陈述。在两者中pressed
,unpressed
您等待 3 x 500 毫秒。
在循环中,您希望bit_is_clear
在更改之前查看 400 次clicked
。
所以看起来bit_is_clear
必须在 600 秒后才能改变clicked
。
请注意,这
if(clicked){
pressed();
}else if(!clicked){
unpressed();
}
是相同的
if(clicked){
pressed();
}else
unpressed();
}
所以在每个循环中你都会输入其中一个。
此外,您不在else
这里似乎很奇怪:
if(bit_is_clear(PINC, PINC5)){
sigurno_pritisnut++;
if(sigurno_pritisnut > 500){
clicked = !clicked;
sigurno_pritisnut = 0;
}
}
else
{
// ... don't you need some code here?
}
所以按钮是这样工作的
bit_is_clear
== true 表示按下
bit_is_clear
== false 表示释放
你需要类似的东西:
while (1)
{
while (1) // Loop until a state is changed
{
if(bit_is_clear(PINC, PINC5))
{
// pressed
if (clicked)
{
// Same state so just continue...
sigurno_pritisnut = 0;
continue;
}
sigurno_pritisnut++;
if(sigurno_pritisnut > 400){
clicked = 1;
sigurno_pritisnut = 0;
// State change - break out
break;
}
}
else
{
// released
if (!clicked)
{
sigurno_pritisnut = 0;
continue;
}
sigurno_pritisnut++;
if(sigurno_pritisnut > 400){
clicked = 0;
sigurno_pritisnut = 0;
break;
}
}
}
if(clicked){
pressed();
}else{
unpressed();
}
}
这样,您只有在发生新事情时才调用pressed
/ 。unpressed
推荐阅读
- python - 将列表中的项目分配到新列表中
- amazon-dynamodb - Dynamodb 单表与分区大小
- ios - 如何从 iOS 中的 Firebase 远程配置中获取双倍价值?
- python - 获取类中特定类型的对象并更改其属性
- php - 使用 Voyager 为 Laravel 项目创建动态菜单
- java - Swing 应用程序未出现
- laravel - 如何存储登录到我的数据库的实际用户并将其显示为我的 CRUD 的创建字段?
- python - 填充列表列表以使其等于最大列表的大小
- r - 使用 par(mfrow()) 方法在一个图中拟合两个 coefplot
- hadoop - 从 Pig 生成的 CurrentTime() 在 Hive Datetime 列中显示为 NULL