Страница 18 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт мар 22, 2011 23:32:44
SSERG
ChipKiller писал(а):... прочитать порт можно и проще, зачем так все усложнять?
в этом и вопрос,я догадался что делаю все через ж...... -поэтому просьба подскажите как,сам пока догнать не могу!
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт мар 22, 2011 23:49:36
ChipKiller
SSERG писал(а):в этом и вопрос,я догадался что делаю все через ж..
... дело не в этом
SSERG писал(а):Подскажите как можно проще опрашивать много портов и сравнивать значения с другими портами
... любая программа начинается с задачи и понимания того, что Вам нужно получить.... угадать тяжело и помочь тоже
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 23, 2011 00:15:39
SSERG
Суть программы вот в чём опросить порты входа,если 0 включить 1 на соответствующем выходе,если на выходе был 0 вкл тревогу если 1 не включать.........
и.т.д для 8 портов,как при сканировании входов узнать была ли 1 на выходе и ещё как програмно приравнять значение порта к переменной в принципе в в этом коде всё работает,только как-то я всё усложнил....
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 23, 2011 12:28:04
koldune
Товарищи, помогите
Написал программу стрелочного тахометра. Работает так: ловим первый импульс - синхронизируемся, ловим второй - запускаем TMR1, ловим третий - останавливаем TMR1 и идём показывать то, что насчитали, на индикатор. Чтобы индикатор на шаговике корректно работал и опускал стрелку в ноль, когда вал остановится, нужен какой-нибудь контроль остановки вала. Иначе программа будет ждать первого или второго импульса (если не дождётся третьего - ничего страшного, по переполнению TMR1 подпрограмма пойдёт в return). Подскажите, как сделать, чтобы если в течение, скажем, 0.2 секунды не поступило импульсов на вход процессора, подпрограмма измерения оборотов уходила бы в return?
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 23, 2011 16:14:20
aleksey_gregul
koldune писал(а):Товарищи, помогите
Зачем так делаете?
Почитайте про input capture.
Специально для этого случая.
Ничего не нужно стартовать, останавливать, дожидаться...
Все происходит на аппаратном уровне.
Ваша же задача - только прочитать ICR
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 23, 2011 16:17:39
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 (кроме первого после паузы) имеем отсчёт времени.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 23, 2011 16:23:06
avreal
aleksey_gregul писал(а):koldune писал(а):Товарищи, помогите
Зачем так делаете?
Почитайте про input capture.
Специально для этого случая.
Алексей, доброго здоровья!
Вот и я о том же. Даже довольно скромные (по сравнению с разными ARM7 и Cortex-M3) таймера AVR позволяют много сделать аппаратно.
Более того, в описанном применении у таймера 1 модули OCR остаются свободными и на них можно сделать таймера с любой частотой выше частоты переполнения таймера, просто в каждом прерывании, к примеру, OCR1A писать
Таким образом даже если по показаниям для тахометра/одометра нужно прескалером сделать период переполнения около
секунды, на том же таймере можно организовать ещё прерывания с частотой, к примеру, около
килогерца (для динамической индикации), просто сделав OCR1A_PERIOD 65 (65536/1000). Для динамической индикации точная частота не важна.
Второй канал OCR1B кроме прерывания ещё заставить инвертировать ножку, при этом на пьезопискунчик можно будет давать меандр с периодом 2*ocr1b_period, т.е. меняя уже не константу, а переменную ocr1a_period можно на пискунчик выдавать разные тона от пары килогерц и ниже. Тоже не точно выставив частоту, но в большинстве случаев для оператора достаточно различия "пикнуло высоким тоном" / "пискнуло низким тоном".
При этом остальные таймера свободны, хотя уже куча всего сделана

Есть чем и шаговый двигатель термопринтера окучить, и его термоголовку

Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 24, 2011 08:47:05
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. Тут его сбрасываем.
// ...
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб мар 26, 2011 18:47:03
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-ном.
Помогите разораться, где "накосячил" ))
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб мар 26, 2011 19:10:21
lix
в хидере надо просто описывать переменные без инициализации, а определять в с-файле и инициализировать там же
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб мар 26, 2011 19:20:32
Chip115
т.е так для h
а в си файле
Код: Выделить всё
int mas[]={0x36,0x2E,0x1E,0x35,0x2D,0x1D,0x33,0x2B,0x1B};
?
И я еще не до конца понял назначение
extern-а
Можете объяснить?:)
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб мар 26, 2011 19:35:22
lix
для хидера
назначение extern состоит в том, чтобы сказать компилеру, что данная данный объект определен в другом модуле.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 27, 2011 18:27:50
O-LED
Подскажите, будут ли генерироваться прерывания КАЖДЫЙ ТИК таймера
Код: Выделить всё
interrupt [TIM2_COMP] void timer2_comp_isr(void) // прерывание Т2 по совпадению
{
OCR2++;
********ОБРАБОТЧИК ПРЕРЫВАНИЯ***********
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 27, 2011 20:33:18
ibiza11
будут генерироваться только в том случае, если за один тик таймера программа успеет войти в прерывание, выполнить обработчик и выйти из прерывания (такое возможно при достаточно большом предделителе и достаточно малом времени выполнения обработчика)
p.s. и если таймер не работает в PWM режиме, т.к. в этом случае OCR записывается не сразу в регистр, а только во временный регистр, откуда при переполнении таймера окончательно переписывается в регистр OCR
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс апр 03, 2011 16:37:05
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}; // прочитать регистр статуса
можно как нибудь сократить объем памяти занимаемый этими массивами?
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс апр 03, 2011 21:23:33
ARV
да, можно, если тщательно обдумать алгоритм. есть предположение, что у вас много избыточных данных хврнится в массивах.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 04, 2011 22:01:29
md5sum
Можно константы объявить с префиксом PROGMEM, не забыв #include <avr/pgmspace.h>
И при необходимости использовать функции описанные в указанном pgmspace.h
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт апр 05, 2011 10:05:28
Gudd-Head
md5sum писал(а):Можно константы объявить с префиксом PROGMEM, не забыв #include <avr/pgmspace.h>
И при необходимости использовать функции описанные в указанном pgmspace.h
Открою небольшой секрет:
Chip115 работает с СиЛабовскими контроллерами, а не АВРовскими.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт апр 05, 2011 12:10:55
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);
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт апр 05, 2011 12:19:59
Gudd-Head
Да,
avreal, ваша правда:
