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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
SSERG
Родился
Сообщения: 4
Зарегистрирован: Пн мар 21, 2011 22:31:30

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

Сообщение SSERG »

ChipKiller писал(а):... прочитать порт можно и проще, зачем так все усложнять?

в этом и вопрос,я догадался что делаю все через ж...... -поэтому просьба подскажите как,сам пока догнать не могу!
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

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

Сообщение ChipKiller »

SSERG писал(а):в этом и вопрос,я догадался что делаю все через ж..
... дело не в этом
SSERG писал(а):Подскажите как можно проще опрашивать много портов и сравнивать значения с другими портами
... любая программа начинается с задачи и понимания того, что Вам нужно получить.... угадать тяжело и помочь тоже
SSERG
Родился
Сообщения: 4
Зарегистрирован: Пн мар 21, 2011 22:31:30

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

Сообщение SSERG »

Суть программы вот в чём опросить порты входа,если 0 включить 1 на соответствующем выходе,если на выходе был 0 вкл тревогу если 1 не включать.........
и.т.д для 8 портов,как при сканировании входов узнать была ли 1 на выходе и ещё как програмно приравнять значение порта к переменной в принципе в в этом коде всё работает,только как-то я всё усложнил....
koldune
Родился
Сообщения: 5
Зарегистрирован: Вт фев 22, 2011 16:30:10

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

Сообщение koldune »

Товарищи, помогите :?

Написал программу стрелочного тахометра. Работает так: ловим первый импульс - синхронизируемся, ловим второй - запускаем TMR1, ловим третий - останавливаем TMR1 и идём показывать то, что насчитали, на индикатор. Чтобы индикатор на шаговике корректно работал и опускал стрелку в ноль, когда вал остановится, нужен какой-нибудь контроль остановки вала. Иначе программа будет ждать первого или второго импульса (если не дождётся третьего - ничего страшного, по переполнению TMR1 подпрограмма пойдёт в return). Подскажите, как сделать, чтобы если в течение, скажем, 0.2 секунды не поступило импульсов на вход процессора, подпрограмма измерения оборотов уходила бы в return?
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

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

Сообщение aleksey_gregul »

koldune писал(а):Товарищи, помогите :?

Зачем так делаете?
Почитайте про input capture.
Специально для этого случая.
Ничего не нужно стартовать, останавливать, дожидаться...
Все происходит на аппаратном уровне.
Ваша же задача - только прочитать ICR
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Не уточняется, что за контролер и что за TMR1 (с какими возможностями), поэтому рассчитываю на TMR1 с возможностью захвата и входом ICP1.
Считается, что период входных импульсов меньше периода переполнения таймера. Если больше, то тоже можно выкрутиться, но это отдельная песня.
  • Таймер не останавливается, бежит всегда.
  • По переполнению таймера инкрементируется счётчик защиты от пропадания импульсов на входе. Если счётчик уже равен 2, то дальше не инкрементируется (чтобы не досчитал опят до 0, а то будет как в инцидентах на Therac-25). Доход до 2 означает пропажу импульсов на входе (падение ниже уровня чувствительности, для таксометра я выбирал прескалер так, чтобы такая ситуация была при падени скорости ниже 2км/ч).
  • По прерыванию от входа захвата ICP содержимое ICP1 берётся в работу в переменную icp1_new и
    • Если счётчик защиты меньше или равен 1, то вычисляется delta = icp1_new - icp1_prev (содержимое будет правильным даже если было переполнение таймера!). Если нужно, delta дальше идёт в фильтрацию, чтобы сгладить колебания.
    • icp1_new записывается в icp1_prev (даже если счётчик защиты был 2).
  • По каждому прерыванию ICP счётчик защиты обнуляется.

Таким образом по каждому импульсу на ICP1 (кроме первого после паузы) имеем отсчёт времени.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

aleksey_gregul писал(а):
koldune писал(а):Товарищи, помогите :?

Зачем так делаете?
Почитайте про input capture.
Специально для этого случая.
Алексей, доброго здоровья!
Вот и я о том же. Даже довольно скромные (по сравнению с разными ARM7 и Cortex-M3) таймера AVR позволяют много сделать аппаратно.

Более того, в описанном применении у таймера 1 модули OCR остаются свободными и на них можно сделать таймера с любой частотой выше частоты переполнения таймера, просто в каждом прерывании, к примеру, OCR1A писать

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

OCR1A += OCR1A_PERIOD;

Таким образом даже если по показаниям для тахометра/одометра нужно прескалером сделать период переполнения около секунды, на том же таймере можно организовать ещё прерывания с частотой, к примеру, около килогерца (для динамической индикации), просто сделав OCR1A_PERIOD 65 (65536/1000). Для динамической индикации точная частота не важна.

Второй канал OCR1B кроме прерывания ещё заставить инвертировать ножку, при этом на пьезопискунчик можно будет давать меандр с периодом 2*ocr1b_period, т.е. меняя уже не константу, а переменную ocr1a_period можно на пискунчик выдавать разные тона от пары килогерц и ниже. Тоже не точно выставив частоту, но в большинстве случаев для оператора достаточно различия "пикнуло высоким тоном" / "пискнуло низким тоном".

