На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Atmel AT90S2313 + COM порт , помогите плиз передать данные
      Нужно передать данные с одного компа на другой через COM порт хотя бы в симплексном режиме.
      Есть плата, на которой размещены контроллер Atmel AT90S2313+RS232+кварцевый генератор и кое-какие необходимые мелочи, от нее отходит два кабеля, заканчивающиеся 9-пиновым COM разъемом, в котором используется только 3 пина - TXD, RXD, GND.
      Софт для WinXP написан в Visual Studio C++ 6.0 с использованием класса CSerialPort, скачанного с этого сайта.
      Вот ключевые кусочки кода:
      Пересылка данных:
      ExpandedWrap disabled
        CSerialPort port;
        clock_t start, finish;
        double  duration;
        char temp[20];
        char service='$';
        port.Open(1, 2400);
        if (!port.IsOpen())
        {
            MessageBox("PORT FAILS");
            return;
        };
        port.Write(&service, 1);
        start = clock();
        int Transf=port.Write(Data, Size);
        finish = clock();
        port.Write(&service, 1);
        duration = (double)(finish - start) / CLOCKS_PER_SEC;

      Прием данных (в др функции) :
      ExpandedWrap disabled
        CSerialPort port;
        port.Open(1,2400);
        if (!port.IsOpen())
        {
            MessageBox("PORT FAILS");
            return;
        };
         
        m_VEdit2="Receiving...";
        UpdateData(false);
        start = clock();
        Transf=port.Read(Data,MAXBUFFER);
        finish = clock();
        duration = (double)(finish - start) / CLOCKS_PER_SEC;

      глобальные переменные:
      const int MAXBUFFER=1000;
      char Data[MAXBUFFER];
      int Size;
      А теперь вопросы:
      1) Я правильно понимаю, что ,как правило, COM1, который юзается и для передачи, и для приема на др компе, на матке находится выше, чем СОМ2 (если смотреть на заднюю стенку)?
      2) Реально ли вообще передавать данные чисто через TXD/RXD, без вникания в протокол и использования служебных пинов типа DCD, DTR или WinAPI без них откажется просто отсылать/считывать сигнал по TXD/RXD с заданной частотой(с учетом стартового, стопового и паритетного бита)? А можно ли с использованием ассемблерной вставки получить доступ к этим пинам напрямую?
      3) как будет выглядеть Atmel ASM код, который нужно зашить в микроконтроллер? там наверно в пределах 6-7 строк. :unsure:
      Заранее спасибо
        1. Обычно да, если их несколько
        2. Точно не отвечу, не работал с СОМ портом
        3. Код полностью зависит от того что должен делать контроллер, как построена схема, какие элементы и т.д.
        Плюс можно писать и на сишке. Есть компиляторы C для AVR, например WinAVR (http://winavr.sourceforge.net/)
        И ещё момент, AT90S2313 давно снят с производства. Он заменен ATTiny2313. Распиновка та же, только более современный и мощьный.
          Цитата Radagast @
          Реально ли вообще передавать данные чисто через TXD/RXD, без вникания в протокол и использования служебных пинов типа DCD, DTR
          да.

          Цитата Radagast @
          А можно ли с использованием ассемблерной вставки получить доступ к этим пинам напрямую?
          нет.
            Цитата
            AT90S2313 давно снят с производства

            плата уже готова :) надо заставить ее работать
            trainer
            уточните плиз, вот тот С++ -шный код с 1го поста будет работать корректно, даже если служебные пины не задействованы?
              Цитата Radagast @
              уточните плиз, вот тот С++ -шный код с 1го поста будет работать корректно, даже если служебные пины не задействованы?
              Я не знаю внутреннего устройства CSerialPort. Чтобы не влияли DTR/DSR, RTS/CTS, XON/XOFF, надо в параметрах порта выключить программное/аппаратное управление потоком данных.
                trainer
                описание класса:
                ExpandedWrap disabled
                  void Open( int nPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE DataBits = 8, StopBits stopbits = OneStopBit, FlowControl fc = NoFlowControl, BOOL bOverlapped = FALSE);

                Метод использующийся для контроля потока данных. Может принимать след. значения:

                enum FlowControl
                {
                NoFlowControl,
                CtsRtsFlowControl,
                CtsDtrFlowControl,
                DsrRtsFlowControl,
                DsrDtrFlowControl,
                XonXoffFlowControl
                };

                bOverlapped TRUE если Вы хотите открыть в режиме overlapped, иначе FALSE для использования блокирующих вызовов.

                походу по умолчанию весь контроль отключен... :unsure:
                а что значит overlapped?
                Сообщение отредактировано: Radagast -
                  Цитата Radagast @
                  2) Реально ли вообще передавать данные чисто через TXD/RXD, без вникания в протокол и использования служебных пинов типа DCD, DTR или WinAPI без них откажется просто отсылать/считывать сигнал по TXD/RXD с заданной частотой(с учетом стартового, стопового и паритетного бита)? А можно ли с использованием ассемблерной вставки получить доступ к этим пинам напрямую?
                  3) как будет выглядеть Atmel ASM код, который нужно зашить в микроконтроллер? там наверно в пределах 6-7 строк. :unsure:
                  Заранее спасибо

                  2) да... на прямую - нет...про частоту...
                  а) необходимо знать параметры настроек со стороны МК. Подбирать можно если Вы знаете тактовую МК, тип МК, приблизительно что передаёт (имееться ввиду сами данные)...
                  б) частота последовательной передачи сильно зависит от кварца служащего для тактирования МК. Лучше всего со скоростями определиться - заглянув в даташит на данный МК. Вы сможете точно определить верхнию границу тактовой...
                  в) после нахождения параметров связи (параметры инициализации ком порта) - рекомендую выключить буфферизацию на передачу и делать тайм-ауты между байтами. Задержку подобрать лучше экспериментально и немного увеличить. Дело в том, что буффер приёма на МК как правило в один байт. Нужно обеспечить выемку со стороны МК переданного байта. Не всегда программа на принимающей стороне реализована так, чтобы обеспечивать прохождение без доп. тимингов...
                  3) код может выглядеть по разному...вариант а) - обслуга по прерыванию...смысл - при приёме очередного байта - прерывание которое вынимает байтик из буффера и сохраняет его в ОЗУ, либо обрабатывает - зависит от логики.. б) - обслуга по спулингу. ком порт постоянно опрашивается в некотором общем цикле для всей программы. при приходе символа - идёт сохранение в буффере и(или) обработка...

                  передача как правило всегда синхронна, хотя опять же никто не мешает и её навертеть асинхронную...если микроконтроллер AVR - вряд ли 6,7 строк... немного поболее :))) элементарные примеры - смотрите в даташитах на тот или иной МК. Примеры, как правило, есть на азме и на сях.


                  с уважением
                  (круглый)
                  ЗЫ
                  Рекомендую заюзать обращение к порту напрямую (хотя - хз, может класс Вам и поможет). При обращении напрямую к порту - не забывайте сбрасывать статус порта (помойму после каждого приёма) - иначе может затнкуться в неподходящий момент времени...
                    Цитата Radagast @
                    А можно ли с использованием ассемблерной вставки получить доступ к этим пинам напрямую?

                    Если Win выше 98 - нет.
                    Цитата Radagast @
                    как будет выглядеть Atmel ASM код, который нужно зашить в микроконтроллер? там наверно в пределах 6-7 строк.
                    Заранее спасибо

                    Побольше. Настройка генератора, настройка пинов для работы в режиме порта, настройка самого порта, включение модуля порта, настройка прерывания от порта, разрешение прерывания - все это навряд ли уложится в 7 строк asm кода микроконтроллера. :D
                      Итак, пока что тестируем МК сам по себе. Хочу посмотреть на тестере, что выдается на TXD при работе UART'a. Такой ведь код правильный?
                      ExpandedWrap disabled
                        .DEVICE AT90S2313
                        .CSEG
                            LDI UBRR, 95    ;4800 bauds, clock 7.3728 MHz
                            SBR UCR, 3  ;transmit enable
                            LDI R0, 0xFF    ;output "1"
                        LOOP:   LDI UDR, R0
                            JMP LOOP

                      и еще одна вещь меня очень беспокоит...
                      логическая "1" для CОМ порта это от -3 до -12 В, "0" от +3 до +12 В
                      а вот для ОМК (и UART'a ? ) "0" это скорее всего 0 В, а "1" где-то 5 В
                      в офиц документации точных цифр так и не нашел <_<
                      т.е. придется еще лепить кучу транзисторов для преобразования? или можно как-то программно заставить МК работать по-другому?
                        Цитата Radagast @
                        т.е. придется еще лепить кучу транзисторов для преобразования?

                        МАХ232,SD232 - микросхемы конвертеры - и ничего "лепить" не нужно. :D
                        Цитата Radagast @
                        или можно как-то программно заставить МК работать по-другому?

                        Насколько я знаю - нет. Но даташит на контроллер обязан прояснить эту ситуацию. :)
                          Цитата
                          МАХ232,SD232 - микросхемы конвертеры

                          спасибо, попробую заюзать :)
                          а код-то из 9го поста правильный?
                            Цитата Radagast @
                            а код-то из 9го поста правильный?

                            Нет. При таком раскладе модуль USART не включен - выводы контроллера работают как биты порта D, причем на ввод (по умолчанию после сброса). Попытка вывести байт FFH даже при включенном USART - максимум, что ты увидишь на экране осциллографа - высокий уровень, за который (ошибочно) можно принять и импеданс (особенно если на выходе будет вход МАХ"а). :) Что бы четко увидеть - рекомендую передавать 55Н - будешь наблюдать перепады уровня на выходе. :D

                            Добавлено
                            Еще маленькое но. Передачу следующего символа (загрузку регистра передатчика) нужно производить не ранее окончания передачи предыдущего, о чем тебя известит прерывание от передатчика (которое нужно настроить и, соответственно, разрешить + написать обработчик, расположенный по нужному вектору) т.к. очередь передатчика не резиновая и состоит всего из одного дополнительного регистра - следовательно передача различных байт в таком виде приведет к потере 3 байта, о чем тебя тоже известит регистр статуса передатчика, который ты и не подумал проверить перед подачей в передатчик очередного байта. :D Вывод - нужно более "трепетно" относится к рекомендациям разработчиков, которые они "доносят" до нас в даташитах. :D
                              medved_68 я не уверен, что получится достать осциллограф, хотелось бы просто увиделть +5 В на вольтметре, т.е. постоянную логич. "1" (ятп логич "0" это ~0 В) - на выходе TXD и примерно -10 В на выходе MAX232 - убедиться, что МК вообще работает и прошивается.
                              Цитата
                              модуль USART не включен - выводы контроллера работают как биты порта D, причем на ввод (по умолчанию после сброса).
                              а как это решается? Оо разве загрузки регистров UBRR и UCR недостаточно? при том, что по умолчанию все прерывания отключены

                              я исправил код:
                              ExpandedWrap disabled
                                .include "2313def.inc"    
                                    ldi r16,95  ;4800 bauds, 7.3728 MHz
                                    out UBRR,r16
                                    sbr r16, 3  ;transmit enable
                                    out UCR,r16
                                    ldi r16, 0xFF   ;output "1"
                                LOOP:   out UDR, r16
                                    rjmp LOOP
                              Сообщение отредактировано: Radagast -
                                Цитата Radagast @
                                что готовый проект компилится нормально, а те же самые команды, которые я написал, вызывают ошибку?

                                Есть такая директива - include. При помощи этой директивы подключается файл где есть такое:
                                ExpandedWrap disabled
                                  UBRR equ 0x0009;
                                и т.д. Этим ты даешь понять компилятору, что метку UBRR нужно заменить на адрес регистра 09Н. Иначе:
                                Цитата Radagast @
                                Illegal argument type or count

                                тебе же русским языком говорят, что плохой, неизвестный и т.п. аргумент. :D Если ты не знаешь, где этот файл подключен (нет исходника работающего кода и т.д.), то изволь вручную набить в начале своей программы все эквиваленты регистров или же оперировать не мнемоникой (типа UBRR), а реальными адресами в НЕХ коде. :)
                                Цитата Radagast @
                                а как это решается? Оо разве загрузки регистров UBRR и UCR недостаточно?

                                А каким битом ты его включаешь и где? :)
                                  medved_68 я отредактил пост, глянь плиз :)
                                  теперь все норм компилится, отослал HEX на прошивку...

                                  Добавлено
                                  у меня есть этот инклуд
                                    Radagast выкинь лучше на порт ноль, и проверяй замером напряжения нога передатчика - питание. Так поймаешь если импеданс.

                                    Добавлено
                                    А про очередь передатчика - игнор? :D
                                      medved_68 ой...так "в состоянии покоя" на ножке TXD высокий потенциал? :(
                                      про очередь - спасибо за совет, это мне пригодится, когда буду полноценную прогу писать. Т.е. сегодня :)
                                        Цитата Radagast @
                                        medved_68 ой...так "в состоянии покоя" на ножке TXD высокий потенциал?

                                        Нет, это импеданс. По сбросу нога подключена к порту D - режим ввод. Поэтому и говорю - выбрось ноль. :D И увидишь, что ничего не измениться.
                                          скажите еще плиз, чем отличается jmp от rjmp? судя по описанию в прогах для перехода на метку нужно юзать jmp, так же как и в ASM8086, но в примерах прог я везде вижу rjmp

                                          Добавлено
                                          medved_68 хорошо, я выброшу ноль, только объясните, что значит умное слово "импеданс"? оно как-то выражается в вольтах?
                                            Цитата Radagast @
                                            скажите еще плиз, чем отличается jmp от rjmp? судя по описанию в прогах для перехода на метку нужно юзать jmp, так же как и в ASM8086, но в примерах прог я везде вижу rjmp

                                            А где ты в даташите увидел инструкцию jmp??? :) rjmp - это короткий переход высчитывается смещением от места вызова (относительный), до 80Н - вперед, свыше назад + 1 к программному счетчику.
                                            Цитата Radagast @
                                            medved_68 хорошо, я выброшу ноль, только объясните, что значит умное слово "импеданс"? оно как-то выражается в вольтах?

                                            Отключен, или Z-состояние. Вольтметром ловится порядка 3 - 3.8В - достаточно, чтобы сделать вывод: "Ага, единица!!!", но на деле это не так. Осциллографом - если в момент контакта с пином тронуть шину пальцем - видно на экране шум, чего не бывает при достоверном логическом уровне. :)
                                              medved_68 а какие вольтажи для AT90S2313 соответствуют "1" и "0" ? в документации я не нашел :(
                                                Цитата Radagast @
                                                а какие вольтажи для AT90S2313 соответствуют "1" и "0" ? в документации я не нашел

                                                0.3 - 0.8В для "0", 70%VCC - для "1". Стандарты соответствуют уровням CMOS технологии, поэтому в даташитах обычно опускается. :)
                                                  medved_68 спасибо :)
                                                  предыдущая прога заработала нормально (выкидывал 0)
                                                  сегодня написал прогу собственно по курсачу. Компилится нормально, но я так и не увидел, где в симуляторе AVR Studio можно имитировать сигнал на RXD, так что перед прошивкой выложу код. Глянь плиз, может глазами увидишь какие-то логические ошибки.
                                                  Принцип работы такой - через UART принимается 100 байт данных на скорости 2400 бит/с, записываются в SRAM, а потом передаются через TXD на скорости 4800 бит/с.
                                                  ExpandedWrap disabled
                                                    .include "2313def.inc"
                                                    .def x1=r16         ;accumulator
                                                    .def x2=r17         ;byte counter up to 100
                                                     
                                                    .org 0              ; вектора прерываний
                                                            rjmp Reset    
                                                    .org    URXCaddr
                                                            rjmp mrxc   ;interrupt RXC
                                                    .org    UDREaddr
                                                            rjmp mudre  ;interrupt UDRE
                                                     
                                                    RESET:
                                                        ldi x1,ramend   ;stack define
                                                        out spl,x1
                                                        
                                                    recpr:  ldi x1,0b10010000           ;подготовка к приему
                                                        ;бит7-RX Complete Interrupt Enable
                                                        ;бит6-TX Complete Interrupt Enable
                                                        ;бит5-UART Data Register Empty Interrupt Enable
                                                        ;бит4-Receiver Enable
                                                        ;бит3-Transmitter Enable
                                                        ;бит2-9 Bit Characters
                                                        ;бит1-Receive Data Bit 8
                                                        ;бит0-Transmit Data Bit 8
                                                        out UCR,X1
                                                     
                                                        ldi x1,191  ; при кварце 7.3728МГц, скорость =2400
                                                        out UBRR,x1
                                                        ldi zh,0    ;инициализация адреса ОЗУ
                                                        ldi zl,$60
                                                        ldi x2,0    
                                                        sei
                                                     
                                                    wait:   rjmp wait   ;infinite cycle
                                                    ;-------------------------------------
                                                    trapr:  ldi x1,0b00101000 ;подготовка к передаче
                                                        out UCR,X1
                                                        ldi x1,95   ; при кварце 7.3728МГц, скорость =4800
                                                        out UBRR,x1
                                                        ldi zh,0    
                                                        ldi zl,$60
                                                        ldi x2,0
                                                        sei
                                                        rjmp trans
                                                    ;-------------------------------------
                                                     
                                                    mrxc:   in x1, UDR ;прием
                                                        st Z+, x1
                                                        inc x2
                                                        cpi x2, 100
                                                        BREQ trapr
                                                        reti
                                                    ;-------------------------------------
                                                    trans: ;передача
                                                    mudre:  LD x1, Z+
                                                        out UDR, x1
                                                        inc x2
                                                        cpi x2, 100
                                                        BREQ recpr
                                                        reti
                                                  Сообщение отредактировано: Radagast -
                                                    Цитата Radagast @
                                                    А теперь вопросы:
                                                    1) Я правильно понимаю, что ,как правило, COM1, который юзается и для передачи, и для приема на др компе, на матке находится выше, чем СОМ2 (если смотреть на заднюю стенку)?

                                                    Не всегда, лучше ссылаться на документацию к матке.
                                                    Цитата

                                                    2) Реально ли вообще передавать данные чисто через TXD/RXD, без вникания в протокол и использования служебных пинов типа DCD, DTR или WinAPI без них откажется просто отсылать/считывать сигнал по TXD/RXD с заданной частотой(с учетом стартового, стопового и паритетного бита)? А можно ли с использованием ассемблерной вставки получить доступ к этим пинам напрямую?


                                                    Реально. Поставить на портах перемычки на DTR-DSR и RTS-CTS или отключить их проверку программно.

                                                    Насчет прямого доступа к портам, в принципе можно и под NT5+ через драйвера
                                                    giveIO, ntport,
                                                    WinIO
                                                    но для совместимости ИМХО лучше по максимуму держаться подальше от таких решений.
                                                      Цитата Radagast @
                                                      Компилится нормально, но я так и не увидел, где в симуляторе AVR Studio можно имитировать сигнал на RXD, так что перед прошивкой выложу код.

                                                      Нет эмуляции передачи. Ты можешь эмулировать прерывание (если разрешено) записав в приемный регистр байт, который якобы пришел на порт и в отладчике просмотреть по шагам работу программы (отклик на прерывание).
                                                      Цитата Radagast @
                                                      Глянь плиз, может глазами увидишь какие-то логические ошибки.

                                                      1. Главное правило - сохраняй ВСЕ регистры при переходе по вектору прерывания, вплоть до регистров статуса и флагов. У тебя этого нет.
                                                      2. Идем по логике - принял на скорости 2400, передал на 4800, а если в цикле??? Каким макаром главная программа, которая крутиться в бесконечном цикле:
                                                      Цитата Radagast @
                                                      ExpandedWrap disabled
                                                        wait:   rjmp wait
                                                      узнает, что все передано и что то нужно далее делать, например, опять вернуть скорость порта назад (для дальнейшего приема) или залечь в Sleep для экономии энергии??? Я понимаю, что ты пока учишься, но ТАКИЕ вещи (оставление "черных ходов") для "себя любимого", чтобы облегчить себе дальнейшую жизнь при наращивании прошивки - надо закладывать сразу, это фундамент. :) Да и препод, зацепившись за это, начнет задавать вопросы в ЭТОМ русле, а не в другом, а ты к ним готов! :D Надеюсь - мысль понятно оформил? ;)
                                                        medved_68
                                                        1. наверно вопрос прозвучит диким, но - зачем? :unsure: в данном случае я такой необходимости не вижу. Дальнейшего развития у проги не будет - сдам и забуду, как страшный сон :)
                                                        и что конкретно Вы имеете в виду?
                                                        ExpandedWrap disabled
                                                          push sreg

                                                        и куда это запихнуть? и потом pop'ить? и что такое регистр флагов? :blink:

                                                        2.
                                                        Цитата
                                                        узнает, что все передано и что то нужно далее делать

                                                        переход по метке mudre при каждом прерывании "регистр данных UART'a пуст" - при передаче данных.
                                                        есть отдельные блоки для подготовки приема и передачи - с обнулением счетчика и настройкой UART'a, вроде все логично связано...
                                                          Цитата Radagast @
                                                          и куда это запихнуть? и потом pop'ить? и что такое регистр флагов?

                                                          Перед началом обработки прерывания. Флаги - флаг нуля, переполнения переноса, частичного переноса и т.д.
                                                          Цитата Radagast @
                                                          переход по метке mudre при каждом прерывании "регистр данных UART'a пуст" - при передаче данных.

                                                          Цитата Radagast @
                                                          ExpandedWrap disabled
                                                            mudre:  LD x1, Z+
                                                                    out UDR, x1
                                                                    inc x2
                                                                    cpi x2, 100
                                                                    BREQ recpr
                                                                    reti
                                                          Если равно 100 - пропускаем загрузку регистра передатчика и на выход. А на выходе бесконечный цикл...и прерываний от передатчика больше не будет и? :D Так и будет крутиться, бедняга. :D Хотя для этого:
                                                          Цитата Radagast @
                                                          Дальнейшего развития у проги не будет - сдам и забуду, как страшный сон
                                                          даже того, что написал и прерывания прицепил - достаточно, здесь я полностью с тобой согласен. :D
                                                            Цитата
                                                            пропускаем загрузку регистра передатчика и на выход.

                                                            а на выходе подготовка к приему след. 100 байт и ожидание
                                                            Цитата
                                                            даже того, что написал и прерывания прицепил - достаточно

                                                            надо, чтобы прога работала...потому что на данный момент что-то не пашет :( данные с компа уходят, а прога на принимающем компе виснет на Listening... так что хочется быть уверенным, что причина не в АСМ коде.

                                                            Добавлено
                                                            я правильно понимаю, что BREQ - переход по метке, если числа равны?
                                                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                            0 пользователей:


                                                            Рейтинг@Mail.ru
                                                            [ Script execution time: 0,0740 ]   [ 16 queries used ]   [ Generated: 25.04.24, 13:05 GMT ]