我正在开发一个嵌入式(avr)项目,基本上我想根据引脚被按下多长时间打印出一些不同的东西。我无法弄清楚当值通过时会发生什么,并且在整个过程中满足if语句(按钮仍被按下以便计数器递增)。
设置如下:
如果溢出在7-48之间(按下按钮30ms-200ms),则打印出'。' 如果溢出大于48(按下按钮超过200ms),则打印出' - '
如果溢出大于97(超过400毫秒未按下按钮),则打印出''
我目前的代码如下:
static inline void isr(char type) {
static unsigned int overflows = 0;
static unsigned char idx = 0;
if (type == 'e') { // edge captured
if (TCCR1B & 0x40) { // rising edge
if (overflows < 7) {
// do nothing
} else if (overflows < 49) {
buffer[idx++] = '.';
size++;
} else {
buffer[idx++] = '-';
size++;
}
}
overflows = 0; // restart counting overflows at each edge
} else { // overflow occured
overflows++;
if (buffer[idx-1] != ' ' && !(TCCR1B & 0x40) && overflows > 97) {
buffer[idx++] = ' ';
size++;
}
}
我不确定这是否正确,因为看起来在'.
'之前总会有一个'-
',因为当溢出值递增时,它满足&lt; 49条件。
有什么想法吗?
答案 0 :(得分:0)
如果你想计算no.of次按开关,你可以使用while循环。 例如,
if(sw==0) //sw is switch connected with I/O pin
{
while(sw==0)
{
led=1; //LED is output
delay(); // use delay function
led=0;
delay();
count++;
}
}
通过使用while循环,可以避免多次按下开关。如果你打开一个开关,计数将增加一个。
答案 1 :(得分:0)
我不确定这是否正确,因为看起来总会有'。'在' - '之前,因为溢出 值递增,满足&lt; 49条件。
但测试仅在上升沿执行 - 同时type == 'e'
和(TCCR1B & 0x40) != 0
。因此,overflow
计数仅在按钮发布时进行评估,因此您不会在.
之前看到中间-
。
因此,为了回答您的问题,条件为真时执行条件语句或块。这里有嵌套条件,因此所有前面的条件必须为true才能评估内部条件。
答案 2 :(得分:0)
根据你的描述,我假设你的针上有一个按钮,所以在这种情况下,在做任何事情之前我首先建议的是对按钮信号实施去抖动。 我会解决这样的问题:
#define BUTTON_UNKNOWN 0
#define BUTTON_DOWN 1
#define BUTTON_UP 2
#define FALSE 0
#define TRUE 1
static inline unsigned char debounce( unsigned char current_state)
{
static unsigned char ret_value;
unsigned char state_changed = FALSE;
// Counter for number of equal states
static unsigned char count = 0;
// Keeps track of current (de-bounced) state
static unsigned char button_state = 0;
// Check if button is high or low for the moment
if (current_state != button_state)
{
// Button state is about to be changed, increase counter
count++;
if (count >= 3)
{
// The button have not bounced for four checks, change state
button_state = current_state;
// If the button was pressed (not released), tell main so
count = 0;
state_changed = TRUE;
}
}
else
{
state_changed = FALSE;
// Reset counter
count = 0;
}
//if butten press or release detected
if (state_changed == TRUE)
{
//check for the current state of the button
if (current_state != 0)
{
ret_value = BUTTON_DOWN;
}
else
{
ret_value = BUTTON_UP;
}
}
return ret_value;
}
int main(void)
{
//perform proper initialization of your pin
unsigned char button = BUTTON_UNKNOWN;
unsigned char cycle_count = 0;
unsigned char idx = 0;
unsigned char buffer[255];
unsigned char current_state;
unsigned char no_activity;
//unsigned char current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
while(1)
{
//read the button state
current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
// Update button_state
button = debounce(current_state);
// Check if the button is pressed.
if (button == BUTTON_DOWN)
{
//count cycles in which the button was pressed
//one cycle is 10 ms - see delay below
cycle_count++;
}
else
{
//check if the button was pressed before
if ((button != BUTTON_UNKNOWN) && (cycle_count != 0))
{
//if button was pressed for 200ms
if (cycle_count <= 20)
{
buffer[idx] = '.';
idx++;
}
else
{
//if the button was pressed between 200 and 400 ms
if ((cycle_count > 20) && (cycle_count <= 40))
{
buffer[idx] = '-';
idx++;
}
//the button was pressed for more than 400ms, uncomment if you need it
/*else
{
buffer[idx] = ' ';
idx++;
}*/
}
//reset counting mechanism
cycle_count = 0;
no_activity = 0;
}
else
{
no_activity++;
if (no_activity >= 40)
{
buffer[idx] = ' ';
idx++;
no_activity = 0;
}
}
}
// Delay for a while so we don’t check to button too often
_delay_ms(10);
}
}
您可以根据需要调整此代码:
更改行current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
以便读取您的pin状态,并更改缓冲区的声明以满足您的需求unsigned char buffer[255];
请注意,由于去抖,所测量的时间不是200毫秒(它是200毫秒+ 2 *去抖时间= 260毫秒(去抖时间是3个周期,每个周期是10毫秒,见最后的延迟),但你可以补偿通过最终减少cycle_count比较中的含量来解决这些错误。
希望这有帮助!
如果你真的坚持你的解决方案,那么为了避免问题你所经历的是不连续评估溢出值,不要试图确定按钮按下的长度,而是尝试测量长度推送和之后评估它并将char放入缓冲区。你需要等待发布按钮&#39;然后评估按下按钮的时间。像这样:
static inline void isr(char type) {
static unsigned int overflows = 0;
static unsigned char idx = 0;
unsiged char button_status;
if (type == 'e') { // edge captured
if (TCCR1B & 0x40) { // rising edge
//perform a debounce otherwise wont be good
button_status = 1;
}
overflows = 0; // restart counting overflows at each edge
} else { // overflow occured
overflows++;
//if button was pressed and its now released evaluate result
if (!(TCCR1B & 0x40) && (button_status == 1))
{
if (overflows < 7) {
// do nothing
} else if (overflows < 49) {
buffer[idx++] = '.';
size++;
} else {
buffer[idx++] = '-';
size++;
}
button_status = 0;
}
if (buffer[idx-1] != ' ' && !(TCCR1B & 0x40) && overflows > 97) {
buffer[idx++] = ' ';
size++;
}
}