При этом остальные таймера свободны, хотя уже куча всего сделана :-)
Есть чем и шаговый двигатель термопринтера окучить, и его термоголовку :-)
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

avreal писал(а):Если счётчик защиты меньше или равен 1, то вычисляется delta = icp1_new - icp1_prev (содержимое будет правильным даже если было переполнение таймера!). Если нужно, delta дальше идёт в фильтрацию, чтобы сгладить колебания.
Ага, вот что значит переэкономить аппаратные ресурсы. В реальном проекте у меня было немного не так (об этом ниже), а тут я на ходу решил сэкономить ещё один канал захвата и в результате не всегда будет правильно.
Если интервал периода таймера (65536) или больше, но меньше двух периодов, то тут соврёт. Это надо анализировать сотношение icp1_new и icp1_prev вместе с защитным счётчиком и иногда поглядывать на флаг прерывания переполнения таймера, короче, уже всё делать как для полноценного расширения рахрядности таймера дополнительной переменной.

А в реальном проекте у меня выходило так, что интервал между импульсами больше где-то 50000 отсчётов уже считался «бесконечностью» и на практике не интересовал. В итоге было как-то так

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

ISR(TIMER1_CAPT_vect) {
    uint16_t icr1_new = ICR1;
    // отодвигаем прерывание TIMER1_COMPA_vect максимально далеко от момента захвата
    OCR1A = icr1_new - 1;
    TIFR1 = 1 << OCF1A; сбрасываем на всякий случай, вдруг как раз на предыдущих командах поднялся
    // Обрабатываем icr1_new как описано выше, только как признак "предыдущего импульса не было"
    // используем флаг, поднимаемый в TIMER1_COMPA_vect. Тут его сбрасываем.
    // ...
}
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

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

Сообщение Chip115 »

Всем привет!
написал код для контроллера, но компилятор (Keil uVision) выдает предупреждения типа
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: NFREQ
MODULE: main_prog.obj (MAIN_PROG)
ADDRESS: 0255H
что я натворил в целом.
Прописал все переменные в h-файле под именем Global Constants.h (не задумывайтесь над логикой названия файла с переменными. сам не знаю :) )
Вот его содержимое

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

//----------
// Global Constants
//----------



extern int mas[]={0x36,0x2E,0x1E,0x35,0x2D,0x1D,0x33,0x2B,0x1B};    // ìàññèâ ñîñòîÿíèé êëàâèàòóðû
extern int alfa,betta,nfreq,timer_lo,timer_hi;
extern int flag_1=0;
extern char    mean_time=0,
      St_M2=0;
      FREV=0;         // Ôëàã ðåâåðñà. FREV=0 - ðåâåðñà íåò
      REV=0;
      COLS=0;         // ñ÷åò÷èê äëÿ âûâîäà çíà÷åíèé íà èíëèêàòîð äëÿ øòàíãè
      COLL=0;         // ñ÷åò÷èê äëÿ âûâîäà çíà÷åíèé íà èíëèêàòîð äëÿ ëåíòû
      COLL_1=0;
      mas2[]={0,1,2,3,4,5,6,7,8,9};
      i=0;

extern char freq []={0xD8,0xDC,0xDF,0xE1,0xE3,0xE5,0xE7,0xE8,0xEA,0xEB,0xEC};   // means of freq from 50 to 100 Hz step 5
static int counter = 0;
extern void delay_ms (unsigned int delay);

Не могу понять откуда ворнинги? Причем их за 70 штук
Впервые попытался написать h-файл . До этого я не пользовался extern-ном.
Помогите разораться, где "накосячил" ))
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

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

Сообщение lix »

в хидере надо просто описывать переменные без инициализации, а определять в с-файле и инициализировать там же
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

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

Сообщение Chip115 »

т.е так для h

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


extern int mas[]={};   



а в си файле

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

int mas[]={0x36,0x2E,0x1E,0x35,0x2D,0x1D,0x33,0x2B,0x1B};    


?
И я еще не до конца понял назначение extern
Можете объяснить?:)
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

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

Сообщение lix »

для хидера

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

extern int mas[]


назначение extern состоит в том, чтобы сказать компилеру, что данная данный объект определен в другом модуле.
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

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

Сообщение O-LED »

Подскажите, будут ли генерироваться прерывания КАЖДЫЙ ТИК таймера

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

interrupt [TIM2_COMP] void timer2_comp_isr(void)  //  прерывание Т2 по совпадению
{
OCR2++;
********ОБРАБОТЧИК ПРЕРЫВАНИЯ***********
}
KIT
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

будут генерироваться только в том случае, если за один тик таймера программа успеет войти в прерывание, выполнить обработчик и выйти из прерывания (такое возможно при достаточно большом предделителе и достаточно малом времени выполнения обработчика)

