в этом и вопрос,я догадался что делаю все через ж...... -поэтому просьба подскажите как,сам пока догнать не могу!ChipKiller писал(а):... прочитать порт можно и проще, зачем так все усложнять?
Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
- Реклама
- ChipKiller
- Сверлит текстолит когтями
- Сообщения: 1163
- Зарегистрирован: Ср янв 05, 2011 16:25:15
Re: Вопросы по С/С++ (СИ)
... дело не в этомSSERG писал(а):в этом и вопрос,я догадался что делаю все через ж..
... любая программа начинается с задачи и понимания того, что Вам нужно получить.... угадать тяжело и помочь тожеSSERG писал(а):Подскажите как можно проще опрашивать много портов и сравнивать значения с другими портами
Re: Вопросы по С/С++ (СИ)
Суть программы вот в чём опросить порты входа,если 0 включить 1 на соответствующем выходе,если на выходе был 0 вкл тревогу если 1 не включать.........
и.т.д для 8 портов,как при сканировании входов узнать была ли 1 на выходе и ещё как програмно приравнять значение порта к переменной в принципе в в этом коде всё работает,только как-то я всё усложнил....
и.т.д для 8 портов,как при сканировании входов узнать была ли 1 на выходе и ещё как програмно приравнять значение порта к переменной в принципе в в этом коде всё работает,только как-то я всё усложнил....
Re: Вопросы по С/С++ (СИ)
Товарищи, помогите
Написал программу стрелочного тахометра. Работает так: ловим первый импульс - синхронизируемся, ловим второй - запускаем TMR1, ловим третий - останавливаем TMR1 и идём показывать то, что насчитали, на индикатор. Чтобы индикатор на шаговике корректно работал и опускал стрелку в ноль, когда вал остановится, нужен какой-нибудь контроль остановки вала. Иначе программа будет ждать первого или второго импульса (если не дождётся третьего - ничего страшного, по переполнению TMR1 подпрограмма пойдёт в return). Подскажите, как сделать, чтобы если в течение, скажем, 0.2 секунды не поступило импульсов на вход процессора, подпрограмма измерения оборотов уходила бы в return?
Написал программу стрелочного тахометра. Работает так: ловим первый импульс - синхронизируемся, ловим второй - запускаем TMR1, ловим третий - останавливаем TMR1 и идём показывать то, что насчитали, на индикатор. Чтобы индикатор на шаговике корректно работал и опускал стрелку в ноль, когда вал остановится, нужен какой-нибудь контроль остановки вала. Иначе программа будет ждать первого или второго импульса (если не дождётся третьего - ничего страшного, по переполнению TMR1 подпрограмма пойдёт в return). Подскажите, как сделать, чтобы если в течение, скажем, 0.2 секунды не поступило импульсов на вход процессора, подпрограмма измерения оборотов уходила бы в return?
- aleksey_gregul
- Встал на лапы
- Сообщения: 130
- Зарегистрирован: Ср дек 29, 2010 17:30:34
Re: Вопросы по С/С++ (СИ)
Зачем так делаете?koldune писал(а):Товарищи, помогите![]()
Почитайте про input capture.
Специально для этого случая.
Ничего не нужно стартовать, останавливать, дожидаться...
Все происходит на аппаратном уровне.
Ваша же задача - только прочитать ICR
- Реклама
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Не уточняется, что за контролер и что за 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 счётчик защиты обнуляется.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Алексей, доброго здоровья!aleksey_gregul писал(а):Зачем так делаете?koldune писал(а):Товарищи, помогите![]()
Почитайте про input capture.
Специально для этого случая.
Вот и я о том же. Даже довольно скромные (по сравнению с разными ARM7 и Cortex-M3) таймера AVR позволяют много сделать аппаратно.
Более того, в описанном применении у таймера 1 модули OCR остаются свободными и на них можно сделать таймера с любой частотой выше частоты переполнения таймера, просто в каждом прерывании, к примеру, OCR1A писать
Код: Выделить всё
OCR1A += OCR1A_PERIOD;Второй канал OCR1B кроме прерывания ещё заставить инвертировать ножку, при этом на пьезопискунчик можно будет давать меандр с периодом 2*ocr1b_period, т.е. меняя уже не константу, а переменную ocr1a_period можно на пискунчик выдавать разные тона от пары килогерц и ниже. Тоже не точно выставив частоту, но в большинстве случаев для оператора достаточно различия "пикнуло высоким тоном" / "пискнуло низким тоном".
При этом остальные таймера свободны, хотя уже куча всего сделана
Есть чем и шаговый двигатель термопринтера окучить, и его термоголовку
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ага, вот что значит переэкономить аппаратные ресурсы. В реальном проекте у меня было немного не так (об этом ниже), а тут я на ходу решил сэкономить ещё один канал захвата и в результате не всегда будет правильно.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: Вопросы по С/С++ (СИ)
Всем привет!
написал код для контроллера, но компилятор (Keil uVision) выдает предупреждения типа
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: NFREQ
MODULE: main_prog.obj (MAIN_PROG)
ADDRESS: 0255H
что я натворил в целом.
Прописал все переменные в h-файле под именем Global Constants.h (не задумывайтесь над логикой названия файла с переменными. сам не знаю
)
Вот его содержимое
Не могу понять откуда ворнинги? Причем их за 70 штук
Впервые попытался написать h-файл . До этого я не пользовался extern-ном.
Помогите разораться, где "накосячил" ))
написал код для контроллера, но компилятор (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);
Впервые попытался написать h-файл . До этого я не пользовался extern-ном.
Помогите разораться, где "накосячил" ))
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
© Альберт Эйнштейн
Re: Вопросы по С/С++ (СИ)
в хидере надо просто описывать переменные без инициализации, а определять в с-файле и инициализировать там же
- Chip115
- Сверлит текстолит когтями
- Сообщения: 1132
- Зарегистрирован: Пт фев 16, 2007 14:18:20
- Откуда: Новосибирск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
т.е так для h
а в си файле
?
И я еще не до конца понял назначение extern-а
Можете объяснить?:)
Код: Выделить всё
extern int mas[]={};
Код: Выделить всё
int mas[]={0x36,0x2E,0x1E,0x35,0x2D,0x1D,0x33,0x2B,0x1B};
И я еще не до конца понял назначение extern-а
Можете объяснить?:)
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
© Альберт Эйнштейн
Re: Вопросы по С/С++ (СИ)
для хидера
назначение extern состоит в том, чтобы сказать компилеру, что данная данный объект определен в другом модуле.
Код: Выделить всё
extern int mas[]Re: Вопросы по С/С++ (СИ)
Подскажите, будут ли генерироваться прерывания КАЖДЫЙ ТИК таймера
Код: Выделить всё
interrupt [TIM2_COMP] void timer2_comp_isr(void) // прерывание Т2 по совпадению
{
OCR2++;
********ОБРАБОТЧИК ПРЕРЫВАНИЯ***********
}KIT
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
будут генерироваться только в том случае, если за один тик таймера программа успеет войти в прерывание, выполнить обработчик и выйти из прерывания (такое возможно при достаточно большом предделителе и достаточно малом времени выполнения обработчика)
p.s. и если таймер не работает в PWM режиме, т.к. в этом случае OCR записывается не сразу в регистр, а только во временный регистр, откуда при переполнении таймера окончательно переписывается в регистр OCR
p.s. и если таймер не работает в PWM режиме, т.к. в этом случае OCR записывается не сразу в регистр, а только во временный регистр, откуда при переполнении таймера окончательно переписывается в регистр OCR
Ставим плюсы: )
- Chip115
- Сверлит текстолит когтями
- Сообщения: 1132
- Зарегистрирован: Пт фев 16, 2007 14:18:20
- Откуда: Новосибирск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
не подскажите, как можно оптимизировать код. у меня есть куча массивов, но памяти ограниченно.
например вот
можно как нибудь сократить объем памяти занимаемый этими массивами?
например вот
Код: Выделить всё
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
- Ум, честь и совесть. И скромность.
- Сообщения: 18642
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
да, можно, если тщательно обдумать алгоритм. есть предположение, что у вас много избыточных данных хврнится в массивах.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Можно константы объявить с префиксом PROGMEM, не забыв #include <avr/pgmspace.h>
И при необходимости использовать функции описанные в указанном pgmspace.h
И при необходимости использовать функции описанные в указанном pgmspace.h
— Не говорите мне что делать и я не скажу куда Вам идти...
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Вопросы по С/С++ (СИ)
Открою небольшой секрет: Chip115 работает с СиЛабовскими контроллерами, а не АВРовскими.md5sum писал(а):Можно константы объявить с префиксом PROGMEM, не забыв #include <avr/pgmspace.h>
И при необходимости использовать функции описанные в указанном pgmspace.h
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Тогда надо смотреть, какое ключевое слово нужно компилятору. Уж не помню в каком компиляторе, с 51-ми лет 10 не работаю, а до того использовал AVOCET и KEIL (скорее всего в обеих было одинаково, а в AVOCET просто не было слова bit для возвращаемого функией значения), были слова code, idata, xdata для управления размещением.
Например, так:
Например, так:
и это же code во всех указателях, которые могут принимать этот массив:unsigned char const code cmd_PPWM[5] = {0xE3, 0x10, 0x00, 0x50, 0x00};
bit process_command(unsigned char const code *pcmd);
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Вопросы по С/С++ (СИ)
Да, avreal, ваша правда:

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


