Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Mishany
Электрический кот
Сообщения: 1031
Зарегистрирован: Чт июн 20, 2013 00:00:58
Откуда: москва, м.Сходненская

Re: Вопросы по С/С++ (СИ)

Сообщение Mishany »

создал в папке проекта где hex delay.h в блокноте написал F_CPU 9600000, частота как в претусе ну и сточку в программе #include <util/delay.h>
в претусе заморгало, буду играться теперь с частотой мигания.
выявлено нестабильность в моргании...
в тексте надо частоту цпу прописывать или фъюзы в avrstudio5 или достаточно в delay.h только указать?
Последний раз редактировалось Mishany Сб июл 20, 2013 14:47:37, всего редактировалось 1 раз.
Аватара пользователя
blackx
Говорящий с текстолитом
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Re: Вопросы по С/С++ (СИ)

Сообщение blackx »

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: Вопросы по С/С++ (СИ)

Сообщение Mishany »

спасибо, буду пробовать, сразу не придал значения этому, точнее пропустил мимо ушей)))
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Вопросы по С/С++ (СИ)

Сообщение a_skr »

blackx писал(а):Есть известные ограничения на максимальные значения задержек. Они указаны в документации 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.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение urry »

Дело не в максимуме - VHEMaster , скорее всего, пользуется библиотекой из семплов хайтека - а она написана с ошибкой.
Существует альтернатива
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: Вопросы по С/С++ (СИ)

Сообщение Mishany »

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: Вопросы по С/С++ (СИ)

Сообщение Mishany »

вроде заработало)
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

Mishany писал(а): #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"

похоже avrstudio глючит либо криво встала

Это не студия глючит, в самой библиотеке заложено данное сообщение. Для полного использования нужно включить оптимизацию.
Аватара пользователя
VHEMaster
Потрогал лапой паяльник
Сообщения: 374
Зарегистрирован: Сб июл 14, 2012 09:20:09
Откуда: Украина, город Полтава

Re: Вопросы по С/С++ (СИ)

Сообщение VHEMaster »

urry писал(а):Дело не в максимуме - VHEMaster , скорее всего, пользуется библиотекой из семплов хайтека - а она написана с ошибкой.

Верно.. Попробую использовать ваши.

Добавил
Секундочку.. В вашем delay.c есть строка #include "always.h" Что это за файл?
Всем канифоли :)
https://vk.com/maks_naumchuk
Аватара пользователя
blackx
Говорящий с текстолитом
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Re: Вопросы по С/С++ (СИ)

Сообщение blackx »

Как несложно догадаться, он лежит там же :)

https://notendur.hi.is/~tryggvh/mechatronics/documents/
Изображение only pure true norwegian blackx Изображение
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение urry »

оно там не юзается, можно заремить.
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение Мikа »

Привет, коты:) Подскажите, пожалуйста, вот в чём: нужно сделать так, чтобы контроллер висел ничего не делая, пока не произойдёт прерывание, которое должно перенести его на выполнение чего-то. Я это вижу так: делаю w=1, while(1) {}, в прерывании w=0. Контроллер должен будет перейти на строку после while. Тут я наткнулся на то, что если внутри {} ничего нет, то он из этой петли никогда не выходит. Вот вопрос, что эквивалентно пустому действию, которое можно туда записать?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Вопросы по С/С++ (СИ)

Сообщение a_skr »

Код: Выделить всё

volatile char w=1;

обработчик прерывания()
{
  w = 0;
}

main()
{
  while(1)
  {
    // ждем, когда w станет нулем:
    while(w){}
    // здесь что-то делаем
    ...
    w = 1;
    // и идем опять ждать
  }
}
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение Мikа »

a_skr, почитав вот это я понял, что дело должно быть в volatile, щас попробую, спасибо!
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
Mishany
Электрический кот
Сообщения: 1031
Зарегистрирован: Чт июн 20, 2013 00:00:58
Откуда: москва, м.Сходненская

Re: Вопросы по С/С++ (СИ)

Сообщение Mishany »

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 раз.
Причина: Нарушение п.п. 2.2 и 2.5 Правил Форума
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение Мikа »

Коты, я реально не догоняю, то ли лыжи не едут, то ли. Мля.
Вот кусок ТУПОГО, ПРОСТОГО, блин, кода.

Код: Выделить всё

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
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение YS »

Тут есть волшебная проблема цикла.

Изображение

Между двумя переключениями мотор просто не успеет среагировать. И будет казаться, что он либо постоянно включен, либо постоянно выключен. Ну а таймер, похоже, влияет косвенно.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение Мikа »

YS, привет! :) Поэксперементировать я смогу только завтра, но тут вот что: последней строчкой стоит w=0, что не даст циклу начаться заново без повторного нажатия кнопки, которое присвоит в w=1 и значение переменной в условии выполнения станет истинным... Да и не реагирование на motor();, повторяющее в себе PORT_SIG^=0b00000010; так и остаётся непонятным :(
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение YS »

Ага, привет.

Вообще, непонятно, ради чего тут используется XOR. Я бы просто включал/выключал установкой/снятием бита. XOR дает некоторую неопределенность.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
VHEMaster
Потрогал лапой паяльник
Сообщения: 374
Зарегистрирован: Сб июл 14, 2012 09:20:09
Откуда: Украина, город Полтава

Re: Вопросы по С/С++ (СИ)

Сообщение VHEMaster »

Вот что я могу вам предложить. Вы перестанете ломать голову над этой прошивкой, а я вам бесплатно напишу прошивку под ваше усмотрение на Си, но только на PIC. С ними проще по-моему
Всем канифоли :)
https://vk.com/maks_naumchuk
Ответить

Вернуться в «Разные вопросы по МК»