p.s. и если таймер не работает в PWM режиме, т.к. в этом случае OCR записывается не сразу в регистр, а только во временный регистр, откуда при переполнении таймера окончательно переписывается в регистр OCR
Ставим плюсы: )
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

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

Сообщение Chip115 »

не подскажите, как можно оптимизировать код. у меня есть куча массивов, но памяти ограниченно.
например вот

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

unsigned char  cmd_RESET[5] =   {0xE3, 0x10, 0x00, 0x30, 0x00};
unsigned char const cmd_PPWM[5] =    {0xE3, 0x10, 0x00, 0x50, 0x00};
unsigned char const cmd_DEADT[5] =   {0xE3, 0x00, 0x36, 0x24, 0x00}; // 4.5 мкс  мертвое время  24
unsigned char const cmd_ACB[5] =     {0xE3, 0x10, 0x00, 0x61, 0x00}; //  50 Гц   базовая частота
unsigned char const cmd_ACC[5] =     {0xE4, 0x00, 0x60, 0x05, 0x00}; //    ускорение
unsigned char const cmd_F[5] =       {0xE4, 0x00, 0x62, 0x3C, 0x99}; //  задание синусоидальной частоты
unsigned char const cmd_FPWM[5] =    {0xE3, 0x10, 0x00, 0x42, 0x00}; //10.6 кГц  частота ШИМ
unsigned char const cmd_VBOOST[5] =  {0xE3, 0x00, 0x6C, 0x00, 0x00}; //   0 %    амплитуда синуса при нулевой синусоидальной частоте
unsigned char const cmd_MODIN[5] =   {0xE3, 0x00, 0x75, 0xFE, 0x00}; //  99 %    индекс модуляции синуса (амплитуда)
unsigned char const cmd_FTOUT[5] =   {0xE4, 0x00, 0x6A, 0x00, 0x08}; // таймаут после аварии
unsigned char const cmd_VBDEC[5] =   {0xE4, 0x00, 0xC9, 0x03, 0x55}; // 119 %    значение Vbus при котором начинается снижение скорости торможения
unsigned char const cmd_VBRAKE[5] =  {0xE4, 0x00, 0x64, 0x03, 0x55}; // 119 %    значение Vbus при котором появляется сигнал вкл. тормозного  VT
unsigned char const cmd_VBROWN[5] =  {0xE4, 0x00, 0x66, 0x80, 0x00}; //  50 %    нижнее значение Vbus при откл. ШИМ и появляется сигнал аварии   
unsigned char const cmd_VBOVR[5] =   {0xE4, 0x00, 0x68, 0x03, 0x71}; // 123 %    верхнее значение Vbus при откл. ШИМ и появляется сигнал аварии
unsigned char const cmd_FORW[5] =    {0xE3, 0x10, 0x00, 0x10, 0x00}; // "вперед"
unsigned char const cmd_REW[5] =     {0xE3, 0x10, 0x00, 0x11, 0x00}; // "назад"
unsigned char const cmd_STOP[5] =    {0xE3, 0x10, 0x00, 0x20, 0x00}; // "стоп"
unsigned char const read_ACTF[3] =   {0xD1, 0x00, 0x85};             // прочитать текущюю синусоидальную частоту
unsigned char const read_SETUP[3] =  {0xD0, 0x00, 0xAE};             // прочитать регистр установок
unsigned char const read_VBUS[3] =   {0xD1, 0x00, 0x79};             // прочитать напряжение питания инвертора (DC_bus)
unsigned char const read_F[3] =      {0xD1, 0x00, 0x62};             // прочитать задание на синусоидальную частоту
unsigned char const read_STATUS[3] = {0xD0, 0x00, 0xC8};             // прочитать регистр статуса

можно как нибудь сократить объем памяти занимаемый этими массивами?
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

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

Сообщение md5sum »

Можно константы объявить с префиксом PROGMEM, не забыв #include <avr/pgmspace.h>
И при необходимости использовать функции описанные в указанном pgmspace.h
— Не говорите мне что делать и я не скажу куда Вам идти...
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20091
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

md5sum писал(а):Можно константы объявить с префиксом PROGMEM, не забыв #include <avr/pgmspace.h>
И при необходимости использовать функции описанные в указанном pgmspace.h

Открою небольшой секрет: Chip115 работает с СиЛабовскими контроллерами, а не АВРовскими.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Тогда надо смотреть, какое ключевое слово нужно компилятору. Уж не помню в каком компиляторе, с 51-ми лет 10 не работаю, а до того использовал AVOCET и KEIL (скорее всего в обеих было одинаково, а в AVOCET просто не было слова bit для возвращаемого функией значения), были слова code, idata, xdata для управления размещением.
Например, так:
unsigned char const code cmd_PPWM[5] = {0xE3, 0x10, 0x00, 0x50, 0x00};

и это же code во всех указателях, которые могут принимать этот массив:
bit process_command(unsigned char const code *pcmd);
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20091
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

Да, avreal, ваша правда:
Изображение
Вложения
Безымянный.GIF
(13.53 КБ) 607 скачиваний
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Ответить

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