AVR Assembler - HELP

Salve a tutti. Ho un problema con un programma in assembler che sto scriverndo per un AT90S2313. In pratica realizza un controllo PWM il cui valore è settato da tre tastini: prog, più e meno. Per programmare bisogna premere contemporaneamente prog e più o meno a seconda.

Ho settato il Timer1 come PWM a 9 bit e senza prescaler (per arrivare vicino alla frequenza di 4 kHz che mi serve). In teoria vorrei che tutte le volte che riaccendo la scheda, il valore del duty cycle fosse quello impostato. Voi direte: te lo scrivi in EEPROM e sei a posto, basta leggerlo ad ogni start-up. Il problema sta qua! :-( Settando il Timer1 come PWM a 8 bit, leggo, scrivo e faccio quello che voglio col valore del OCR1AL, che è il registro che contiene il valore del duty cicle (più o meno... è il registro di compare-match). Quando però passo ai 9 bit, non riesco a fare "resuscitare" i valori allo start-up. Allego qua sotto il codice. Un grande grazie a chi può darmi una mano! Ciao Pelo

.INCLUDE "2313DEF.INC"

;*******DEF************************************************************ ;.DEF =R1 ;.DEF =R2 ;.DEF =R3 ;.DEF =R4 ;.DEF =R5 ;.DEF =R6 ;.DEF =R7 ;.DEF =R8 ;.DEF =R9 ;.DEF =R10 ;.DEF =R11 ;.DEF =R12 ;.DEF =R13 ;.DEF =R14 ;.DEF =R15 .DEF BUFFER =R16 .DEF TEMP =R17 ;.DEF =R18 .DEF TEMP2 =R19 .DEF FLAG =R20 .DEF KEYA =R21 .DEF KEYB =R22 ;.DEF =R23 .DEF BASSO =R24 ; Inizio registri PAIR .DEF ALTO =R25 ;.XL =R26 ; Da non toccare ;.XH =R27 ; " " ;.YL =R28 ; " " ;.YH =R29 ; " " ;.ZL =R30 ; " " ;.ZH =R31 ; " "

.equ EEPROMADDRESS =0x20 .equ PIU =5 .equ MENO =4 .equ PROG =3 .equ STEP =1 ;**************************INTERRUPT VECTORS *********************

.ORG 0x000

rjmp MAIN ;RESET reti ;EXT_INT0 reti ;EXT_INT1 reti ;TIM1_CAPT reti ;TIM1_COMP reti ;TIM1_OVF reti ;TIM0_OVF reti ;SPI_STC reti ;UART_RXC reti ;UART_DRE reti ;UART_TXC reti ;ADC reti ;EE_READY reti ;ANA_COMP

.org 0x010 ;************************************* STACK POINTER INIT

*****************************************

MAIN: ldi BUFFER,low(RAMEND) out SPL,BUFFER

;*********************************** GENERAL INTERRUPT MASK

**************************************** ldi BUFFER,0b10000000 ; Enable the External interrupt 1 ;ldi BUFFER,0b01000000 ; Enable the External interrupt 0 ;ldi BUFFER,0b10000000 ; Enable the External interrupt 0 and 1 out GIMSK, BUFFER

;***************************************** MCUCR INIT

********************************************

;ldi BUFFER,0b00xxxxxx ; Reserved bits ;ldi BUFFER,0bxx1xxxxx ; Sleep mode enable ;ldi BUFFER,0bxxx1xxxx ; Sleep mode select: 0->Idle mode 1->Power down ;ldi BUFFER,0bxxxx1xxx ; ISC11 |->Set external interrupt mode ;ldi BUFFER,0bxxxxx1xx ; ISC10 | See Manual p.30 for details ;ldi BUFFER,0bxxxxxx1x ; ISC01 | ;ldi BUFFER,0bxxxxxxx1 ; ISC00 | ldi BUFFER,0b00001000 out MCUCR,BUFFER

;*************************************** EEPROM INIT

**********************************************

ldi BUFFER,0b00000000 ;Reset the EEPROM address register out EEAR,BUFFER ;Init the EEPROM control register ;ldi BUFFER,0b0000xxxx ;0 are reserved bits ;ldi BUFFER,0bxxxx1xxx ;Ready interrupt enable ;ldi BUFFER,0bxxxxx1xx ;Master write enable ;ldi BUFFER,0bxxxxxx1x ;Write enable ;ldi BUFFER,0bxxxxxxx1 ;Read enable ldi BUFFER,0b00000000 out EECR,BUFFER

;*********************************** TIMER/COUNTER 1 INIT******************************************

ldi BUFFER,0b10000010 ; out TCCR1A,BUFFER ldi BUFFER,0b00000001 ; out TCCR1B,BUFFER

;**************************************** PORT INIT

*********************************************** ;DDR PORT I/O Pullup Comment ;0 0 In No Tristate ;0 1 In Yes Input with pull-up ;1 0 Out No Push-Pull Zero out ;1 1 Out No Push-Pull One out

;**************************************** INIT PORT B

*********************************************

; As OUTPUT Zero OUTPUT ldi BUFFER,0b11111111 out DDRB,BUFFER ldi BUFFER,0b00000000 out PORTB,BUFFER

;**************************************** INIT PORT D

*********************************************

; As INPUT with PULLUP ldi BUFFER,0b00000000 out DDRD,BUFFER ldi BUFFER,0b11111111 out PORTD,BUFFER

;***************************************************************************

************************ ;******************************************** MAIN ************************************************* ;*************************************************************************** ************************

; Reads the PWM from the EEPROM Memory ldi BUFFER,EEPROMADDRESS ; Read the first byte out EEAR,BUFFER sbi EECR,EERE read1: sbic EECR,EERE rjmp read1 in BASSO,EEDR

;ldi BUFFER,EEPROMADDRESS ; Read the second byte inc BUFFER out EEAR,BUFFER sbi EECR,EERE read2: sbic EECR,EERE rjmp read2 in ALTO,EEDR out OCR1AH,ALTO out OCR1AL,BASSO

Lupo: sbrc FLAG,0 rjmp xxx in TEMP,PIND sbrc TEMP,PROG rjmp Lupo sbr FLAG,1

Program:

in KEYB,PIND mov TEMP,KEYB in BASSO,OCR1AL in ALTO, OCR1AH

ldi BUFFER,STEP sbrs TEMP,PIU

adiw ALTO:BASSO,STEP sbrs TEMP,MENO sbiw ALTO:BASSO,STEP

out OCR1AH,ALTO out OCR1AL,BASSO in ALTO,OCR1AH in BASSO,OCR1AL

wait_EEWE2: sbic EECR,EEWE ; Waits for write ready rjmp wait_EEWE2 ldi TEMP,EEPROMADDRESS ; Load the high address of position in memory out EEAR,TEMP out EEDR,ALTO sbi EECR,EEMWE ; Set the EEPROM Master Write Enable bit sbi EECR,EEWE ; Set the EEPROM Write Enable bit

wait_EEWE3: sbic EECR,EEWE ; Waits for write ready rjmp wait_EEWE3 ;ldi TEMP,EEPROMADDRESS ; Load the low address of position in memory inc TEMP out EEAR,TEMP out EEDR,BASSO sbi EECR,EEMWE ; Set the EEPROM Master Write Enable bit sbi EECR,EEWE ; Set the EEPROM Write Enable bit

wait_EEWE4: sbic EECR,EEWE ; Waits for write ready rjmp wait_EEWE4

xxx: in KEYA,PIND cp KEYA,KEYB breq Lupo cbr FLAG,1 rjmp Lupo

Reply to
Pelo
Loading thread data ...

Non ho tempo adesso di analizzare il tuo listato, pero' ricordo che il primo indirizzo della EEPROM a volte tende a cancellarsi (ho incontrato il problema proprio con un AT90S2313), per cui prova a cambiare la locazione di E2P.

Un altra precauzione e' mettere sempre a zero,cioe' alla prima locazione (che non viene usata ) i puntatori EEAR dopo un operazione in EEPROM. Pare che durante il reset o il power down a volte possano sporcare la memoria puntata, soprattutto se i fronti di discesa della VCC non sono molto ripidi.

Se dopo queste modifiche hai ancora problemi faccelo sapere,

ciao Stefano

Reply to
SB

"SB" ha scritto nel messaggio news: snipped-for-privacy@4ax.com...

Grazie mille della risposta! Allora qualcuno usa gli AVR! :-)

