|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Jun 2006
Messaggi: 13
|
interrupt sh7047
Sto testando gli interrupt su una scheda con un processore SH 7047.
Il programma che ho realizzato accende l’AD converter e finita la conversione dovrebbe far avvenire un interrupt, che attiva una funzione che mediante un ciclo infinito accende e spegne un led della scheda che è legato a un pin della porta e. Il main è questo: #include "iodefine.h" int i; void main(void) { INTC.IPRG.BIT._AD01=0x0A; /* da la priorità 10 a l’interrupt dell’ AD*/ PFC.PEIORL.WORD|=0xFFFF; /*tutta la porta e output*/ PFC.PECRL1.WORD&=0x0000; /*tutta la porta e general i/o*/ PFC.PECRL2.WORD&=0x0000; /*tutta la porta e general i/o*/ PE.DRL.WORD=0x0000; /*data register della PE*/ MST.CR2.BIT._AD1=0; /*accende l’AD, inizialmente è in stand by*/ AD1.ADCR.BIT.ADST=0; /*AD start =0*/ AD1.ADCSR.BIT.ADF=0; /*flag a 0*/ AD1.ADCSR.BIT.ADIE=1; /*abilita l’ interrupt*/ AD1.ADCSR.BIT.ADM=00; /*1 canale*/ AD1.ADCR.BIT.CKS=0; /*velocita di scansione max*/ AD1.ADCSR.BIT.CH=0x1; /* II canale*/ AD1.ADCR.BIT.ADCS=0; / *modo single scan*/ AD1.ADCR.BIT.ADST=1; /*parte l’AD*/ } Gli altri file che trovo sono Inthandler .h: void INT_Manual_Reset_PC(void) __attribute__ ((interrupt_handler)); void INT_Manual_Reset_SP(void) __attribute__ ((interrupt_handler)); void INT_Illegal_code(void) __attribute__ ((interrupt_handler)); void INT_Illegal_slot(void) __attribute__ ((interrupt_handler)); void INT_CPU_Address(void) __attribute__ ((interrupt_handler)); void INT_DTC_Address(void) __attribute__ ((interrupt_handler)); void INT_NMI(void) __attribute__ ((interrupt_handler)); … void INT_MTU4_TCIV4(void) __attribute__ ((interrupt_handler)); void INT_ADI0(void) __attribute__ ((interrupt_handler)); void INT_ADI1(void) __attribute__ ((interrupt_handler)); void INT_DTC_SWDTEND(void) __attribute__ ((interrupt_handler)); … Penso che definisca come interrupt le varie funzioni definite. Lo lascio così; Inthandler.c: #include "inthandler.h" #include "iodefine.h" /*lo ho aggiunto io per far riconoscere le strutture in ADI1*/ void INT_Manual_Reset_PC(void) { /*add your code here*/ } void INT_Manual_Reset_SP(void) { /*add your code here*/ } void INT_Illegal_code(void) { /*add your code here*/ } … void INT_ADI1(void) /*qui sono andato a scrivere il codice della funzione attivata dall’ interrupt*/ { int i; while (1) { for (i=0;i<30000;i++) PE.DRL.WORD|=0x4000; /*queste maschere portano a 1 e 0 il pin 14 che corrisponde al led*/ for (i=30000; i<60000; i++) PE.DRL.WORD&=0xBFFF; i=0; } } …; vects: #include "inthandler.h" extern void start (void); /* Startup code (in start.s) */ extern void stack (void); /* stack from linker script */ /**---------------------------------- ** Typedef for the function pointer **-----------------------------------*/ typedef void (*fp) (void); #define VECT_SECT __attribute__ ((section (".vects"))) const fp HardwareVectors[] VECT_SECT = { start, /* 0 Power-on reset, Program counter (PC) */ INT_Manual_Reset_PC, INT_Manual_Reset_SP, INT_Illegal_code, (fp)0, /*Reserved 5*/ INT_Illegal_slot, (fp)0, /*Reserved 7*/ (fp)0, /*Reserved 8*/ … INT_ADI0, INT_ADI1, … Dovrebbe realizzare la vector table. Non lo tocco; iodefine.h: che associa i registri a strutture con nomi più mnemonici; start.asm: ! Start.asm .list .section .text .global _start ! global Start routine .extern _hw_initialise ! external Sub-routine to initialise Hardware .extern _main .extern _data .extern _mdata .extern _edata .extern _ebss .extern _bss .extern _stack .extern _vects #if DEBUG .extern _exit #endif _start: ! initialise the SP for non-vectored code mov.l stack,r15 ! Call hw_initialise mov.l hw_initialise,r1 jsr @r1 nop !load data section from ROM to RAM only if ROMSTART is defined #if ROMSTART ! initialise sections mov.l edata,r1 ! edata in r1 mov.l mdata,r2 ! mdata in r2 mov.l data,r0 ! data in r0 cmp/eq r0,r1 bt start_1 nop start_l: mov.b @r2,r3 !get from src mov.b r3,@r0 !place in dest add #1,r2 !inc src add #1,r0 !inc dest cmp/eq r0,r1 !dest == edata? bf start_l nop start_1: #endif // ROMSTART ! zero out bss mov.l ebss,r1 mov.l bss,r0 cmp/eq r0,r1 bt start_3 sub r2,r2 start_2: mov.b r2,@r0 add #1,r0 cmp/eq r0,r1 bf start_2 nop start_3: #ifdef CPPAPP !Initialize global constructor mov.l _InitCtors,r1 jsr @r1 nop #endif mov.l main,r1 jsr @r1 nop ! call to exit #if DEBUG mov.l _exit_k,r1 jsr @r1 nop #endif #if RELEASE exit: bra exit nop #endif .ALIGN 4 hw_initialise: .long _hw_initialise stack: .long _stack main: .long _main #ifdef CPPAPP _InitCtors: .long ___main #endif data: .long _data mdata: .long _mdata edata: .long _edata bss: .long _bss ebss: .long _ebss #if DEBUG _exit_k: .long _exit #endif .end Che non so cosa fa(?); hwinit: #include "iodefine.h" void hw_initialise (void) { // TODO: add hardware initialisation code here } Qui penso che dovrei scrivere le inizializzazioni hardware che invece ho messo sul main, ma facendolo non ho avuto comunque miglioramenti. Compilato e monitorato col debbugger mi accade che: 1) se metto il PC sull’ indirizzo del main (come ho fatto per testare gli altri programmi senza interrupt finora) il programma mi esegue tutto il main, ma finito salta all’indirizzo 00000000 e si blocca senza eseguire l’interrupt. L’AD si accende e finisce la conversione perché la sua flag visualizzando i registri vedo che la flag di fine conversione va a 1. (dimenticavo: ho scaricato il programma sulla memoria interna del processore: FFFFD000, all’indirizzo 00000000 che è una memoria flash c’è il monitor per il debugger). 2) se vado dove si trova inizialmente il PC lo trovo all’ indirizzo corrispondente di _start. Eseguendo passo passo o mandandolo in esecuzione mi si blocca dopo hwinit: MOV.L R14,@-R15 void hw_initialise (void) { MOV R15,R14 .DATA.W H'FFFF } si blocca qui col messaggio break=illegal general istruction Sapete dove sbaglio? |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:04.



















