Vai al contenuto
PLC Forum


Interrupt Sh7047


sandro76

Messaggi consigliati

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 [at]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 [at]r2,r3 !get from src

mov.b r3,[at]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,[at]r0

add #1,r0

cmp/eq r0,r1

bf start_2

nop

start_3:

#ifdef CPPAPP

!Initialize global constructor

mov.l _InitCtors,r1

jsr [at]r1

nop

#endif

mov.l main,r1

jsr [at]r1

nop

! call to exit

#if DEBUG

mov.l _exit_k,r1

jsr [at]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,[at]-R15 void hw_initialise (void) {

MOV R15,R14

.DATA.W H'FFFF } si blocca qui col messaggio break=illegal general istruction

Sapete dove sbaglio?

Link al commento
Condividi su altri siti


Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...