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

UniBomb

Свой
  • Постов

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

  • Посещение

Весь контент UniBomb


  1. Nikson1200, со вчерашнего дня я нашёл даташит. Но по вашим двум последним ссылкам я не вижу как скачать даташит. И я был на этом сайте, и страницы эти изучал долго и упорно. Ссылки Locate Part LTM035A776C и Locate DataSheet никуда меня не ведут, других ссылок я не нашёл. Спасибо всем откликнувшимся :)
  2. Как бы то нибыло, а на LTM035A776С я тоже ничего не нашёл :(
  3. oldparrot, спасибо. А это аналог? Просто на моём экземпляре нет такого обозначения :)
  4. Добрый день. Долго у меня валялся нерабочий кпк HP Jornada 560, мозолил глаз и всем своим видом напрашивался на экзекуцию. В общем самое полезное что я оттуда вытащил - дисплей с маркировкой F1865-80021. Но вот беда - никак не могу найти на него даташит. Если кому попадется - скажите мне пожалуйста :)
  5. Профайлер

    SasaVitebsk, в моей пока ещё недолгой карьере я был доволен кодом всего один раз :) Прошивку для предыдущего прибора я писал довольно долго, менял методы решений, оптимизировал, сокращал и т.д. Зато когда я закончил - налюбоваться не мог (не то, что бы я бахвальством любил заниматься :) ). Ничего не прибавить, ничего не убавить, лепота :) А так в принципе любой инженер устроен - будь то программист или схемотехник (или ещё кто). И я считаю, что это здорово когда есть желание стремится к лучшему :)
  6. Профайлер

    RA3WUM, за HAPSIM спасибо, не знал о такой примочке))) А вот второе... Я не программирую на бейсике по религиозным причинам.... zltigo, да я сам проповедую такой подход, просто ситуация такая сложилась. Поставленную задачу я решал впервые, опыта проектирования программ подобного рода у меня мало да и решить задачу требовалось в самые кратчайшие сроки. Сейчас вроде всё работает, но мне жутко не нравится реализация. Чувствую сопровождать такую программу будет очень сложно. Сейчас пока времени более-менее хватает и пока я ещё помню что и зачем я делал я решил улучшить качество кода... sitafern, он платный ): В общем я так понял, что искомого мне не найти... Жаль. Поставил себе в блокнотик в разделе "долгосрочные задумки" заметку "сделать что-то подобное", авось у меня что-нибудь получится...
  7. Профайлер

    SasaVitebsk, вот как раз из-за того, что прогресс шагает и шагает я и предложил что такая утопия уже воплощена в каком-либо объёме. На самом деле я не написал ничего экстрасложного, разные части уже реализованы для того или иного языка программирования/интегрированной среды/etc. Многое из того, что я перечислил можно вообще получать на этапе компиляции. Но раз уж такая постановка задачи не нравится, то перефразирую её - "А есть ли в природе ещё профайлеры кроме gprof?". С другой стороны - система системе рознь и проектирование для каждой (по крайней мере у меня) существенно различаются подходы. Отлаживать программу всем форумом - это глупо :) Скажу просто - есть достаточно громоздкая система с кучей функций. Декомпозиция проведена не очень хорошо и надо это дело оптимизировать. Профайлер gprof может сказать сколько времени выполнялась та или иная функция и зависимость вызовов функций. Всё. Но порой этой информации мало. Описывать конкретнее в двух словах у меня всё равно не получится, да и потом выглядеть такое описание будет как глупая абстракция... В общем вот...
  8. Профайлер

    Добрый день. Не знал куда запостить тему, посему пусть тут повисит. Итак, во время очередной затяжной отладки программы я понял что чего-то мне не хватает в этой жизни для полного счастия. Я понял, что считать быстродействие функций по тактам это зло. Я понял, что следить за переменными ставя точки останова по всей программе это от лукавого. Я понял, что отлавливать вхождения одних функций в другие по загоранию светодиода это тоже не очень хорошо. И я в конце концов пришёл к выводу, что мне нужен хороший профайлер. Единственное что я пока обнаружил - это avr-gprof.exe тихо спящим в папке bin моего WinAVR. Вот пока копаю в эту сторону и что-то оно меня пока не впечатляет. Посему вопрос знатокам - а есть ли в природе альтернативы этому чуду? Что бы мог указать зависимость вызовов функций, что бы мог указать время выполнения каждого куска кода, что бы мог сказать где и как переменные используются, что и зачем храниться в стеке и т.д. И при всём при этом что бы он имел хоть какой-нибудь графический интерфейс...
  9. Да, насчёт таймера я был неправ... Сейчас попробую))) зы: кстате, бонус вопрос. Если скорость обмена 38400Кбод/сек, то время приёма 3,5 символов будет (1/38400)*3,5 ?
  10. MrYuran, я думал так сделать, но у меня всего один свободный таймер остался. А с одним таймер на два усарта не очень то и получается...
  11. Работа с обоими USART в ATMega64

    Добрый день. У меня есть девайс на 64-ой меге, в которой задействованы оба усарта. Реализован протокол ModBus RTU (самолично). По описанию протокола все посылки данных начинаются и оканчиваются интервалом времени, равное времени приёма 3,5 символов. Не мудрствуя лукаво я реализовал это условие в лоб - при приёме первого символа мк уходит в прерывание и не выходит из него до тех пор, пока не примет всю посылку. До недавнего времени использовался только один усарт и всё было хорошо. Но вот буквально вчера возникла необходимость использования и второго усарта. Естетсвенно вышеописанный подход неверен, т.к. из-за большой частоты посыла запроса и соответсвенно получения ответа два прерывания по приёму данных мешают друг другу. Т.е. если в данный момент уже идёт приём данных по первому усарту и в это время начали приходить данные на второй усарт, то часть посылки со второго усарта просто теряется. Такого быть недолжно.... Сократил об прерывания до самого минимума: uint8_t data_recv0[128]; uint8_t cur_data_recv0; /*...*/ ISR(SIG_UART0_RECV) { data_recv1[cur_usart1_recv] = UDR0; cur_data_recv++; } Но я никак немогу сообразить, как же в этом случае вести отсчёт времени, как отделять посылки друг от друга и вообще как определить конец посылки. Пробовал через таймер, но что то невыходит. Получается либо слишком большой промежуток времени, либо приходится делать период срабаотывания таймера настолько маленьким, что одна посылка разбивается на несколько. Какие ещё есть решения? Кто как обходил эту ситуацию?
  12. В том то и дело, что до этого никакую SCADA мы не использовали. А правильно ли я понял, что если в SCADA прописать опрос регистра с номером 40001, то фактически будет послан такой запрос: [xx][03][00][01]...[crcH][crcL] где [00][01] - это и есть адрес регистра?
  13. Добрый день. Использую Modbus RTU по интерфейсу rs-485. Краем уха слышал где-то, что в зависимости от того, какую разновдность протокола и по какому интерфейсу я использую это безобразие регистры хранения имеют разные адреса. Т.е. в одном случае адрес первого регистра 1, а в другом 40001. В стандарте я это либо пропустил, либо действительно об этом не сказано, так что просветите пожалуйста :)
  14. Проблемы с TWI

    Нет. Как высокоимпендансные входы. Незнаю. Сейчас посмотрю В слипе я модуль не использую. Две функции не вызываются в одно время и следовательно работают либо функции TWI, либо функции АЦП.
  15. Проблемы с TWI

    вопрос - как связаны между собой модуль TWI и спящий режим? Методом исключения я выяснил причину сбоев шины - её оказалась команда sleep. Незнаю почему, но если хоть раз мк был переведён в спящий режим, то TWI сбоит вышеописанным способом... Теперь ломаю голову почему так происходит.... зы: используемый мной режим спящего режима - ADC Noise Reduction.
  16. Проблемы с TWI

    Так, вопрос всё ещё актуальный... sensor_ua, прошу прощения за возможно-безосновательные претензии :) В общем получается так - если написать маленькую программку, в которой просто сделать опрос температурной микросхемы, то всё работает. for(;;) { set_conG; for(int i = 0; i < 20; i++) _delay_loop_2(0xFFFF); ds1621_start(); clr_conG; for(int i = 0; i < 20; i++) _delay_loop_2(0xFFFF); temperature = ds1621_read(); } Причём как при использовании функций товарища Fleury. Температура считывается, передаётся по RS-485 и всё в общем пучком. Если те же самые функции запихнуть в основную программу, то происходит то, что я написал в третьем посте. Казалось бы виной тому остальные части большой программы, но я в ней уже всё вичистил. Функции для работы с TWI ни на кого не завязаны, порты нигде не меняюются и т.д. Аггрр....
  17. Проблемы с TWI

    M_Andrey, я надеюсь не на шину, а к питанию? ;) ensor_ua, ясно))) Вы немного неправильно делаете - над именно судить код, а не искать различия реализации алгоритма. Нужные флаги тут проверить ну никак нельзя, т.к. нужно смотреть их совокупность (совокупное значение). Этот товарищ делает точно также за двумя исключеними - я пользуюсь числовым обозначением - он предопределёнными константами; он отсекает то что не надо одним махом - я же смотрю только то, что нужно. Критического тут ничего нет. Проверяет он регистр статуса - без этого никак. С TWI можно работать двумя способами - либо через прерывания (в котором всё равно смотрится код статуса в регистре статуса), либо самому регистр статуса всё время мониторить. Вот как он это делает: twst = TW_STATUS & 0xF8; if( twst != TW_MT_DATA_ACK) return 1; где TW_STATUS - предопределённая константа, идущая в хедере вместе с компилятором : #define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|\ _BV(TWS3)) #define TW_STATUS (TWSR & TW_STATUS_MASK) Для наглядности (и просто по привычке) я этими макросами не пользуюсь и представляю всё в явном виде. Возврщаясь к проблеме скажу, что код, на который вы указали работает и у меня запустился. Температура читается и вроде даже без глюков. Но понять почему - я пока так и не смог Так что спасибо за ссылку и за диалог. Вопрос вроде как снимается)))
  18. Проблемы с TWI

    sensor_ua, continue там стоит логично (по идее), но совершенно непонятно как это делает мой код нерабочим. Ведь если код статуса будет всё время 0xF8 то из цикла while ( 1 ) программа никогда не выйдет вне зависимости от того стоит там continue или нет...
  19. Проблемы с TWI

    sensor_ua, лучше бы ты меня идиотом назвал... Проверил, коды функций мало чем отличаются, все различия несущественны и заключаются в различном офрмлении. ReAl, насчёт того, чего делать не стоит - да, там опечатка, но ничего вопиющего в принципе нет. Принял к сведению. А насчёт работы - это с моими функциями работает? с теми, что в первом посте? Сделал программный TWI используя функции, взятые тута - тоже не работает. Думаю пока что именно.
  20. Проблемы с TWI

    Перепробовал все примеры использования, какие только мог найти в интернетах. С использованием прерываний и без оных. Мой вариант как я понял мало чем отличается от других, посему мысль о своей неполноценности я отбросил (не без колебаний, кстате)... Получается вот что: при первых двух-трёх вызовов функций СТАРТ (это когда происхоит запись TWCR = (1 << TWINT|1 << TWSTA|1 << TWEN);) и последущих вызовов функций СТОП (это когда происхоит запись TWCR = (1 << TWINT|1 << TWSTO|1 << TWEN);). Всё происходит нормально. Затем происходит мистика - на линии SDA постоянно висит "0" если была вызвана функция инициализации модуля TWI и "1" если соответсвенно не была вызвана та функция. Осцилограф показывает постоянный сигнал на обеих линиях (SDA и SCL). Кода статуса постоянно 0xF8, а флаг TWINT постоянно сброшен. Думалка уже отказывается работать и причина этого мне не ясна... Пойду ваять программный TWI чтоли... и всё таки - что я делаю не так?
  21. Проблемы с TWI

    ммм...... неужели нет мыслей? Путём отладки выяснил, что модуль TWI вроде как вообе не работает. После любой операции не устнавливается флаг TWINT, а код статуса всё время 0xF8. Так что даже в состояние СТАРТ неполучается вывести...
  22. Проблемы с TWI

    Добрый день. Работаю с восьмой мегой и температурным датчиком ADT75. Написал собсвенные функции работы с TWI: unsigned char twi_get_last_status(void) { return (TWSR & (1 << TWS7|1 << TWS6|1 << TWS5|1 << TWS4|1 << TWS3)); } //--------------------------------------------------------------------------- unsigned char twi_Wait_TWINT(void) { register unsigned char i=0; //ожидаем TWIN==1 do { if(TWCR & (1<<TWINT)) return 0x01; //true } while(--i); return 0x00; //false } //--------------------------------------------------------------------------- void twi_init_asmaster(void) { TWBR = 0x20; TWSR = (0 << TWPS1|0 << TWPS0); TWCR |= (1 << TWEN|1 << TWEA); twi_start(); twi_write_address(0xff, 'r'); twi_start(); twi_stop(); } //--------------------------------------------------------------------------- unsigned char twi_start(void) //он же повстарт { TWCR = (1 << TWINT|1 << TWSTA|1 << TWEN); unsigned char twi_last_status = twi_get_last_status(); if(twi_Wait_TWINT() == 0x01) { if((twi_last_status == 0x08) || (twi_last_status == 0x10)) return 0x01; //true } else return 0x00; //false return 0; } //--------------------------------------------------------------------------- unsigned char twi_stop(void) { TWCR = (1 << TWINT|1 << TWSTO|1 << TWEN); register unsigned char i=0; do { if(PINC & 0x10) //смотрим, установилась ли в "1" линия SDA return 0x01; //true } while(--i); TWCR = (1 << TWINT|1 << TWSTO); return 0x00; //false } //--------------------------------------------------------------------------- unsigned char twi_write_byte(unsigned char data_byte) { TWDR = data_byte; TWCR = (1 << TWINT|1 << TWEN); if(twi_Wait_TWINT() == 0x01) { unsigned char twi_last_status = twi_get_last_status(); if((twi_last_status == 0x28) || (twi_last_status == 0x30)) return 0x01; //true else if(twi_get_last_status() == 0x38) return 0x00; //потеряли приоритет } else return 0x00; //false return 0; } //--------------------------------------------------------------------------- unsigned char twi_write_address(unsigned char address_byte, char read_write) { if(read_write == 'r') address_byte |= 0x01; else if(read_write == 'w') address_byte &= 0xFE; else return 0x00; TWDR = address_byte; TWCR = (1 << TWINT|1 << TWEN); if(twi_Wait_TWINT() == 0x01) { unsigned char twi_last_status = twi_get_last_status(); if(read_write == 'w') { if((twi_last_status == 0x18) || (twi_last_status == 0x20)) return 0x01; //true else if(twi_get_last_status() == 0x38) return 0x00; //потеряли приоритет } else if(read_write == 'r') { if((twi_last_status == 0x40) || (twi_last_status == 0x48)) { TWCR = (1 << TWINT|1 << TWEA|1 << TWEN); return 0x01; //true } else if(twi_get_last_status() == 0x38) return 0x00; //потеряли приоритет } } else return 0x00; //false return 0; } //--------------------------------------------------------------------------- unsigned char twi_read_byte(unsigned char *data, unsigned char ack_nack) //ack_nack == 1 - подтверждение { //ack_nack == 0 - неподтверждение if(twi_Wait_TWINT() == 0x01) { unsigned char twi_last_status = twi_get_last_status(); if((twi_last_status == 0x50) || (twi_last_status == 0x58)) { *data = TWDR; if(ack_nack == 1) TWCR = (1 << TWINT|1 << TWEA|1 << TWEN); if(ack_nack == 0) TWCR = (1 << TWINT|1 << TWEN); return 0x01; //true } } else return 0x00; return 0; } Соответсвенно для работы с температурной микросхемой использую вот такие функции: void ADT75_init(void) { twi_start(); twi_write_address(0x90, 'w'); twi_write_byte(0x01); twi_write_byte(0x20); twi_stop(); } //--------------------------------------------------------------------------- void ADT75_start(void) { twi_start(); twi_write_address(0x90, 'w'); twi_write_byte(0x04); twi_stop(); } //--------------------------------------------------------------------------- char ADT75_read(void) { unsigned char read_temp_h = 0; unsigned char read_temp_l = 0; twi_start(); twi_write_address(0x90,'w'); twi_write_byte(0x00); twi_stop(); twi_start(); twi_write_address(0x90, 'r'); twi_read_byte(&read_temp_h, 1); twi_read_byte(&read_temp_l, 0); twi_stop(); return (char)read_temp_h; } Но почему то всё время функция ADT75_read(); очень часто возвращает 0. Т.е. симптомы такие - работает всё около часа, потом всё время возвращается 0. Если выключить и снова включить прибор, то может часа три поработать, потом опять нули. Посмотрите пожалуйста свежим взглядом, а то я уже замылился... зы: если надо - соответсвующие порты настроены как высокоомные входы, линия подтягиваеться резюками 6,8к (пробовал разные)... Так же на шине присутсвсует микросхема памяти 24CO4N (вроде как), так она работает правильно всё время...
  23. Палыч, у меня с усартом почти также))) Почти потому, что приём данных парсинг данных, подготовка ответных данных и инициация передачи у меня происходит в прерывании по приёму данных. Я так сделал по нескольким причинам - во-первых я могу в этом случае отсчтывать временные интервалы между пакетами данных, во-вторых я не позволяю обновляться внутренним данным обновляться во время обмена, да и много ещё почему... Передача же данных буферизирована и не задерживает программу. В общем спасибо всем за ответы, я получил ответ на свой вопрос)))
  24. Спасибо всем за ответы, я подчерпнул для себя много нового :) Палыч, если бы все эти функции могли бы выполняться одна за одной, то я бы таймер вообще не использовал. Так например между вызовами функциями BeginTempConvers(); и GetTempValue(); должно пройти по крайней мере полсекунды. Это особенность микросхемы-термометра. Плюс я ещё оставляю между вызовами функций много времени для того, чтобы свободного процессорного времени было много. Это делается для того, чтобы при использовании USART было бы побольше времени для выполнения функций, реализующих какой-либо протокол. Плюс ко всему в последнем проекте используеться микросхема памяти, запись данных в которую происходит очень много времени. _Pasha, ммм... а что такое "атомарный"? :) DpInRock, насчёт алгоритма понятно. Просто задачи я решаю в основном однотипные, которые сводятся к элементарной линейноти и очерёдности... haker_fox, ваши слова заставили меня задуматься... Чуствую в моих программах грядут большие изменения XVR ясно)))
  25. Кстате, а почему плохо? Спрашиваю для общего развития, а не для спора))) #include <io.h> volatile int counter; int main() { //инициализирую всё и вся for(;;) //уже не пустой бесконечный цикл { switch(counter) { case 100: BeginTempConvers(); counter++; break; //посылаю запрос для начала считывания температуры case 200: GetADCValue(); counter++; break; //считываю значение с АЦП case 300: ProcessADCValue(); counter++; break; //раситываю необходимые значения case 400: GetTempValue(); counter++; break; //считываю температуру case 500: SetAlarm(); counter++; break; //проверяю значения и вывожу аварийные сигналы если надо case 600: DisplayValues(); counter++; break; //вывожу все данные на экран } //counter инкрементируется для того, что бы функция невызывалась повторно в случае когда время итерации цикла меньше перода таймера } } ISR(SIG_OUTPUT_COMPARE1A) { counter++; if(counter == 601) counter = 0; } ммм.... так? Да логика то в моих реальных заданиях такая же простая как в примере))) А начсёт процедур - что за процедура UI?
×
×
  • Создать...