Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Работа с UART

Вт апр 09, 2019 16:08:13

Всем доброго времени суток! Работаю над чтением по UART GPS данных с SIMM68m. Контроллер PIC18F47J53, кварц на 24 МГц. Программирую в среде MicroPascal используя встроенные библиотеки.

Подключаю UART на ножки RC0 - Rx, RC1 - Tx. Настраиваю на вход и выход, хоть в даташите сказано, что настройка автоматическая. Делаю ремап, инициализирую на скорость 115200, обрабатываю прерывание(в него заходит проверял), но вот в итоге буфер чтения всегда пустой. Не могу понять куда копать.

Код:
procedure interrupt;
var delim:string[2];
begin
  if PIR3.RC2IF=1 then begin  //Прерывание от GPS
     delim:=chr($0D)+chr($0A);
     if UART_Remappable_Data_Ready()<>0 then
     begin
           RC6_bit :=1;
          UART_Remappable_Read_Text(gps_buff1,delim,200);
     end;
     PIR3.RC2IF:=0;
  end;
 
end;


Код:
procedure InitKernel();
begin
     pmpen_bit := 0;    // Отключаем паралельный порт
     CM1CON := 0;       // Отключаем анаоговые компараторы
     CM2CON := 0;

     //Настройка портов Аналог/Цифра  Все порты цифра
     ANCON0 := %11111111;
     ANCON1 := %11111111;
         
      //Инициализация портов ввода вывода       1 - вход 0 - выход
     LATA:=0;
     TRISA:=%00101100;
     PORTA:=0;

     LATB :=0;
     TRISB := %11100001;
     PORTB := %00000000;

     LATC :=  0;
     TRISC := %00100001;
     PORTC:=  0;
   
     LATD :=0;
     TRISD := 0;
     PORTD:=0;

     //RE2 изначально равен 1 (дешифратор не активен)
     LATE :=0;
     TRISE := %00000000;
     PORTE:= %00000100;
     
     // Ремапим UART2
     Unlock_IOLOCK();
     PPS_Mapping(12, _OUTPUT, _TX2_CK2);
     PPS_Mapping(11, _INPUT, _RX2_DT2);
     Lock_IOLOCK();   
     
     //Инициализируем UART2
     UART_Remappable_Init(115200);
     //U2OD_bit :=1;
     delay_ms(100);

    // sim68_Sleep();  // Отправляем в сон навигатор
     //запуск часов
     Clock_write($0C,0);
     //Тестируем карту памяти
     FS_SDSel();
     // инициализируем карточку если ошибка выдаём сообщение и выключаемся
     if FS_SDinit()<>0 then begin
     repeat until PORTA.B5<>1;
            delay_ms(200);
            PowerOff;
     end;
     // включаем подсветку
     Filename := 'regul.cfg';
     pregLigth := FS_Config_Read(0);
     SendToWK2(0x01,pregLigth);
     delay_ms(500); //Делаем задержку перед включением подсветки
     // Сброс и инициализация LCD дисплея
     InitDisplay();
end;

Re: Работа с UART

Вт апр 09, 2019 16:59:40

Лично я с новым для меня оборудованием поступаю так: подключаю к компьютеру через переходник и при помощи программы RS232 отлаживаю диалог, а потом уже подключаю к микроконтроллеру ;)

Re: Работа с UART

Вт апр 09, 2019 19:47:04

В ПЕРВУЮ очередь настраивают эхо. В части МК даже есть такой режим - ничего не надо перемыкать.

Re: Работа с UART

Ср апр 10, 2019 06:12:33

Режим эха? Что-то не припомню такого в этом семействе...
"Ничего не надо перемыкать" - а если порт битый? Толку от эха?
А если у SIMM68m проблема с портом, то как обмен отлаживать?
ТС имеет ДВА не проверенных устройства... Ладно, пусть шаманит, может угадает... ;)
В общем лично мне не понятен совет КРАМ-а...

Re: Работа с UART

Ср апр 10, 2019 06:24:12

Совет очень простой. Проверить УАРТ контроллера. Стандартная процедура, прежде чем подключаться к другому устройству.

Re: Работа с UART

Ср апр 10, 2019 09:18:38

Спасибо за советы! Uart устройства работает, проверял осцилографам, пачки данных идут и так же приходят на контроллер. В начале были неправильно соеденены устройство и контроллер TX<->TX, Rx<->RX, исправив это появилась новая проблема.. после

Код:
UART_Remappable_Init(115200);


Контроллер виснет.. Пробывал менять скорость ничего не помогает.

Re: Работа с UART

Ср апр 10, 2019 09:30:06

Контроллер не умеет виснуть. Контроллер может уйти на нештатное исполнение кода. Для этого существует аппаратная отладка (дебаг).

Re: Работа с UART

Чт апр 11, 2019 08:00:03

Ура, получил наконец то сообщения от GPS. Причиной "зависания" был постоянный уход в прерывание и не верная скорость, всетаки 9600 а не 115200. Осталась последняя проблема это в начало посылки добавляется 2 байта.

Код:
     $P$GNRMC,135549.041,V,,,,,0.27,0.00,100419,,,N*51

     $G$GNRMC,135551.041,V,,,,,0.40,0.00,100419,,,N*59


должно приходить
Код:
     $GNRMC,135549.041,V,,,,,0.27,0.00,100419,,,N*51

     $GNRMC,135551.041,V,,,,,0.40,0.00,100419,,,N*59


Не приложу ума, в какую сторону нужно копать!?

Re: Работа с UART

Вт июл 02, 2019 13:45:51

Доброго времени суток.

