создал в папке проекта где hex delay.h в блокноте написал F_CPU 9600000, частота как в претусе ну и сточку в программе #include <util/delay.h> в претусе заморгало, буду играться теперь с частотой мигания. выявлено нестабильность в моргании... в тексте надо частоту цпу прописывать или фъюзы в avrstudio5 или достаточно в delay.h только указать?
Последний раз редактировалось Mishany Сб июл 20, 2013 14:47:37, всего редактировалось 1 раз.
Можно сказать? Работа библиотеки delay.h меня не порадовала т.к. вела себя нестабильно при больших значениях DelayUs и DelayMs
Есть известные ограничения на максимальные значения задержек. Они указаны в документации avr-glibc к этим функциям. Например, максимальная задержка функции _delay_ms при частоте 1 МГц составляет 262,14 мс. Это значение пропорционально уменьшается с увеличением частоты. Нужно это учитывать при использовании функций.
Mishany, не очень понял, что вы сделали. Вам нужно просто добавить #include <util/delay.h> в начало вашей программы, а перед этим - указать значение тактовой частоты (если вы уже не задали ее где-нибудь в настройках проекта), вот так:
Код:
#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>
int main() { //... }
Тогда вам станут доступны функции _delay_ms(double __ms) и _delay_us(double __us).
Есть известные ограничения на максимальные значения задержек. Они указаны в документации avr-glibc к этим функциям. Например, максимальная задержка функции _delay_ms при частоте 1 МГц составляет 262,14 мс. Это значение пропорционально уменьшается с увеличением частоты. Нужно это учитывать при использовании функций.
ограничение для _delay_ms() - 6.5535 секунд, просто уменьшается дискрет до 1/10 мс (независимо от частоты МК):
Цитата:
void _delay_ms ( double __ms ) Perform a delay of __ms milliseconds, using _delay_loop_2().
The macro F_CPU is supposed to be defined to a constant defining the CPU clock frequency (in Hertz).
The maximal possible delay is 262.14 ms / F_CPU in MHz.
When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.
Mishany, не очень понял, что вы сделали. Вам нужно просто добавить #include <util/delay.h> в начало вашей программы, а перед этим - указать значение тактовой частоты (если вы уже не задали ее где-нибудь в настройках проекта), вот так:
Код:
#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>
int main() { //... }
).
так пишет ошибку Error 1 delay.h: No such file or directory C:\..............\AVRGCC1\AVRGCC1.с и Warning 1 #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed" d:\atmel\avr studio 5.0\avr toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h 94 3 AVRGCC1
Привет, коты:) Подскажите, пожалуйста, вот в чём: нужно сделать так, чтобы контроллер висел ничего не делая, пока не произойдёт прерывание, которое должно перенести его на выполнение чего-то. Я это вижу так: делаю w=1, while(1) {}, в прерывании w=0. Контроллер должен будет перейти на строку после while. Тут я наткнулся на то, что если внутри {} ничего нет, то он из этой петли никогда не выходит. Вот вопрос, что эквивалентно пустому действию, которое можно туда записать?
_________________ Почему я здесь и задаю тупые вопросы? Потому что хочу научиться.
c delay пока так и не разобрался с прописыванием частоты и фьюзов, но зато немного разобрался в использовании EEPROM моя програмка с памятью последнего включенного режима из трех, из фьюзов ckdiv8 работает на attiny13a после компиляции, hex был зашит в реальный МК и проверен на работоспособность. надеюсь кому из новичков это пригодиться. Спойлер
Код:
#include <avr/io.h> #include <avr/eeprom.h> #define a 3500 //константы для #define b 6500 //удобства их #define c 2500 //корректировки. unsigned char s; //объявляем переменную "s" unsigned char morgalka EEMEM; //определяем переменную в EEPROM
int main(void) { unsigned int x; //объявляем переменную "x" unsigned int y; //объявляем переменную "y" DDRB |= (1<<0) | (1<<1); //порт0 и порт1 на выход PORTB = 0x00; //все порты установить в "0" s = eeprom_read_byte(&morgalka); //считываем байт из EEPROM и помещаем его в "s" y = s; //дублируем "s" в "y" для последующего сравнения, что бы //избежать лишней записи, т.е. что бы запись производилась только в случае изменения, т.е. эта //переменная будет служить "датчиком" изменения режима работы. while (1) { if((PINB&(1<<2))==0) //обработка входа порта2 на наличие на нем "0" //порт через внешний резистор 5кОм подключен к +5В, для имитации "1" { while((PINB&(1 << 2)) == 0){} //цикл пока нажата кнопка... s++; //при отпускании кнопки "s" увеличить на 1 for (x = 0; x < 10000; ++x); //задержка, "должна" устранить дребезг контактов } if (s>=3) //условие переполнения количества режимов с { s = 0; //последующим сбросом в "0" } if (s!=y) //условие: если изменился режим, то { y = s; //сбрасываем "датчик" изменения режима eeprom_write_byte(&morgalka, s); //записываем "s" в EEPROM } if (s==0) //режим "0" { PORTB = 0x03; //на выходы портов 0 и 1 подать "1" for (x = 0; x < a; ++x); //подождать, чтобы увидеть PORTB = 0x00; //подать на все порты "0" for (x = 0; x < b; ++x); //подождать } if (s==1) //режим "1" { PORTB = 0x01; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x01; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x01; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < c; ++x); PORTB = 0x02; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x02; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x02; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < c; ++x); } if (s==2) //режим "2" { PORTB = 0x03; } } return 0; }
и вот тоже самое только без использования кнопки)) функцию кнопки теперь выполняет вк/вык питание схемы, т.е. при каждом последующем включении схемы будет меняться режим. Спойлер
Код:
#include <avr/io.h> #include <avr/eeprom.h> #define a 3500 //константы для #define b 6500 //удобства их #define c 2500 //корректировки. unsigned char s; //объявляем переменную "s" unsigned char morgalka EEMEM; //определяем переменную в EEPROM
int main(void) { unsigned int x; //объявляем переменную "x" DDRB |= (1<<0) | (1<<1); //порт0 и порт1 на выход PORTB = 0x00; //все порты установить в "0" s = eeprom_read_byte(&morgalka); //считываем байт из EEPROM и помещаем его в "s" s++; //при подачи питания на схему"s" увеличить на 1 if (s>=3) //условие переполнения количества режимов с s = 0; //последующим сбросом в "0" eeprom_write_byte(&morgalka, s); //записываем "s" в EEPROM //запись происходит только один раз при подачи питания на схему.
while (1) { if (s==0) //режим "0" { PORTB = 0x03; //на выходы портов 0 и 1 подать "1" for (x = 0; x < a; ++x); //подождать, чтобы увидеть PORTB = 0x00; //подать на все порты "0" for (x = 0; x < b; ++x); //подождать } if (s==1) //режим "1" { PORTB = 0x01; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x01; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x01; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < c; ++x); PORTB = 0x02; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x02; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < a; ++x); PORTB = 0x02; for (x = 0; x < a; ++x); PORTB = 0x00; for (x = 0; x < c; ++x); } if (s==2) //режим "2" { PORTB = 0x03; } } return 0; }
delay не дает мне покоя..... можно разжевать? У меня AVR Studio5 в шапке программы пишем: задаем частоту
Код:
#define F_CPU хххUL // ххх MHz
прописываем библиотеку
Код:
#include <util/delay.h>
в тексте программы используем
Код:
_delay_ms()
если не трогать фьюзы на прошитом мк нет никакой реакции на изменение частоты
Код:
#define F_CPU хххUL // ххх MHz
может надо какие фьюзы включить/отключить? я немного некоторые потыкал в Fuse Low Byte туда сюда результат нулевой, остальный не трогал чтобы не запороть мк.
Последний раз редактировалось Gudd-Head Вт июл 23, 2013 15:15:20, всего редактировалось 1 раз.
Коты, я реально не догоняю, то ли лыжи не едут, то ли. Мля. Вот кусок ТУПОГО, ПРОСТОГО, блин, кода.
Код:
while (1) { while (w!=0) { //Включение двигателя, разгон, PORT_SIG^=0b00000010; //Включить или выключить двигатель _delay_ms(2000);
//Включение таймера, подсчёт прерываний, вычисление скорости timer=0; //Обнуление таймера прерываний (увеличивается на 1 раз в секунду) GICR=(1<<INT0); //Разрешение прерываний на INT0, вращение (ещё пока не используется) counter=0; //Обнуление счётчика прерываний (количество прерываний на оптопаре от синхродиска) TIMSK=(1<<OCIE1A); //Включает и выключает прерывания по таймерам (Совпадение А) TCNT1=0; //Обнуление счётчика таймера LcdWriteData('S'); (просто вывод на дисплей буквы, типа до сюда программа дошла)
while (timer<3) - ждем 3 секунды. считаеем количество прерываний от синхродиска за эти 3 сек) {
}
GICR=(~(1<<INT0)); //Запрещение прерываний на INT0, вращение //TIMSK=(~(1<<OCIE1A)); //Запрет прерываний по таймеру А PORT_SIG^=0b00000010; //Включить или выключить двигатель counter/=3; //Вычисление количества оборотов в минуту w=0; } }
Визуально он шлёт буквы на дисплей. ВКЛ выкл мотор. Но, если раскомментировать //TIMSK=(~(1<<OCIE1A));, его величество уже не отключит мотор. Если заменить PORT_SIG^=0b00000010; на motor(); в которую написать то же самое, его величество включит мотор, а вот выключать уже не будет. Я уже офонарел, если честно, 50 раз перечитывать эту сраную(не побоюсь этого слова!) программу. Подскажите, пожалуйста, что компилятору не нравится, раз он до МК доносит какой-то бред. Или я не правильно "объясняю" компилятору то, чего я хочу?
_________________ Почему я здесь и задаю тупые вопросы? Потому что хочу научиться.
Между двумя переключениями мотор просто не успеет среагировать. И будет казаться, что он либо постоянно включен, либо постоянно выключен. Ну а таймер, похоже, влияет косвенно.
_________________ Разница между теорией и практикой на практике гораздо больше, чем в теории.
YS, привет! Поэксперементировать я смогу только завтра, но тут вот что: последней строчкой стоит w=0, что не даст циклу начаться заново без повторного нажатия кнопки, которое присвоит в w=1 и значение переменной в условии выполнения станет истинным... Да и не реагирование на motor();, повторяющее в себе PORT_SIG^=0b00000010; так и остаётся непонятным
_________________ Почему я здесь и задаю тупые вопросы? Потому что хочу научиться.
Вот что я могу вам предложить. Вы перестанете ломать голову над этой прошивкой, а я вам бесплатно напишу прошивку под ваше усмотрение на Си, но только на PIC. С ними проще по-моему
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения