Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Странен проблем с RS на 877А
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=798
Страница 1 от 2

Автор:  ToHu [ Чет Юни 23, 2005 7:09 am ]
Заглавие:  Странен проблем с RS на 877А

Така ... какво става в общи линии :
#INT_RDA
rda_isr()
{
recive=getc();
....
}

това е прекъсването. Вътре има и разпознаване на \r\n и др. подобни но това не е интересно. Значи понякога всичко работи .... при получаване на команда тя се изпълнява, НО ... понякога не работи. Как така по някога не знам. Тоя софт работи от доста време, тая част е многократно тествана. Последната промяна е преди 3-4 месеца, но реално няма пряко отошение към тая част.
Преди месец два може би просто прекомпилирах без да пипам нищо, и явно от тогава са почнали проблемите.
Понякога лсед рестарт спира да работи. Пуснах го вера в дебъг режим и какво виждам, ами то изобщо не влиза в прекъсването, или по точно при първия приет байт влиза, и след това не ще. CCS показва малко глупости, щото като гледам Interrupt данните в дебъгера казва че един куп прекъсвания са забранени, но като ги гледам същите в съответните модули са разрешени, а и съдържанието на регистрите е правилно.
Та .... нещата са повече от странни, преди време нещо друго се беше счупило така,съвсем без пречина, не разбрах от какво стана, взех си файловете от архива, преинсталирах винбоз и комплатор и всичко се оправи.

Автор:  Lino [ Чет Юни 23, 2005 8:47 am ]
Заглавие: 

Как излизаш от ситуация на препълване?

Автор:  [ Чет Юни 23, 2005 9:01 am ]
Заглавие: 

Колеги, пускайте листинга на програмите, в които имате проблем, това много помага :?

Автор:  ToHu [ Чет Юни 23, 2005 1:06 pm ]
Заглавие: 

Препълване на буфера ли ?

Автор:  zax [ Чет Юни 23, 2005 1:29 pm ]
Заглавие: 

това и аз съм го наблюдавал в сравнително кратката работа с CCS на 876а после се оказа че проблема е в хардуерния i2c които за 876а беше бъгав след като го изключих всичко се оправи и засега работи / да чукна на дърво .... :-) /
а за 87 съм публикувал подобни странности
ето един пример от днес

//--
if ( comp1 == no_date && comp2 == no_date )
{
CRC_Result = 0xFC2E; // dobawqm kontr suma
printf("\r\n|no_date|[%lu]\r\n", CRC_Result);
goto END_DATA;
}
//--

това нещо съм го пробвал многократно но днес ми излизат всякакви бози на мястото на |no_date, за сметка на това всичко в кв. скоби е нормално
а това е нещо с което съм имал проблеми виж " CCS проблеми "
както и да е, проблема с no_date ми се оправи след като затворих и отворих наново CCS и вградения към него монитор на RS порта

Пирев изказа предложение но не съм го пробвал засега просто защото
работи а имам по спешна задача
съмнявам се да е приема данните за 32бита защото като пробвам да сменя формата и ми бълва грешки и изобщо не стига до компилиране
по скоро е в компилатора който не си адресира правилно страниците на паметта но това си е само мое предположение и по никакъв начин не мога да го докажа

сега преследвам проблем които се оказва подобен няма да го коментирам засега но общо казано като седна на моя комп и през моя порт всичко е добре , но като мина на комп на колегата от високото ниво от време на време се наблюдават части от единия клон на програмата да се прехвърлят на другия лошото е че няма закономерност и е адски трудно да хвана такъв проблем защото не знам кога ще се появи

Автор:  ToHu [ Чет Юни 23, 2005 1:37 pm ]
Заглавие: 

#int_RDA
rda_irs()
{
recive=getc();
//------------------------------------------------------------------------------------------------
if(recive==0x0A || recive==0x0D) // when recive \r or \n
{
if(rb>0)
{
data_available=1; // and set data available flag
}
rb=0; // clear pointer to recive bufer
}
else
{
recive_data[rb]=recive; // write recive data to recive bufer
rb++;
if(rb>15)
{
rb=0;
}
}
if(rb==1)
{
com_time_out=0;
}
}

ето го кода .... току що отворих стар проект,в които няма проблем и вс. работи ..... сравних ги , няма разлики засягащи RS-а ... да не кажа че няма никакви ралзики освен че тук имам една константа дето не я ползвам,в стария има един празен ред в повече, и в новия при стартиране проверявам състоянието на флаговете за рестарт и състоянието на BOR .. всъшност даже не го проверявам а съм го коментирал
edit ... редактирах си страннотописане :)

Автор:  [ Чет Юни 23, 2005 2:15 pm ]
Заглавие: 