Что бы не создавать новых тем напишу в этой. Сново вопрос про UART. Соединяю два мк PIC18F47j53. Посылаю байт 0xBB, вторым мк принимаю и отправляю вновь. Смотрю осцилографом на порт приходит то что надо, принимает мк и отправляет тот же байт, но вот в обработчике не видно его светодиод не загорается. Предпологается использовать совместно с SPI (пин RC7 общий для SPI и UART). И еще вопрос, должны ли совпадать уровни сигнала? У меня на TX единица 3V, а на RX еденица 5 V

принимающая сторона
Код:
procedure EUSART1_Initialize();
begin
    TRISC.B7 := 1;
    PORTC.B7 := 0;
    LATC.B7  := 0;
    // disable interrupts before changing states
    // ABDOVF no_overflow; TXCKP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; RXDTP not_inverted;
    BAUDCON1 := 0x08;

    // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled;
    RCSTA1 := 0x90;
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
    //TXSTA1 := 0x24;
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH lo_speed; CSRC slave_mode;
    TXSTA1 := 0x20;
    //
    SPBRG1 := 0x08;
    //
    SPBRGH1 := 0x00;
end;

procedure EUSART1_Write(tx_byte: byte);
begin
  while(TRMT1_bit <> 1) do ;
        TXREG := tx_byte;
end;

function EUSART1_Read(): byte;
begin
    if(RCSTA1.OERR) then
    begin
        CREN1_bit := 0;
        CREN1_bit := 1;
    end;
    result := RCREG1;
end;

function EUSART1_Data_Ready(): byte;
begin
     if (RCIF_bit = 0) then
       result := 0 else
       result := 1;
end;

// Обработчик в прерывании
procedure interrupt;
begin
  if (PIR1.RC1IF) then
  begin
       if (EUSART1_Data_Ready() = 1) then
       begin
         pByteUART := EUSART1_Read;
         if pByteUART = 0xBB then
            PORTD.B4 := 1
            else
            PORTD.B4 := 0;
         EUSART1_Write(pByteUART);
       end;
     PIR1.RC1IF := 0;
  end;
end;

Re: Работа с UART

Ср июл 03, 2019 14:03:05

Первое - согласовать уровни . Приемник RX при питании 5 вольт требует логический ноль ниже 0,2 питания и единицу выше 0,8 питания. Контроллер от 3,3 вольт такого обеспечить не может.

Re: Работа с UART

Ср июл 03, 2019 14:41:19

Первое - согласовать уровни . Приемник RX при питании 5 вольт требует логический ноль ниже 0,2 питания и единицу выше 0,8 питания. Контроллер от 3,3 вольт такого обеспечить не может.


Пробовал закольцевать UART на одном и втором контроллере, прием и передача работают в рамках одного контроллера. А вот между контроллерами не работает. Если правильно понимаю, то раз принимает и передает в кольце, значит 0 и 1 распознаются.

Re: Работа с UART

Чт июл 04, 2019 10:38:47

Вам проще питать оба контролера от одного уровня напряжения. Либо три либо пять. И все заработает.

Re: Работа с UART

Чт июл 04, 2019 12:44:54

Контроллеры питаются от от одного уровня 3.3. Но на линии RX сделана включение разрешения работы с этой линией, так как используется еще SPI. И вот микросхема на выходе дает 5 вольт.

Re: Работа с UART

Чт июл 04, 2019 13:30:49

Лично я ничего не понял про SPI... Какое он имеет отношение к UART-у? Схему можно привести?

Re: Работа с UART

Чт июл 04, 2019 16:27:25

Схему выложу завтра. Открылась еще одна особенность. Один контроллер работает с кварцем на 24 МГц. Второй - 19,44. Инициализацию UART провел исходя из частоты кварца. В итоге тоже самое: если замкнуть в кольцо TX-RX передача и прием работают, а вот между собой не хочет принимать. Нужно ли что то еще настраивать?

Re: Работа с UART

Пт июл 05, 2019 03:45:44

Какой то треш, а не объяснения...
Разница частот слишком мала, чтобы быть существенной при настройке рейта. И несовпадение рейтов передатчика и приемников не может привести к отсутствию связи, а лишь ошибкам при передаче, включая ошибку фрейма. Вход в прерывание у приемника должен быть даже при одном импульсе на его входе.
Отсутствие приема возможно при переполнении буфера приемника. Восстановить связь можно, только перезапустив модуль УАРТ. Сброс флага OERR вручную невозможен, он сбрасывается автоматически при перезапуске.

Re: Работа с UART

Пт июл 05, 2019 11:33:52

Скорее всего мои кривые руки чего то не так делали. В общем сейчас прием и передача работают, но беда теперь другая: В цикле от 0 до 255 посылаю в порт UART число 0xAA принимаю вторым мк и вновь оправляю первому. Первым мк принимаю в массив и потом записываю в файл. В итоге приходит сплошной мусор. Скорость настраиваю исходя из частоты кварца, по формуле из datashit. Подскажите, куда стоит еще посмотреть? Возможно совпадение, но похоже, что первый байт правильный приходит.

Re: Работа с UART

Пт июл 05, 2019 12:51:56

FERR и OERR какое значение имеют?
Рейт можно посмотреть осциллографом на выходе Tx. И сравнить у двух МК.

Re: Работа с UART

Пн июл 08, 2019 11:46:20

Проверял по отдельность FERR и OERR устанавливаются в 1.

Re: Работа с UART

Пн июл 08, 2019 12:20:01

Их нельзя проверять в останове на брекпойнте. Нужно копировать регистр в переменную и только в этой переменной проверять.
Ни один из битов не должен быть установлен. Это ошибки фрейма (отсутствие стоп-бита) и переполнения буфера.
Ответить