Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обработка DMX512
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
yrbis
Подскажите, плз, как приспособить PIC16F876 под прием этого долбанного DMX512... Не удается никак принять второй байт в пачке. Использую встроенный USART, но у меня постоянно устанавливается ошибка приема FERR. Может что-то натупил с алгоритмом:
0. сбрасываю CREN и SPEN в RCSTA
1. жду "0"
2. если длина этого "0" меньше ~88us, перехожу к 1.
3. жду "1"
4. устанавливаю SPEN и CREN в RCSTA
5. жду прихода байта по флагу RCIF в PIR1
6. если была ошибка при приеме (установлены: бит FERR или OERR в RCSTA), то вызываю RX_ERR и иду к 0.
7. если байт в RCREG != 0, иду к 5.
8. жду прихода второго байта по флагу RCIF в PIR1
9. если была ошибка при приеме (установлены: бит FERR или OERR в RCSTA), то вызываю RX_ERR и иду к 0.
10. посылаю байт из RCREG в PORTB на ЦАП
11. иду к 0.

Функция RX_ERR стирает RCSTA и мигает диодом на плате...

После запуска диод постоянно мигает а на входах ЦАПа нули...

Короче, если кто-нибудь знает нормально-работающий код для приема DMX512 -- напишите!!!
yrbis
...))если будут проблемы с сабж обращайтесь... Всем огромное спасибо)
DL36
Цитата(yrbis @ May 1 2007, 18:11) *
Подскажите, плз, как приспособить PIC16F876 под прием этого долбанного DMX512... Не удается никак принять второй байт в пачке. Использую встроенный USART, но у меня постоянно устанавливается ошибка приема FERR. Может что-то натупил с алгоритмом:
0. сбрасываю CREN и SPEN в RCSTA
1. жду "0"
2. если длина этого "0" меньше ~88us, перехожу к 1.
3. жду "1"
4. устанавливаю SPEN и CREN в RCSTA
5. жду прихода байта по флагу RCIF в PIR1
6. если была ошибка при приеме (установлены: бит FERR или OERR в RCSTA), то вызываю RX_ERR и иду к 0.
7. если байт в RCREG != 0, иду к 5.
8. жду прихода второго байта по флагу RCIF в PIR1
9. если была ошибка при приеме (установлены: бит FERR или OERR в RCSTA), то вызываю RX_ERR и иду к 0.
10. посылаю байт из RCREG в PORTB на ЦАП
11. иду к 0.

Функция RX_ERR стирает RCSTA и мигает диодом на плате...

После запуска диод постоянно мигает а на входах ЦАПа нули...

Короче, если кто-нибудь знает нормально-работающий код для приема DMX512 -- напишите!!!

Какого плана ошибка? Переполнение или кадра.
Постоянно выключать модуль USART не надо(SPEN) достаточно выключить прием(CREN)
yrbis
Цитата(DL36 @ May 3 2007, 14:17) *
Какого плана ошибка? Переполнение или кадра.
Постоянно выключать модуль USART не надо(SPEN) достаточно выключить прием(CREN)


Проблема была по большому счету с переполнением... Я не выключал приемник сразу после удачного чтения, и он естесственно читал дальше и вызывал постоянное переполнение...
А вообще хотелось бы увидеть правильный код обработчика протокола DMX512, а то, например, сейчас иногда виснет PIC на строках:

BTFSS PIR1, RCIF
GOTO $-1

если включить сначала плату с ПИКом, а потом модуль DMX512.
fantasy
Код
    //Приём с линии DMX512

    if(RCIF)
    {
        if(!OERR)
        {
            if(RX9D&&(!FERR))
            {//принят байт без ошибок
                tempISRhi = RCREG;
                if(dmx__wasBREAK!=false)
                {
                    if(dmx__wasSCode!=false)
                    {
                        if(dmx__curAdr >= dmx_baseAdr)
                        {
                            DMX_Array[dmx__chNum] = tempISRhi;
                            dmx__chNum++;
                            if(dmx__chNum>=maxChNum)
                            {
                                dmx__wasBREAK=false;
                                dmx_syncBREAK=true;
                            };
                        }
                        else dmx__curAdr++;
                    }
                    else
                    {//проверяем на стартовый код
                        if(tempISRhi==0x00)
                        {
                            dmx__wasSCode = true;
                            dmx_error = false;
                            dmx_tmrDMX = 0;
                        }
                        else dmx__wasBREAK=false;
                    };
                };
            }
            else
            {//детектирование сигнала BREAK (ошибка кадра или отсутствие стопового бита)
                dmx__curAdr = 0;
                dmx__chNum = 0;
                if(dmx__wasBREAK==true)dmx_syncBREAK=true;
                dmx__wasBREAK = true;
                dmx__wasSCode = false;
                tempISRhi = RCREG;
            };
        }
        else
        {//переполнение аппаратного буфера
            dmx_error = true;
            dmx__wasBREAK = false;
            slaveStart = false;
            CREN = 0;
            CREN = 1;
            while(RCIF)tempISRhi = RCREG;
        };
    };



