Помаленьку осваиваю AVR, пишу в WinAVR. Всякие простейшие "моргалки", вроде освоил, решил светофор сбацать. Вроде элементарно, но в
WinAVR столкнулся с проблемами с задержками > 250 ms.
Версия WinAVR - 20070525, все проверялось в Proteus 7.2SP6.
Вот, что получилось:
Код
//Электронный светофор, =AVR.
// cpu: ATMega8
// speed: 1 mhz
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL
int main(void) { //Начало программы
// Инициализация портов
PORTB=0x20;
DDRB=0x1F;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
while (1) //Бесконечный цикл
{
PORTB |= _BV(PB0); // Уст. пин 0 порта B в "1" - вкл. красный
PORTB |= _BV(PB3); // Уст. пин 3 порта B в "1" - вкл. зеленый для пеших
_delay_ms(250); // Пауза 3 сек. - пока горит красный
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
PORTB |= _BV(PB1); // Уст. пин 1 порта B в "1"- вкл. желтый
_delay_ms(250);
_delay_ms(250);
PORTB &= ~_BV(PB0); // Уст. пин 0 порта B в "0" - выкл. красный
PORTB &= ~_BV(PB3); // Уст. пин 3 порта B в "0" - выкл. зеленый для пеших
_delay_ms(250); // Пауза 1 сек. - пока горит желтый
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
PORTB &= ~_BV(PB1); // Уст. пин 1 порта B в "0"- выкл. желтый
PORTB |= _BV(PB2); // Уст. пин 1 порта B в "1"- вкл. зеленый
PORTB |= _BV(PB4); // Уст. пин 3 порта B в "1" - вкл. красный для пеших
_delay_ms(250); // Пауза 3.5 сек. - пока горит зеленый
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
PORTB &= ~_BV(PB2); // Уст. пин 2 порта B в "0"- выкл. зеленый
PORTB |= _BV(PB1); // Уст. пин 1 порта B в "1"- вкл. желтый
PORTB &= ~_BV(PB4); // Уст. пин 3 порта B в "0" - выкл. красный для пеших
_delay_ms(250); // Пауза 1 сек. - пока горит желтый
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
PORTB &= ~_BV(PB1); // Уст. пин 1 порта B в "0"- выкл. желтый
} //
}
Т.е., что бы получить требуемые задержки, как я думал, типа _delay_ms(3000), _delay_ms(1000) и _delay_ms(4500), прошлось делать "порно" в виде последовательных команд _delay_ms(250);
То же самое - в CVAVR - все ОК:
Код
/*****************************************************
Project : TrafficLights
Version : 1 alpha
Date : 16.11.2008
Author : Freeware, for evaluation and non-commercial use only
Chip type : ATmega8
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#include <delay.h>
void main(void)
{
// Input/Output Ports initialization
PORTB=0x20;
DDRB=0x1F;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
while (1)
{
// Place your code here
PORTB.0 = 1; // Уст. пин 0 порта B в "1" - вкл. красный
delay_ms(3000); // Пауза 3 сек. - пока горит красный
PORTB.0 = 0; // Уст. пин 0 порта B в "0" - выкл. красный
PORTB.1 = 1; // Уст. пин 1 порта B в "1"- вкл. желтый
delay_ms(1000); // Пауза 1 сек. - пока горит желтый
PORTB.1 = 0; // Уст. пин 1 порта B в "0"- выкл. желтый
PORTB.2 = 1; // Уст. пин 1 порта B в "1"- вкл. зеленый
delay_ms(4500); // Пауза 1 сек. - пока горит зеленый
PORTB.2 = 0; // Уст. пин 2 порта B в "0"- выкл. зеленый
PORTB.1 = 1; // Уст. пин 1 порта B в "1"- вкл. желтый
delay_ms(1000); // Пауза 1 сек. - пока горит желтый
PORTB.1 = 0; // Уст. пин 1 порта B в "0"- выкл. желтый
};
}
Здесь - все четко - в Preteus'е все переключается(правильные задержки) как надо!
В чем косяк в случае с WinAVR?!! Как решать проблему?!!