Колеги, никъде нямате проверка за препълване на хардуерния буфер на серийния порт на професора, а винаги трябва да го имате, защото не знаете колко "чисти" данни ще дойдат ( може и фронтовете да са калпави ). Един фрагмент, който съм използвал на почти всички ПИК16 с хардуерен сериен канал и никога не съм имал проблем с тях:
Код:

#INT_GLOBAL
InterruptHandler()      // Global interrupt vector for PIC16F87X
{
   GIE = 0;
   PushOntoStack();   // Store registers in 'Stack'
   if( RCIF )
      RxDHandler();
   PopFromStack();      // Restore registers from 'Stack'
}

void RxDHandler(void){
static char rcin, *ptr, rctmp, parity;

   rcin = RCREG;

   if( OERR )   {
      rctmp = RCREG;
      rctmp = RCREG;
      CREN = 0;   rctmp += 2; CREN = 1;
      goto RxDHandlerError;
   }

   if( FERR )   {
      CREN = 0;
      _C = 0; if( RX9D ) _C = 1;
      rctmp = RCREG;
      CREN = 1;
      goto RxDHandlerError;
   }

   if( ! RcvEnd && cInQueue < cMaxInQueue )   {
      ptr = (char*)&SnapFromLocal + cInQueue;
      switch( cInQueue )      {
         // S.N.A.P synchronization byte
         case 0: if( rcin == SNAP_SYNC )
                  goto RxDHandlerSaveInput;
               goto RxDHandlerError;

         // S.N.A.P header definition byte 2
         case 1: if( ( rcin & 0xFC ) == ( SNAP_DAB_1 | SNAP_SAB_1 | SNAP_ACK_NO_REQUEST  )  )
                  goto RxDHandlerSaveInput;
               goto RxDHandlerError;

         // S.N.A.P header definition byte 1
         case 2: if( ( rcin & 0xC0 ) == ( SNAP_COMMAND | SNAP_EDM_CRC16 ) )
               {
                  rctmp = rcin & 0x0F;
                  if( rctmp == SNAP_NDB_0 )
                  {
                     cMaxInQueue = 5+2;         // Accept 0 data bytes
                     goto RxDHandlerSaveInput;
                  }
                  if( rctmp == SNAP_NDB_USER )   // User specified
                  {
                     cMaxInQueue = 5+9+2;      // Accept 9 data bytes
                     goto RxDHandlerSaveInput;
                  }
               }
               goto RxDHandlerError;

         // S.N.A.P destination address byte
         case 3: if( rcin == myaddr )
                  goto RxDHandlerSaveInput;
               goto RxDHandlerError;

         // S.N.A.P source address byte
         case 4: if( rcin == lcaddr )
                  goto RxDHandlerSaveInput;
               goto RxDHandlerError;

         // S.N.A.P   DB0 - Neuron command code
         case 5: if( cMaxInQueue == sizeof(SNAP) )
                  goto RxDHandlerSaveInput;
               if( cMaxInQueue == 7 )
                  goto RxDHandlerSaveInput;
               goto RxDHandlerError;

         // S.N.A.P   DB1 - begin
         case 6: if( cMaxInQueue == sizeof(SNAP) )
               {
                  if( rcin >= LAMP_MIN_NODE_ADDR && rcin <= LAMP_MAX_NODE_ADDR )
                     goto RxDHandlerSaveInput;
               }
               if( cMaxInQueue == 7 )
               {
                  RcvEnd = 1;
                  RCIE = 0;
                  goto RxDHandlerSaveInput;
               }
               goto RxDHandlerError;

         // S.N.A.P DB2 - end
         case 7: if( rcin >= LAMP_MIN_NODE_ADDR && rcin <= LAMP_MAX_NODE_ADDR )
                  goto RxDHandlerSaveInput;
               goto RxDHandlerError;

         // S.N.A.P DB3 - response
         case 8: if( rcin != 0 )
                  goto RxDHandlerError;
               goto RxDHandlerSaveInput;

         // S.N.A.P DB4 - timetolive
         case 9:

         // S.N.A.P DB5 - data[0]
         case 10:

         // S.N.A.P DB6 - data[1]
         case 11:

         // S.N.A.P DB7 - data[2]
         case 12:

         // S.N.A.P DB8 - data[3]
         case 13:
               goto RxDHandlerSaveInput;

         // S.N.A.P CRC16H
         case 14:
               // CRC-16 ñå èç÷èñëÿâà â ãëàâíàòà ïðîãðàìà, ïîðàäè òîâà ÷å èçèñêâà
               // íàä 2 ms ïðîöåñîðíî âðåìå çà èç÷èñëåíèå !
               goto RxDHandlerSaveInput;

         // S.N.A.P CRC16L
         case 15: RcvEnd = 1;
                RCIE = 0;
                goto RxDHandlerSaveInput;

         default:
               goto RxDHandlerError;
      }
RxDHandlerSaveInput:
      *ptr = rcin;
      cInQueue++;
   }
   return;

RxDHandlerError:
   // Íóëèðàì âõîäíèÿ áóôåð
   cInQueue = cMaxInQueue = sizeof(SNAP); ptr = (char*)&SnapFromLocal;
   do {
      *ptr++ = 0;
   } while( --cInQueue );
}


