我正在学习微控制器编程。我需要帮助才能在WinAVR上使用Atmega8L-8PU完成我的程序。 当按下按钮时,我添加了3个按钮:第一个按钮将提供15分钟输出,第二个按钮将提供30分钟,最后一个按钮将提供45分钟。每次应该在下次按下后自动重置时。
这是我写的代码,但我不能添加持续时间。如果有人能做到这对我来说会非常有帮助。提前谢谢:)。
#define numberofButtons 3
#include <avr/io.h>
#include"buttonpress.h"
int main(void)
{
DDRB = 0b00000000;
DDRD = 0b00000111;
PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);
while(1)
{
if (buttonpressed(0, PINB, 0, 100))
{
PORTD ^= (1<<PIND0);
}
if (buttonpressed(1, PINB, 1, 100))
{
PORTD ^= (1<<PIND1);
}
if (buttonpressed(2, PINB, 2, 100))
{
PORTD ^= (1<<PIND2);
}
}
}
我试过这种方式,但它也没有工作........ :(
#define numberofButtons 3
#include"buttonpress.h"
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char seconds =0;
int minutes;
int main ()
{
DDRB = 0b00000000;
DDRD = 0b00000111;
PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);
volatile int seconds;
DDRD |= (1<<PIND0)|(1<<PIND1)|(1<<PIND2);
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
sei(); // Enable global interrupts
OCR1A = 15624; // Set CTC compare value to 1Hz at 8MHz AVR clock, with a prescaler of 64
TCCR1B |= ((1 << CS10) | (1 << CS11)); // Start timer at Fcpu/64
while (1)
{
if(seconds==60)
{
minutes++;
seconds=0;
}
{
if (buttonpressed(0, PINB, 0, 100))
{
PORTD ^= (1<<PIND0);
int total_seconds=900;
while(total_seconds-seconds!=0)
{
//Delay of 15 min
}
}
} return 0;
}
}
ISR (TIMER1_COMPA_vect)
{
seconds++;
}
答案 0 :(得分:1)
例如,您可以将Timer0设置为每秒调用一次中断。在每次中断期间,您必须递增内部计数器。经过所需的时间(15,30,45分钟)后,实现自己的逻辑(如关闭所需的端口)。
答案 1 :(得分:1)
如果您有从CPU获取计数器的功能,这是一个非常简单的计数器,计数器会随着可以计算的特定间隔而增加。
然后按下该按钮时,将变量设置为计数器的当前值加上对应于15分钟的量。在循环中,您将计数器的当前值检查到您在按键上设置的变量。当前计数器等于或大于变量时,则经过15分钟。
一些伪代码
int main(void)
{
int eventHapening = 0;
while (1)
{
if (keypress)
{
eventHappening = currentCounter + 15 minutes;
}
// Check that eventHappening is non-zero to prevent false positives
if (eventHappening != 0 && currentCounter >= eventHappening)
{
// Do something
eventHappening = 0; // Reset, and disable event
}
}
}
答案 2 :(得分:0)
如果您有权访问头文件time.h
,那么以下内容可能是一个解决方案:
#define numberofButtons 3
#include <avr/io.h>
#include<time.h>
#include"buttonpress.h"
void wait(double x)
{
clock_t begin, end;
double time_spent, limit=1000*60*x;
begin = clock();
while(time_spent<= limit)
{
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
}
}
int main(void)
{
DDRB = 0b00000000;
DDRD = 0b00000111;
PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);
while(1)
{
if (buttonpressed(0, PINB, 0, 100))
{
PORTD ^= (1<<PIND0);
wait(15);
}
if (buttonpressed(1, PINB, 1, 100))
{
PORTD ^= (1<<PIND1);
wait(15);
}
if (buttonpressed(2, PINB, 2, 100))
{
PORTD ^= (1<<PIND2);
wait(15);
}
}
}
最有可能上面的代码不会出现任何错误。由于代码有一些依赖关系,我可以成功编译一个类似的程序,如下所示。
#define numberofButtons 3
#include <stdio.h>
#include<time.h>
void wait(double x)
{
clock_t begin, end;
double time_spent, limit=1000*60*x;
begin = clock();
while(time_spent<= limit)
{
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
}
}
int main(void)
{
char c;
while((c = getchar())!='e')
{
if (c == 'a')
{
printf("I am in a! Come after 15 min!\n");
wait(15);
printf("WOW! How could you pass 15 min!!\n");
}
if (c == 'b')
{
printf("I am in b! Come after 15 min!\n");
wait(15);
printf("WOW! How could you pass 15 min!!\n");
}
if (c == 'c')
{
printf("I am in c! Come after 15 min!\n");
wait(15);
printf("WOW! How could you pass 15 min!!\n");
}
}
}
使用c。
编译时,您可以看到here没有编译错误答案 3 :(得分:0)
您没有将您的问题标记为AVR,这就是现有答案忽略了您拥有实际AVR计时器这一事实的原因。
更准确地说,那些定时器是CPU周期计数器。 TIMER1
特别是16位计数器。如果将TCCR1
时钟选择位设置为101
,则每1024个CPU周期计数一个时钟。让我们假设一个16 Mhz的时钟,这意味着每秒16000000个CPU周期=每秒15625个滴答。
由于TIMER1
是16位值,因此每4.2秒溢出一次。您可以将此溢出用于generate an interrupt。 900秒仅有214.6次中断 - 你能在898秒内逃脱吗?当然,您也可以计算TIMER0
的溢出数。由于只有8位,所以溢出次数是256次:900秒内54931次。