...



    //таймер ошибки DMX (~1,2 сек.)
    dmx_tmrDMX++;
    if(dmx_tmrDMX==75)
    {
        dmx_error = true;
        dmx_tmrDMX--;
    };




Вот полностью рабочий и неоднакратно проверенный жизнью код. Кстати, если-бы Вы не поленились и глянули на сайт www.microchip.com то нашли-бы искомое: http://www.microchip.com/stellent/idcplg?I...ppnote=en527825
xemul
Цитата(fantasy @ May 6 2007, 21:02) *

Так, на всякий случай... Использование down-counter'ов обычно дает более компактный код.
Код
// somewhere in code
   dmx_tmrDMX = MAX_DMXTMR_TIME;
...
   //таймер ошибки DMX (~1,2 сек.)
   if(dmx_tmrDMX)
      if(!--dmx_tmrDMX)
      {
         dmx_error = true;
         ...
      };
fantasy
Цитата(xemul @ May 6 2007, 21:27) *
Так, на всякий случай... Использование down-counter'ов обычно дает более компактный код.
Код
// somewhere in code
   dmx_tmrDMX = MAX_DMXTMR_TIME;
...
   //таймер ошибки DMX (~1,2 сек.)
   if(dmx_tmrDMX)
      if(!--dmx_tmrDMX)
      {
         dmx_error = true;
         ...
      };


smile.gif Эту особенность я оч. хорошо знаю, но всё равно спасибо за коментарий.
yrbis
Цитата(fantasy @ May 6 2007, 21:02) *
Код
    //Приём с линии DMX512

    if(RCIF)
    {
        if(!OERR)
        {
            if(RX9D&&(!FERR))
            {//принят байт без ошибок
                tempISRhi = RCREG;
                if(dmx__wasBREAK!=false)
                {
                    if(dmx__wasSCode!=false)
                    {
                        if(dmx__curAdr >= dmx_baseAdr)
                        {
                            DMX_Array[dmx__chNum] = tempISRhi;
                            dmx__chNum++;
                            if(dmx__chNum>=maxChNum)
                            {
                                dmx__wasBREAK=false;
                                dmx_syncBREAK=true;
                            };
                        }
                        else dmx__curAdr++;
                    }
                    else
                    {//проверяем на стартовый код
                        if(tempISRhi==0x00)
                        {
                            dmx__wasSCode = true;
                            dmx_error = false;
                            dmx_tmrDMX = 0;
                        }
                        else dmx__wasBREAK=false;
                    };
                };
            }
            else
            {//детектирование сигнала BREAK (ошибка кадра или отсутствие стопового бита)
                dmx__curAdr = 0;
                dmx__chNum = 0;
                if(dmx__wasBREAK==true)dmx_syncBREAK=true;
                dmx__wasBREAK = true;
                dmx__wasSCode = false;
                tempISRhi = RCREG;
            };
        }
        else
        {//переполнение аппаратного буфера
            dmx_error = true;
            dmx__wasBREAK = false;
            slaveStart = false;
            CREN = 0;
            CREN = 1;
            while(RCIF)tempISRhi = RCREG;
        };
    };



...



    //таймер ошибки DMX (~1,2 сек.)
    dmx_tmrDMX++;
    if(dmx_tmrDMX==75)
    {
        dmx_error = true;
        dmx_tmrDMX--;
    };




Вот полностью рабочий и неоднакратно проверенный жизнью код. Кстати, если-бы Вы не поленились и глянули на сайт www.microchip.com то нашли-бы искомое: http://www.microchip.com/stellent/idcplg?I...ppnote=en527825

1. А что такое dmx_syncBREAK? И зачем ему два раза TRUE присваивают?
2. На сайте MICROCHIP'а не догадался в поисковике набрать DMX512... Искал через Source Codes на свой камень.
3. Камень, кстати, как я уже писал раньше: 16F876 (уже перехожу на 16F73). Говорят, что под эти ПИКи лучше писать на ассемблере...
4. Данные надо было не только принимать, но и отправлять выборочно (об этом я не говорил правда)
5. Спасибо за все, но у меня уже и так все работает... wink.gif

P.S. Просто это был мой первый опыт с микроконтроллерами...
P.P.S. "Спасибо" относится ко всем ответившим...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.