Già fatto! parto da 0x20 (riga .equ EEPROMADDRESS =0x20)

Perchè parli di puntatori? L'EEAR non è un registro a 8 bit? Cioè una cosa del genere nel caso di lettura? (metacodice)

ldi BUFFER,EEPROMADDRESS out EEAR,BUFFER sbi EECR,EERE wait: sbic EECR,EERE rjmp wait in BUFFER,EEDR out OCR1AH,BUFFER ldi BUFFER,0 out EEAR,BUFFER

Io spegnevo proprio la scheda... Grazie mille Pelo

Reply to
Pelo

Mi ci trovo bene

Benissimo

Proprio questo: ldi BUFFER,0 out EEAR,BUFFER

Beh, resettando con il pin RES\ non dovrebbe farlo...

Hai provato? Funziona adesso? Perchè per il resto ho dato un occhiata veloce al listato e mi sembra che possa andare.

ciao Stefano

Reply to
SB

"SB" ha scritto nel messaggio news: snipped-for-privacy@4ax.com...

Funziona tutto! Però non capisco perche si debba mettere e zero il registro EEAR... quando lo uso dopo lo ricarico di nuovo!!! Mah...

Grazie dieci mila! Pelo

Reply to
Pelo

Sono contento

Basta che il registro EEAR sia a zero al momento dello spegnimento, quindi se fai una routine di Power Fail con un interrupt per quella funzione lo puoi mettere a zero cosi'.

Se invece vuoi eliminare il problema complicando l'hardware puoi mettere un MC34064 che controlli il RES\

formatting link

o usare un chip ATMega con il "Brown Out Detector" che essenzialmente fa la stessa cosa.

Comunque la soluzione software e' sempre quella che costa meno ;-)

ciao Stefano

Reply to
SB

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.