Перейти к содержанию
    

=GM=

Свой
  • Постов

    1 590
  • Зарегистрирован

  • Посещение

Весь контент =GM=


  1. Если вы толкуете про модбас, то можно сделать систему без модбаса, собрать всю телеметрию в "концентраторе", а из него уже передавать по модбасу. Преимущество в том, что программа микроконтроллеров "гирлянд" будут существенно проще, хоть на восьминожке attiny10 можно собрать со своим протоколом, отсюда меньше габариты, потребление и т.д. и т.п. Что по другим пунктам?
  2. Парни, позвольте внести мои 5 копеек. 1) Зачем беспокоиться о стоимости микроконтроллера, если стоимость 30 датчиков температуры на порядок выше? Программа чтения температуры из датчика DS18B20 занимает порядка 200 байт хоть на си хоть на ассме. Ставьте любой МК, который вам проще программировать. 2) Зачем в системе сбора температуры применять модбас? Собрать с 30 датчиков измеренную температуру, сформировать пакет с контрольной суммой и передать по линии в концентратор или ПК можно и без модбаса. Это будет и дешевле, и проще, и быстрее в реализации. 3) Вообще, на мой взгляд, подобные системы сбора телеметрии должны работать безо всяких запросов, просто непрерывно гнать данные, а МК должен выбирать их с линии по мере необходимости.
  3. Можно вычислить по формуле CRC5*b5 ^ CRC4*b4 ^ CRC3*b3 ^ CRC2*b2 ^ CRC1*b1 ^ CRC0*b0, где CRCi - определённые 6-ти битные коэффициенты bi - текущие биты полинома-делимого * - операция "умножение" (на bi=1 или bi=0) ^ - операция "исключающее или"
  4. Всё началось отсюда, там на основе сломанного электронного термометра был сделан пробник-минивольтметр. Что касается других МК. На STM32F100 discovery писал программку вывода на ЛСД, который стоит на плате, вот там просто исплевался! Не знаю, кто придумал такое аппаратное двухмерное представление сегментов, возможно индусы, тогда я думал о них гораздо лучше, чем они есть на самом деле, но ХУЖЕ просто невозможно придумать, это даже не мазохизм, а примерно как ржавой тупой пилой самому пилить зажатые в тисках гениталии. Извините, Александр, с ходу не углядел, но третью строку вы неправильно представляете. Должно быть "temp_ptr2 = temp_ptr1-4", а не " temp_ptr2 = pph-4". Кстати, порядок для операции присваивания вполне определённый - справа налево.
  5. Не понимаю разницы, оба варианта псевдокода приведите, чтобы сравнить. (Добавлено позже) 1) Здесь не могу согласиться с вашим высказыванием, что "эта строка имеет право стоять где угодно в пределах от { до;" Эта строка не может стоять первой { temp_ptr1 = pph pph = pph + 1 <- эта строка имеет право стоять где угодно в пределах от { до; temp_ptr2 = pph - 4 temp_var1 = *temp_ptr2 temp_var1 = ~temp_var1 *temp_ptr1 = temp_var1 ; 2) Для компилятора в таком коде *pph++=~(*(pph-4)); нет ничего неоднозначного. Судите сами. Берется значение по адресу (pph-4), инвертируется, сохраняется по адресу (pph), затем адрес (pph) увеличивается на 1. Где тут неоднозначность? Здесь компилятор даже предупреждения не может выставить.
  6. Моя версия компилятора даёт один и тот же ассемблерный код для обоих вариантов 1 и 2. while(pph!=&ph[8]) { *(pph++)=~(*(pph-4)); 98: 80 91 70 00 lds r24, 0x0070 9c: 80 95 com r24 9e: 80 93 74 00 sts 0x0074, r24 a2: 80 91 71 00 lds r24, 0x0071 a6: 80 95 com r24 a8: 80 93 75 00 sts 0x0075, r24 ac: 80 91 72 00 lds r24, 0x0072 b0: 80 95 com r24 b2: 80 93 76 00 sts 0x0076, r24 b6: 80 91 73 00 lds r24, 0x0073 ba: 80 95 com r24 bc: 80 93 77 00 sts 0x0077, r24 И сначала мне больше понравилась ваша версия 2, поскольку никаких предупреждений не было, а в моём варианте было предупреждение: operation on pph may be undefined - операция с pph может быть неопределенной. Но присмотревшись к коду, я понял к чему относится предупреждение. По си коду указатель pph в процессе исполнения кода увеличивается на 4, а в листинге указатель кода никак не участвует, поскольку там цикл развернут и применена прямая адресация! Поэтому компилятор предупреждает, что если вы будете использовать pph дальше, то содержимое указателя может быть отлично от того, на что вы рассчитывали. Я считаю, что лучше пусть будет предупреждение просто как напоминание, что может произойти в дальнейшем. А чудеса с оптимизацией продолжаются. Из такого си кода, больше ничего нет int main(void) //LCD test { unsigned char *pph; unsigned char *pdg; while(1) { pdg=&dig[0]; pph=&ph[4]; while(pph!=&ph[8]) { *(pph++)=~(*(pph-4)); } } } получается такой ассемблерный листинг int main(void) //LCD test { 5e: e4 e7 ldi r30, 0x74 ; 116 60: f0 e0 ldi r31, 0x00 ; 0 pph=&ph[4]; while(pph!=&ph[8]) { *(pph++)=~(*(pph-4)); 62: 34 97 sbiw r30, 0x04 ; 4 64: 80 81 ld r24, Z 66: 34 96 adiw r30, 0x04 ; 4 68: 80 95 com r24 6a: 81 93 st Z+, r24 } while((pdg)!=&dig[4]); pph=&ph[4]; while(pph!=&ph[8]) 6c: 80 e0 ldi r24, 0x00 ; 0 6e: e8 37 cpi r30, 0x78 ; 120 70: f8 07 cpc r31, r24 72: b9 f7 brne .-18 ; 0x62 <main+0x4> 74: 34 97 sbiw r30, 0x04 ; 4 76: f5 cf rjmp .-22 ; 0x62 <main+0x4> Умереть-не встать: теперь компилятор решил не разворачивать цикл while. Не могу понять, по какой причине меняется генерируемый код - по воле левой ноги компилятора или я делаю что-то не так?
  7. WinAVR-20100110 (AVR-Studio, vers.4.18, build 684, GUI vers.4.18,0,680) Ключ -Os
  8. Борщ, уймитесь. Мне этот топик был полезен, уже скачал avr-gcc-4.7.2-mingw32, спасибо неозабоченным коллегам.
  9. Чудеса

    При 12 МГц тактовой и однобайтном счётчике, у вас программная задержка будет максимум на 64 мкс, а не на 500 мкс. Вам следует использовать 2-х байтный счётчик задержки. Вернее всего, датчик у вас нормальный, просто не успевает среагировать на короткий импульс. Ниже, для примера, приведен реальный код для начала работы с 1-wire, вроде бы Fклок=10 МГц, проверьте rs1820: cbi PORTB,0 ldi hdelay,high(1249);500us ldi ldelay,low(1249) rs1: sbiw ldelay,1 brne rs1 sbi PORTB,0 ldi temp1,0x1E ;PB0-input out DDRB,temp1 ldi hdelay,high(169);68us ldi ldelay,low(169) rs2: sbiw ldelay,1 brne rs2 ldi temp3,13 ;TempSensor failed sbic PINB,0 rjmp rs4 ldi hdelay,high(1079);432us ldi ldelay,low(1079) rs3: sbiw ldelay,1 brne rs3 ldi temp1,0x1F ;PB0-output out DDRB,temp1 clc ret rs4: ldi temp1,0x1F ;PB0-output out DDRB,temp1 ret
  10. Это я всё могу сделать на асме и сделаю, здесь проблем нет, хотя инлайновый асм в винавре это нечто. Приведенный в первом посте код - это часть прерывания, которая формирует фазы ЖКИ. Скорости там небольшие, но хотелось бы, чтобы все фазы были симметричны по длительности исполнения, иначе возникнет постоянный микроток через ЖК, который в итоге приведёт к разрушению ЖК. Опять же, 3-4 года назад мне здесь же на форуме все уши прожужжали, как хорошо писать на си, я проникся, стал писать, вот результат. Теперь опять призывают писать на асме. Ну, надо быть последовательными, граждане-братцы...
  11. Да, слова золотые, целиком и полностью поддерживаю. Только они никак не отвечают на мой вопрос.
  12. Всем привет. Такой вопрос. Почему код while(pph!=&ph[8]) { *(pph++)=~(*(pph-4)); }, в котором берётся часть массива, инвертируется и записывается в другое место, компилируется в такой несимметричный код? while(pph!=&ph[8]) { *(pph++)=~(*(pph-4)); 94: fd 01 movw r30, r26 96: 34 97 sbiw r30, 0x04; 4 98: 80 81 ld r24, Z 9a: 80 95 com r24 9c: 8c 93 st X, r24 9e: 80 91 71 00 lds r24, 0x0071 a2: 80 95 com r24 a4: 11 96 adiw r26, 0x01; 1 a6: 8c 93 st X, r24 a8: 11 97 sbiw r26, 0x01; 1 aa: 90 91 72 00 lds r25, 0x0072 ae: 89 2f mov r24, r25 b0: 80 95 com r24 b2: 12 96 adiw r26, 0x02; 2 b4: 8c 93 st X, r24 b6: 12 97 sbiw r26, 0x02; 2 b8: 80 91 73 00 lds r24, 0x0073 bc: 80 95 com r24 be: 13 96 adiw r26, 0x03; 3 c0: 8c 93 st X, r24 } Казалось бы чего проще, для всех 4-х байт сделать одно и тоже действие: загрузить байт в регистр, а лучше бы воспользоваться регистровой парой Z, инвертировать и записать в новое место, указываемое парой Х. Дальше, почему бы не использовать постинкремент Х+ вместо двух команд adiw и st? Может, кто-то знает, как переделать си-код в нечто подобное?
  13. Все прекрасно понимают, что если есть синус 10 кГц, его сдвинули на 90 градусов, получился косинус. А что вы понимаете под фазовращателем 0..180 ддя широкополосного сигнала 10..100 кГц?
  14. По описанию время выполнения команды LD Rd,X+ в Xмеге составляет ОДИН такт, если доступ во внутреннюю память на кристалле и ДВА для внешней памяти. Думаю, в примечании 2 ошибка, т.е. должно быть написано 2. One extra cycle must be added when accessing EXTERNAL sram - Должен быть добавлен один дополнительный цикл при доступе во ВНЕШНЮЮ память.
  15. А так почему нельзя сделать unsigned long i; unsigned char *VRAM; VRAM=0x00020000; for(i=0;i<130560;i++) *VRAM++=colour;
  16. Похоже, при формировании структуры си-компилятор находит элемент с максимальной длиной и выделяет каждому элементу структуры размер памяти, равный максимальной длине. По крайней мере, для кейловского компилятора я это доказал. Выделил структуру typedef struct { unsigned long VARA; unsigned char VARB; unsigned int VARC; } CRCSTRUCT; CRCSTRUCT STRD; и в дибаггере стал туда писать побайтно, начиная с VARА. В VARА записалось 4 байта, как и ожидалось, в VARВ записался один байт, остальные три писались в никуда и не отображались, в VARC записалось два байта, остальные записались в никуда. Так что дырки в структурах всегда будут, если структура содержит элементы разной длины.
  17. Кстати, в голову мысль пришла, обобщая способ доступа к байтам через union. Почему-то во многих языках любого уровня редко используются наиболее мощные операторы. Например, в фортране редко использовался оператор EQUIVALENCE, в ассемблере 8051 команда ХСН, в си редко встречается UNION...
  18. Можно проще сделать union { ulong b; uchar c[4]; } a; Обращение к 32-битной переменной: a.b=524354; Обращение к младшему байту: a.c[0]; к старшему - a.c[3]; Вывод среднего байта: PORTB=a.c[2]; сдвиг 32-х бит: a.b<<=1; ну и так далее
  19. Можно так написать for(i=0;i<6;i++) { temp=dig[i]; //temporary for(j=0;j<4;j++) { if(temp & 0x01) PORTD |= _BV(DS) //DS=1 else PORTD &= ~_BV(DS); //or DS=0 PORTD |= _BV(SH_CP); //SH_CP=1 PORTD &=~_BV(SH_CP); //SH_CP=0 temp >>=1; //shift right } } тогда массив bin_digits[10] не нужен
  20. Считать длительности импульсов в шумах - гиблое дело, меняйте подход. Предлагаю устроить "цифровой импульсный фильтр". Заведите переменную SIGNAL, значение которой меняется после каждой выборки. Если входной сигнал равен лог.1, то SIGNAL инкрементируете, пока не достигнете максимального значения, скажем, МАХ=2000, если достигли, то ничего не делаете. Если входной сигнал равен лог.0, то SIGNAL декрементируете, пока не достигнете минимального значения 0, если достигли, то ничего не делаете. Если SIGNAL>МАХ/2, то принятый входной сигнал равен 1, в противном случае он равен 0. Далее можете измерять длительность отфильтрованного сигнала как обычно. Для выбора максимальной допустимой ширины просечек можно ещё поиграться переменной МАХ и частотой выборок. Для автонастройки скорости приёма используйте тот же приём, что и для приёма кода Морзе. Вроде всё...
  21. Какие фазовые шумы, откуда им взяться? И что такое 10 кГц? На вопрос "зачем вам возбудитель" ответьте...
  22. Ну, как зачем.. например, практически голый МК, скажем тинька, плюс ЦАП, может выдать готовый SSB сигнал в полосе 3.50-3.65 МГц с шагом 1Гц. Фильтруем его и усиливаем. Вот и весь передатчик..
  23. Ну я ж сказал, идею пока только вынашиваю, т.е. вопрос реализации SSB на АВР находится в теоретической стадии. Хотя, если реализовывать на DSP, то нет проблем. Скажите, зачем вам возбудитель SSB, если не секрет?
  24. С Морзе могу поделиться, хотите прошитый чип?
×
×
  • Создать...