Вопросы по С/С++ (СИ)
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: Вопросы по С/С++ (СИ)
создал в папке проекта где hex delay.h в блокноте написал F_CPU 9600000, частота как в претусе ну и сточку в программе #include <util/delay.h>
в претусе заморгало, буду играться теперь с частотой мигания.
выявлено нестабильность в моргании...
в тексте надо частоту цпу прописывать или фъюзы в avrstudio5 или достаточно в delay.h только указать?
в претусе заморгало, буду играться теперь с частотой мигания.
выявлено нестабильность в моргании...
в тексте надо частоту цпу прописывать или фъюзы в avrstudio5 или достаточно в delay.h только указать?
Последний раз редактировалось Mishany Сб июл 20, 2013 14:47:37, всего редактировалось 1 раз.
- blackx
- Говорящий с текстолитом
- Сообщения: 1518
- Зарегистрирован: Пт дек 28, 2012 21:56:46
- Откуда: St. Petersburg
Re: Вопросы по С/С++ (СИ)
VHEMaster писал(а):Можно сказать? Работа библиотеки 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).
only pure true norwegian blackx 
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: Вопросы по С/С++ (СИ)
спасибо, буду пробовать, сразу не придал значения этому, точнее пропустил мимо ушей)))
Re: Вопросы по С/С++ (СИ)
ограничение для _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.
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Дело не в максимуме - VHEMaster , скорее всего, пользуется библиотекой из семплов хайтека - а она написана с ошибкой.
Существует альтернатива
https://notendur.hi.is//~tryggvh/mechat ... ts/delay.h
https://notendur.hi.is//~tryggvh/mechat ... ts/delay.c
я этим пользуюсь
Существует альтернатива
https://notendur.hi.is//~tryggvh/mechat ... ts/delay.h
https://notendur.hi.is//~tryggvh/mechat ... ts/delay.c
я этим пользуюсь
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: Вопросы по С/С++ (СИ)
blackx писал(а):VHEMaster писал(а):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
похоже avrstudio глючит либо криво встала
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: Вопросы по С/С++ (СИ)
вроде заработало)
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Mishany писал(а): #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
похоже avrstudio глючит либо криво встала
Это не студия глючит, в самой библиотеке заложено данное сообщение. Для полного использования нужно включить оптимизацию.
- VHEMaster
- Потрогал лапой паяльник
- Сообщения: 374
- Зарегистрирован: Сб июл 14, 2012 09:20:09
- Откуда: Украина, город Полтава
Re: Вопросы по С/С++ (СИ)
urry писал(а):Дело не в максимуме - VHEMaster , скорее всего, пользуется библиотекой из семплов хайтека - а она написана с ошибкой.
Верно.. Попробую использовать ваши.
Добавил
Секундочку.. В вашем delay.c есть строка #include "always.h" Что это за файл?
- blackx
- Говорящий с текстолитом
- Сообщения: 1518
- Зарегистрирован: Пт дек 28, 2012 21:56:46
- Откуда: St. Petersburg
Re: Вопросы по С/С++ (СИ)
only pure true norwegian blackx 
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
оно там не юзается, можно заремить.
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
Привет, коты:) Подскажите, пожалуйста, вот в чём: нужно сделать так, чтобы контроллер висел ничего не делая, пока не произойдёт прерывание, которое должно перенести его на выполнение чего-то. Я это вижу так: делаю w=1, while(1) {}, в прерывании w=0. Контроллер должен будет перейти на строку после while. Тут я наткнулся на то, что если внутри {} ничего нет, то он из этой петли никогда не выходит. Вот вопрос, что эквивалентно пустому действию, которое можно туда записать?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
volatile char w=1;
обработчик прерывания()
{
w = 0;
}
main()
{
while(1)
{
// ждем, когда w станет нулем:
while(w){}
// здесь что-то делаем
...
w = 1;
// и идем опять ждать
}
}- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
a_skr, почитав вот это я понял, что дело должно быть в volatile, щас попробую, спасибо!
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: Вопросы по С/С++ (СИ)
c delay пока так и не разобрался с прописыванием частоты и фьюзов, но зато немного разобрался в использовании EEPROM
моя програмка с памятью последнего включенного режима из трех,
из фьюзов ckdiv8
работает на attiny13a
после компиляции, hex был зашит в реальный МК и проверен на работоспособность.
надеюсь кому из новичков это пригодиться.
и вот тоже самое только без использования кнопки))
функцию кнопки теперь выполняет вк/вык питание схемы, т.е. при каждом последующем включении схемы будет меняться режим.
delay не дает мне покоя..... можно разжевать?
У меня AVR Studio5
в шапке программы пишем:
задаем частоту
прописываем библиотеку
в тексте программы используем
если не трогать фьюзы на прошитом мк нет никакой реакции на изменение частоты
может надо какие фьюзы включить/отключить?
я немного некоторые потыкал в Fuse Low Byte туда сюда результат нулевой, остальный не трогал чтобы не запороть мк.
моя програмка с памятью последнего включенного режима из трех,
из фьюзов 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 раз.
Причина: Нарушение п.п. 2.2 и 2.5 Правил Форума
Причина: Нарушение п.п. 2.2 и 2.5 Правил Форума
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
Коты, я реально не догоняю, то ли лыжи не едут, то ли. Мля.
Вот кусок ТУПОГО, ПРОСТОГО, блин, кода.
Визуально он шлёт буквы на дисплей. ВКЛ выкл мотор. Но, если раскомментировать //TIMSK=(~(1<<OCIE1A));, его величество уже не отключит мотор. Если заменить PORT_SIG^=0b00000010; на motor(); в которую написать то же самое, его величество включит мотор, а вот выключать уже не будет. Я уже офонарел, если честно, 50 раз перечитывать эту сраную(не побоюсь этого слова!) программу. Подскажите, пожалуйста, что компилятору не нравится, раз он до МК доносит какой-то бред. Или я не правильно "объясняю" компилятору то, чего я хочу?
Вот кусок ТУПОГО, ПРОСТОГО, блин, кода.
Код: Выделить всё
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 раз перечитывать эту сраную(не побоюсь этого слова!) программу. Подскажите, пожалуйста, что компилятору не нравится, раз он до МК доносит какой-то бред. Или я не правильно "объясняю" компилятору то, чего я хочу?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Re: Вопросы по С/С++ (СИ)
Тут есть волшебная проблема цикла.

