PIC interupt
Zuffa Jan
ZuffaJ na cgc.sk
Čtvrtek Červenec 24 16:35:01 CEST 2014
Zdravim,
piatok sa blizi tak by som rad nacrtol problem s ktorym uz par vecerov zapasim
a neviem ho vyriesit. Ide o PIC16F648 a UART v asynchronnom mode. Data zo serioveho portu sa citaju
v interupte a spracovavaju v hlavnej slucke
Vsetko funguje ako ma, pokial nezahltim UART vacsim poctom paketov (trebars
10 bez prestavky prejde, vacsi pocet uz nie. Velkost RxBuff je 16 bajtov a v interupte
je osetrene pretecenie.
Pakety su velke 4-5 bajtov velke zakoncene 0x0D
V hlavnej slucke sa dookola cita RxBuff pokial dojde k naplneniu (RxDone == 1)
Pre jednoduchost som hlavnu slucku minimalizoval takze vypada nejak takto
while (1)
{
BYTE bBuffer[RX_BUFF_SIZE];
UART_ RecvData (bBuffer);
__delay_ms(300);
CLRWDT() // nastaveny na 2.5 sekundy
}
Pokusmi som zistil, ze sa program zacykli v interupte, pravdepodobne kazdym hodinovym cyklom
sa opatovne vyvola interupt co nedovoluje hlavnej slucke pokracovat v spracovani.
Skratka program sa zasekne a WatchDog resetuje procesor. Ked dam CLRWDT() do interuptu
procesor sa nezresetuje ale hlavna slucka sa nevykonava.
Otazka je, ako sa dostat z tohto stavu? Detekovat v interupte ze sa nespracovavaju prijate
data je jednoduche, nic co som vyskusal ale nezabralo
Tu je rutina interuptu:
(Tx sa pouzije iba pri starte procesora aby som videl ze doslo k resetu)
void interrupt trx_int(void) {
// RECEIVE BUFFER
if ((RCIF == TRUE) && (RCIE == TRUE)) // PIR1 register
{
if (OERR == TRUE)
{ // overrun, reset UART
CREN = FALSE; // disable UART
CREN = TRUE; // re-enable UART
RxRecv = 0;
}
else
if (FERR == TRUE) // framing error (break?)
{
RxRecv = 0;
}
else
{
RxBuffer[RxRecv] = RCREG; //global variable
if(RxBuffer[RxRecv] == 0x0D)
{
RCIE = 0;
RxDone = 1;
}
RxRecv++;
if (RxRecv >= RX_BUFF_SIZE) // beyond buffer boundary wrap to begin
{
RxRecv = 0;
RCIE = 1;
RxDone = 0;
}
}
}
// TRANSMIT BUFFER UNTIL EMPTY
if ((TXIF == TRUE) && (TXIE == TRUE)) // PIR1 register
{
if(TxSent < TxXmit)
{
bX = TxBuffer[TxSent];
TxSent++;
if (TxSent >= TxXmit) //last byte sent, disable interrupt from TX
{
TXIE = 0;
TxXmit = 0;
TxSent = 0;
}
TXREG = bX;
}
}
}
BYTE UART_RecvData(BYTE *bData)
{
BYTE bCnt;
BYTE bX;
if(RxDone == 1)
{
for(bCnt = 0; bCnt < RxRecv; bCnt++)
{
bData[bCnt] = RxBuffer[bCnt];
}
bX = RxRecv;
RxRecv = 0;
RxDone = 0;
RCIE = 1;
return bX;
}
else
{
return 0;
}
}
Další informace o konferenci Hw-list