А листинга не е сорса, пускайте какве е излезнало от компилатора като асемблерски инструкции !
printf() на CCS си има проблеми от едно време, например с float числа, бях някъде пуснал пример как да си правите собствена printf(). То проблема с нея не винаги се проявява, и аз като zax си мисля, че проблемите й са свързани с банките памет.[/code][/quote]

Автор:  Predator_MF [ Чет Юни 23, 2005 2:36 pm ]
Заглавие: 

Значи @ToHu, точно преди всяко излизане от прекъсването си пиша едно reset_usart_rx(). Идеята е при първото влизане в INT_RDA ако изтървеш да прочетеш няколко получени байта, след това се получи още един FIFO-то се препълва и вдига ERR флага....оттам нататък прекъсвания няма да получиш.
Код:
reset_usart_rx()
{#ASM
   bcf   RCSTA,CREN
   nop
   bsf   RCSTA,CREN
#ENDASM}
Много пъти съм имал точно такъв проблем и си го реших с тия три реда горе. Писах си един протокол, досега съм го качвал на всякви пикове с USART, само на 16F877A се е*аваше постоянно.

Автор:  ToHu [ Чет Юни 23, 2005 2:47 pm ]
Заглавие: 

Хм ... аз това го гледам с дебъгера, и като умира така няма препълване ... ама ще гопробвам сега с това нещо .... не съм сложил препълване щото комуникацията ми е на 9600, програмата която вътртя няма участъци в които да не мога да вляза в прекъсване за времето м-у два бита .... прекъсванията ми отнемат много малко врме, дори всицки накуп да дойтат пак не отиват колкото е м-у два бита.

Автор:  Predator_MF [ Чет Юни 23, 2005 2:49 pm ]
Заглавие: 

А след като излезеш от прекъсването някъде имаш ли Enable_Interrupts(INT_RDA) ? Пробвай да сложиш и това :)

Автор:  ToHu [ Чет Юни 23, 2005 3:01 pm ]
Заглавие: 

Абе това го пробвах с enable interrupt ама тои флага си е разресхен .. сега сложих това за препълването... и май тръгна .. има нещо гнило в тоиа 877А ....... а може и да не е само в него

:) .... досега сравнявах със старияфайл и не откривах никакви разлики ... да но стария файл е за 877 а новия е за 877А .... смених процесора по едно врмее .. бах мама му .. нищо таков ане пише в ератата, сега ще видя това за преход от 877 към 877А

Автор:  Predator_MF [ Чет Юни 23, 2005 3:03 pm ]
Заглавие: 

Да ти кажа тва за гнилото май не е само за 16F877...скоро портнах протокола си в 18-ка и имаше подобен проблем. След излизане от прекъсване стават ей такива гафове...

Автор:  ToHu [ Чет Юни 23, 2005 3:11 pm ]
Заглавие: 

Абе простотия .... мислех вчера да правя нещо подобно .. ама почнах да подавам данните през хипер терминал байт по байт, няма как да с епрепъли, и пак се осираше .. и реших че не е от това .. простотия вселенска. бах мама му ... колко контролерая съм пуснал с тая простотия ......

Автор:  Predator_MF [ Чет Юни 23, 2005 5:03 pm ]
Заглавие: 

Ако искаш ше ти дам моя, Copy >> Paste и заработва одма... Има
Preamble | ID | Data Length | Data | CheckSum. Готов е и направен за команди, Data[0] е командата, после съм го писал с Case от 0 до 255 команди може да имаш.

Автор:  ToHu [ Чет Юни 23, 2005 5:56 pm ]
Заглавие: 

Аз такъв имам, там ми е с препълване и всичко останало .. ама тоя е с хм ... формат е трудно акзано .... *V ми е командата която трябва да обработя ....и освен всичко друго аз връщах едно Er ако нещо не е наред което съвсем е сбозвало нещата ..... сега си мълча ако данните не са наред ... чакам да ме питат отново .... два символа са малко за смислена команда ... има вероятност от грешка .... увеличих и тайаута за получаване на пакета на 500 мс .. знам ли .. онова отсреща може да е свинило нещо .. преди ми беше 200 .....

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/