Stránka 1 z 1

PIC16F648A - preruseni pri seriove komunikaci

Napsal: 20 kvě 2012, 22:50
od mbrazdil
Zdravim Vas,

pokousim se rozchodit seriovou komunikaci mezi dvema MCU PIC16F648A. K programovani pouzivam Hi-Tech C a MPLAB. V podstate jsem se dostal do faze, kdy jsem si v datasheetu nasel informaci jak nastavit synchronni master TX mod. Zkusil jsem to podle navodu na strane 84, ale bez uspechu. Tak jsem zacal od zacatku. Kdyz chci vyvolat jednoduche preruseni tak staci mit:

Kód: Vybrat vše

void main(void) {
 GIE = 1;
 T0IE = 1;
 T0IF = 1;
}



Toto je jasne, ale kdyz udelam toto preruseni:

Kód: Vybrat vše

void main(void) {
 GIE = 1;
 TXIE = 1;
 TXIF = 1;
}



Tak se preruseni nevyvola. Nevite cim to muze byt?

Napsal: 21 kvě 2012, 06:23
od Chenzee
Ahoj, podívej se na stranu 20 a 21 v DS (tabulka "special registers summary" a koukni se, kde se nachází povolení a flag přerušení časovače a kde přerušení od ser. linky. Pak si projdi příslušné pasáže v DS.

Napsal: 21 kvě 2012, 07:42
od frpr666

Kód: Vybrat vše

PEIE=1; // enable peripherals interrupt

Napsal: 21 kvě 2012, 09:28
od mbrazdil
Ahoj, tak jsem se do toho dival, ale nejak nechapu proc by to takto nemelo fungovat :( Proste nastavim povoleni a flag a melo by to fungovat. Zkousel jsem i nastavit PEIE, ale je to stejne. Navic jsem se dival do DS na ten USARTu jeste jednou a tam nic napsaneho nebylo o nastavovani PEIE.

Kód: Vybrat vše

void main(void) { 
 GIE = 1;
 PEIE = 1;
 TXIE = 1;
 TXIF = 1;
}



Toto proste preruseni nevyvola :(

Napsal: 21 kvě 2012, 09:49
od mikollar
to PEIE je spominane vsebocene pri popise preruseni v kat. liste.

Mas spravne nastaveny seriovy port?( registre)

EDIT: spravne nastavenie overis tak ze budes v slucke testovat FLAG prerusenia, on sa nastavuje aj ked mas zakazane prerusenia, samorejme nezabudaj nulovat

Napsal: 21 kvě 2012, 11:51
od Chenzee
... a ty nastavuješ ten flag ručně nebo čekáš, až jej nastaví uC?
-------------------------------------------------
Jinak tedy:
1) musí být povolené globální přerušení
2) musí být povolené přerušení periferií
3) musí být povolené přerušení ser. linky
4) flag ser. linky musí být 0

Pak při změně flagu 0 --> 1 musí být vyvoláno přerušení (skok na 0x4).
Alespoň mě to tedy zatím vždy takto fungovalo. To, jestli musí dojít k přečtení nějakých dat, to nevím ale bylo by to napsané v DS (momentálně nemám čas to číst :-(

Napsal: 21 kvě 2012, 12:06
od mikollar
Este sa moze stat, ak mas zarusenu komunikaciu ze sa ti nastavia chybove bity a pokial ich neznulujes tak ti dalsi prijem nepojde, ale aspon raz by ti to preslo.

Postup pre povolenie preruseni je presne ako pise Chenzee.

Napsal: 21 kvě 2012, 13:50
od mbrazdil
Asi si uplne nerozumime. Uplne na zacatku jsem daval 2 priklady jednoducheho kodu, kde rucne nastavuji flagy preruseni, abych jej vyvolal. V prvnim pripade to se tyka preteceni casovace mi to funguje, ale pokud to dam pro seriovy synchronni prenos tak ne. Nedalo mi to a zkusil jsem zapsat nejaka data do EEPROMky, mel jsem nasledujici kod:

Kód: Vybrat vše

// PIC16F648A

#include <htc.h>

#define _XTAL_FREQ 4000000

// Fuse bity
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF);

// obsluha preruseni
void interrupt gi() {
   GIE = 0;

   if (EEIF) {
      EEIF = 0;
   }

   GIE = 1;
}

// Hlavni program
void main() {

   GIE = 1;
   PEIE = 1;
   EEIE = 1;
   EEADR = 0;
   EEDATA = 0b11110000;
   WREN = 1;
   WR = 1;

   
   while (1) {
   }

}



Tento jednoduchy kod by mel fungovat a mel by zapsat do EEPROMky na adrese 0x01 hodnotu 0XF0. Po kompletnim zapsani by se melo vyvolat peruseni, ktere se ale opet nevyvola. Rekl bych, ze to to bude mit stejnou pricinu jako v pripade te seriove linky. Jsem z toho uz nejaky zmateny, ale opravdu uz nevim cim by to mohlo byt. Testoval jsem tento kod jak v realu a vypisoval hlasky na display, tak i v SIMu a nic. Ani data se do EEPROMky nezapisi. Uz pomaly premyslim, zda neni chyba nekde ve fuzi bitech, ale ty s tim primo nesouvisi, aspon podle me.

Napsal: 21 kvě 2012, 14:35
od frpr666
U PIC se každá periferie chová specificky. Nlp. když se podíváš přímo na hotové příklady např. na [url]piclist.com[/url] a do datasheetu a pak odzkoušet v MPLAB SIM. Někde je třeba v int. handleru mazat flag explicitně, jindy se maže sám implicitně. Ve tvém posledním příkladu není potřeba v int. handleru mazat a nastavovat GIE (nested-interrupt u téhle PIC myslím není).
Sériová komunikace se dá dobře v MPLAB SIM simulovat. Podívej se do helpu k MPLAB SIM.
edit1: při zápisu do EEPROM se dává magická sekvence 0x55, 0xAA do EECON2. Kdo zná Atmel, ten se diví :D

Napsal: 21 kvě 2012, 17:32
od mbrazdil
Tak s tou EEPROMkou je to vzresene a uy to faka, jen mi porad nejake nejede ten seriovz prenos.
V DS na strane 84 je pro zprovozneni synchronniho master modu:

1. TRISB<1> and TRISB<2> should both be set to ‘1’ to configure the RB1/RX/DT and RB2/TX/CK pins as inputs. Output drive, when required, is controlled by the peripheral circuitry.
2. Initialize the SPBRG register for the appropriate baud rate (Section 12.1 “USART Baud Rate Generator (BRG)”).
3. Enable the synchronous master serial port by setting bits SYNC, SPEN and CSRC.
4. If interrupts are desired, then set enable bit TXIE.
5. If 9-bit transmission is desired, then set bit TX9.
6. Enable the transmission by setting bit TXEN.
7. If 9-bit transmission is selected, the ninth bit should be loaded in bit TX9D.
8. Start each transmission by loading data to the TXREG register.



Takze kod by mel vypadat asi takto:

Kód: Vybrat vše

void  main() {
 GIE = 1;
 PEIE = 1;

 TRISB1 = 1; // 1. bod
 TRISB2 = 1; // 1. bod
 SPBRG = 103; // 2. bod
 SYNC = 1; // 3. bod
 SPEN = 1; // 3. bod
 CSRC = 1; // 3 bod
 TXIE = 1; // 4. bod
 // 5. bod preskakuji
 TXEN = 1; // 6. bod
 // 7. bod preskakuji
 TXREG = 255; // 8. bod
}



Je to spravne?