Немного подправил Вашу программу. Я уже Вам писал, что в строке надо писать один оператор, это, в принципе, не приводит к ошибке, но если надо закомментировать какой-либо оператор, (двойными косыми), то будут закомментированы все операторы, находящиеся в этой строке.
Управление портом я переделал на PORTD, а не DDRD, так как я уже выше писал. Регистр D - это настройка порта на ввод или вывод. Работать и так оно будет, потому что Вы переключая вывод порта на вход, Вы тем самым гасите светодиод, так как вывод порта, к которому подключен светодиод, теперь стал вводом и, понятно диод гаснет. Но это не логично.
Переменные m и n, я перенес в глобальные, так как отладчик "не видит" локальные переменные и я не могу отследить, как они изменяются.
Так вот, после всех "переделок" программа компилируется, но компилятор выдает предупреждение, что:
for ( uint8_t m=0; m<3; m + 2)
ничего не делает. Ошибки не выдает, но делает предупреждение. После запуска программы, переменной m присваивается значение равное 0 и дальше она никак не меняется. То есть, выражение m+2 не работает. Не знаю почему, так как так я никогда не писал, поэтому и не выяснял, почему оно не работает.
Дальше. Вы гасите все светодиоды в строке PORTD=0x0F. При запуске программы, загорается один светодиод и программа зацикливается. Выражение for не работает, поэтому программа из этого цикла не выходит, так как m никогда не станет равной 3.
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
void initialization(void)
{
DDRD = 0xff;
PORTD = 0x0F;
}
uint8_t m,n;
int main(void)
{
initialization(); //Вызов функции инициализации порта
//DDRD = 0xff;
//PORTD = 0x0F;
//int f1;
//int f2;
//int f3;
while(1)
{
for (m=0; m<3; m+2) //Переменная m приобретает значение 0 или 2
{
//f1 = DDRD &= ~ _BV(m); _delay_ms(3000); // на выходе PD(m) низкий уровень, диод горит 3 сек.
PORTD &= ~ _BV(m); // на выходе PD(m) низкий уровень, диод горит 3 сек.
}
//_delay_ms(3000);
for(n=0; n<3; n++)
{
PORTD |= _BV(m);
// _delay_ms(500 );
PORTD &= ~ _BV(m);
// _delay_ms(500);
PORTD |= _BV(m); //диод на выходе PD(m) моргает 3 раза
}
PORTD &= ~ _BV(1);
// _delay_ms(2000);
PORTD |= _BV(1); // диод на выходе PD(1) горит 2 сек и гаснет.
}
}
Да забыл, уберите комментарии с операторов _delay_ms. Я закомментировал, иначе отладка будет продолжаться до второго пришествия. 3 сек для отладчика превратятся в часы.
Тогда как понимать Ваше "примитивно" выглядит, если Вы не знаете на чем оно написано.
"Примитивно" относилось не к качеству кода, вовсе нет ! Я имел в виду только и исключительно сам подход - задавать циклограмму самой программой, если можно (ну вряд ли язык накладывает какие-то ограничения в этом плане, нет ?) описать ее (циклограмму) массивом из пар состояние-длительность.
Возможно, Вы правы, но тут же у коллеги, пока первые шаги, поэтому все это в будущем. А пока и "примитивное" не освоено..
Ну, это я ведь так, в порядке "бурчания"
Но на самом деле, в варианте, который я предложил, собственно кода будет меньше и он будет проще для понимания (хотя вся равно оставляет поле для ошибок). На словах - идем по массиву, выбираем пары значений. Первое - напрямую в порт (если светодиоды, и только светодиоды на этом порту) или перестановкой бит отправляем значения в битовые линии порта (если разбросаны или возможен конфликт), второе - в задержку (вероятно, подойдет целое значение в секундах, 1....255). Если очередная задержка = 0, то индекс массива переставляем на начало.
Владимир_К, там еще унарный операнд третий у цикла, если не опечатка
Вернемся еще раз к программе. Я сразу не понял, в чем проблема, как то сразу не усмотрел..
for (m=0; m<3; m+2) // переменная m принимает значение 0 или 2
Дело в том, что это выражение в даном случае, не верно, так как здесь к m прибавляется 2, но новое значение m не присваивается. Нужно так:
for (m=0; m<3; m+=2) // переменная m принимает значение 0 или 2
Можно и так:
for (m=0; m<3; m++, m++) // переменная m принимает значение 0 или 2.
Теперь компилятор не выдает ошибку.
regfile = "attiny13.dat"
$crystal = 1200000
$hwstack = 16
$swstack = 16
$framesize = 16
Ddrb = &B00000111 'pb0-R,pb1-Y,pb2-G
do
Portb = &B00000001 'R
wait 1
Portb = &B00000010 'Y
wait 1
Portb = &B00000100 'G
wait 1
Portb = &B00000010 'Y
wait 1
Loop
Как и обещал 10 строк кода 176 байт .Изменения через 1 сек.
Для сравнения, попробовал #17 собрать и зашить, чтобы оживить коня вакуумного. Вылавливаю блох из кода атмеги8, и все нужное под рукой. Мигает как настоящий, только "заканчивай переход" не говорит.
$ cat >main.c
#include <avr/io.h>
#include <util/delay.h>
#define INIT() { DDRB |= (1 << PB0 | 1 << PB1 | 1 << PB2); }
#define GREEN_LIGHT() { PORTB |= (1 << PB0); _delay_ms(3000); PORTB ^= (1 << PB0); }
#define GREEN_BLINK() { for(uint8_t i=0; i<6; i++) { PORTB ^= (1 << PB0); _delay_ms(500); } }
#define YELLOW_LIGHT() { PORTB |= (1 << PB2); _delay_ms(1000) ; PORTB ^= (1 << PB2); }
#define RED_LIGHT() { PORTB |= (1 << PB1); _delay_ms(3000); PORTB ^= (1 << PB1); }
#define REDYELL_LIGHT() { PORTB |= (1<<PB2 | 1<<PB1); _delay_ms(1000); PORTB &= ~(1<<PB2 | 1<<PB1); }
int main(void){
INIT();
while(1){
RED_LIGHT(); REDYELL_LIGHT();
GREEN_LIGHT(); GREEN_BLINK();
YELLOW_LIGHT();
}
}
$ avr-gcc -fno-stack-protector -fno-pic -Wall -DF_CPU=4000000 -mmcu=atmega8 -Os -c main.c -o main
$ avr-size main
text data bss dec hex filename
152 0 0 152 98 main
$ avr-gcc --version
avr-gcc (Gentoo Hardened 10.2.0-r5 p6) 10.2.0
----
не слинкованный приложил, прошивка больше будет
avr-size main.hex
text data bss dec hex filename
0 3088 0 3088 c10 main.hex
Writing | #################### #################### ########## | 100% 0.93s
avrdude: 3088 bytes of flash written
Надо за ассемблер садиться (:
Последний раз редактировалось ozforester; 18.04.2021 в 20:03.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)