Между двумя переключениями мотор просто не успеет среагировать. И будет казаться, что он либо постоянно включен, либо постоянно выключен. Ну а таймер, похоже, влияет косвенно.

Между двумя переключениями мотор просто не успеет среагировать. И будет казаться, что он либо постоянно включен, либо постоянно выключен. Ну а таймер, похоже, влияет косвенно.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
YS, привет!
Поэксперементировать я смогу только завтра, но тут вот что: последней строчкой стоит w=0, что не даст циклу начаться заново без повторного нажатия кнопки, которое присвоит в w=1 и значение переменной в условии выполнения станет истинным... Да и не реагирование на motor();, повторяющее в себе PORT_SIG^=0b00000010; так и остаётся непонятным 
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Re: Вопросы по С/С++ (СИ)
Ага, привет.
Вообще, непонятно, ради чего тут используется XOR. Я бы просто включал/выключал установкой/снятием бита. XOR дает некоторую неопределенность.
Вообще, непонятно, ради чего тут используется XOR. Я бы просто включал/выключал установкой/снятием бита. XOR дает некоторую неопределенность.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
- VHEMaster
- Потрогал лапой паяльник
- Сообщения: 374
- Зарегистрирован: Сб июл 14, 2012 09:20:09
- Откуда: Украина, город Полтава
Re: Вопросы по С/С++ (СИ)
Вот что я могу вам предложить. Вы перестанете ломать голову над этой прошивкой, а я вам бесплатно напишу прошивку под ваше усмотрение на Си, но только на PIC. С ними проще по-моему