в претусе заморгало, буду играться теперь с частотой мигания.
выявлено нестабильность в моргании...
в тексте надо частоту цпу прописывать или фъюзы в avrstudio5 или достаточно в delay.h только указать?
Есть известные ограничения на максимальные значения задержек. Они указаны в документации avr-glibc к этим функциям. Например, максимальная задержка функции _delay_ms при частоте 1 МГц составляет 262,14 мс. Это значение пропорционально уменьшается с увеличением частоты. Нужно это учитывать при использовании функций.VHEMaster писал(а): Можно сказать? Работа библиотеки delay.h меня не порадовала т.к. вела себя нестабильно при больших значениях DelayUs и DelayMs
Код: Выделить всё
#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>
int main() {
//...
}
only pure true norwegian blackx 
ограничение для _delay_ms() - 6.5535 секунд, просто уменьшается дискрет до 1/10 мс (независимо от частоты МК):blackx писал(а):Есть известные ограничения на максимальные значения задержек. Они указаны в документации avr-glibc к этим функциям. Например, максимальная задержка функции _delay_ms при частоте 1 МГц составляет 262,14 мс. Это значение пропорционально уменьшается с увеличением частоты. Нужно это учитывать при использовании функций.
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.
так пишет ошибкуblackx писал(а):VHEMaster писал(а): Mishany, не очень понял, что вы сделали. Вам нужно просто добавить #include <util/delay.h> в начало вашей программы, а перед этим - указать значение тактовой частоты (если вы уже не задали ее где-нибудь в настройках проекта), вот так:).Код: Выделить всё
#define F_CPU 1000000UL // 1 MHz #include <util/delay.h> int main() { //... }
Это не студия глючит, в самой библиотеке заложено данное сообщение. Для полного использования нужно включить оптимизацию.Mishany писал(а): #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
похоже avrstudio глючит либо криво встала
Верно.. Попробую использовать ваши.urry писал(а):Дело не в максимуме - VHEMaster , скорее всего, пользуется библиотекой из семплов хайтека - а она написана с ошибкой.
only pure true norwegian blackx 
Код: Выделить всё
volatile char w=1;
обработчик прерывания()
{
w = 0;
}
main()
{
while(1)
{
// ждем, когда w станет нулем:
while(w){}
// здесь что-то делаем
...
w = 1;
// и идем опять ждать
}
}Код: Выделить всё
#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;
}Код: Выделить всё
#define F_CPU хххUL // ххх MHzКод: Выделить всё
#include <util/delay.h>Код: Выделить всё
_delay_ms()Код: Выделить всё
#define F_CPU хххUL // ххх MHzКод: Выделить всё
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;
}
}