¿Media tensión en el pin de salida bajo carga?

4

Estoy trabajando con un ATTINY26 (L) aprendiendo sobre las interrupciones, y descubrí un problema.

Estoy obteniendo un voltaje de salida diferente en PORTA (la mitad) que en PORTB . Para simplificar las cosas, hice un programa para encender un solo LED en un pin determinado. He probado hasta ahora en varios pines de ambos puertos.

EnPORTA,simidopinatierrasincarga,obtengo5V.SiconectoelLED(3\$V_f\$)yunaresistenciade100Ω,elvoltajecaea2.5V,yelLEDestáoscuro(2.5VatravésdelLEDy6mVatravésdelaresistencia).

EnPORTB,elvoltajepermanece5V(3VatravésdelLEDy2Vatravésdelaresistencia).

Código:

intmain(){DDRA=0xFF;DDRB=0xFF;while(1){PORTA=(1<<PA6);//Halfvoltage?PORTB=(1<<PB6);//OKmilli_delay(100);PORTA=(0<<PA6);PORTB=(0<<PB6);milli_delay(100);}}voidmilli_delay(intd){for(inti=0;i<d;i++)_delay_ms(1);}

¿Tengounmicrocontroladordañadoohepasadoporaltoalgo?

Actualizar:

Cambiéelmicrocontroladorporunoidénticoyobtuveelmismoresultado.Creoqueespocoprobablequedosesténdañadosdelamismamanera.

Actualización2:

AlgunoshansolicitadoelcódigoHEXcompilado:(Enlaceahoraeliminado)

Actualización3:

@JippietuvolaamabilidaddeverificarelcódigoELF(descompilado)yviouncambioextrañodePORTAdenuevoenlaentrada,inmediatamentedespuésdeconfigurarloparalasalida.¿Quéda?

Elcódigoquepeguéarribanoestácompleto.Hayunapequeñalíneadecódigoadicionalquedeberíahabersecomentadoopegadoenestapregunta:

DDRA=(0<<PA7);//inputonPA7

ElPA7estabadestinadoaleeruninterruptorcomopartedemipruebadeinterrupcióndecambiodepin.Penséquelalíneahabíasidocomentada,peronofueasí.Y,sitefijasbien,descubrirásunproblema.

Deberíaser:

DDRA|=(0<<PA7);

ElintentodeestablecerelpinPA7en0soloparalaentradadebehacerseconunoperadorOR-EQUALS(|=),nosoloIGUALDAD(=).Comoresultado,todoelPORTAseestableciódenuevoenlaentrada.

¿Lalecciónaquí?Unpersonajedesinglearruinómásdeundíaenterodeaprendizajeyexperimentación.Unasolalíneadecódigoomitidaenlapregunta(onocomentadaadecuadamenteparalaprueba)causódoloresdecabeza.

Siempresoymipeorenemigocuandosetratadesolucionarproblemas.Nofueunchipdefectuoso,unerrordecompilaciónoalgunaconfiguraciónaccidental.Totalerrordenovatoalnoafondorevisarmipropiocódigo.

Algunasfotos:

    
pregunta JYelton

1 respuesta

4

No es una respuesta real, pero hay demasiada información para incluir en los comentarios:

Eché un vistazo a tu código desensamblado y esta parte es extraña:

  18:   11 24           eor r1, r1          ; r1 = 0

...

0000005e <main>:
  5e:   8f ef           ldi r24, 0xFF   ; 255
  60:   8a bb           out DDRA, r24   ; DDRA=0xff (output)
  62:   87 bb           out DDRB, r24   ; DDRB=0xff (output)
  64:   1a ba           out DDRA, r1    ; DDRA=0x00 (input)

Definitivamente algo extraño está sucediendo. DDRA se establece en salida y, poco después, se establece en entrada. Esto explica el brillo de 2V5 de sus LED, está viendo el brillo de los LED por la corriente a través de las resistencias internas. Esto explica lo que ve, pero no puedo explicar por qué esto está sucediendo.

Compilé el código en mi propia PC y aunque no puedo probarlo en un ATtiny26, me parece bien. Así que aquí están las versiones de herramientas que utilizo:

  • avr-gcc --version → avr-gcc (GCC) 4.7.0
  • avr-objcopy --version → Objcopy GNU (GNU Binutils) 2.20.1.20100303
  • avr-objdump --version → GNU objdump (GNU Binutils) 2.20.1.20100303

Estos son los comandos que uso para generar los desmontables:

avr-gcc $(cflags) -mmcu=$(avrType) -c -o $(src).o $(src).cpp
avr-gcc $(cflags) -mmcu=$(avrType) -o $(src).elf $(src).o
avr-objdump -C -d $(src).elf

Y a flash:

avr-objcopy -j .text -j .data -O ihex $(src).elf $(src).hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U flash:w:$(src).hex

Observe que $(..) son variables, en mi caso de prueba:

baud=19200
src=main
avrType=attiny26
avrFreq=1000000
programmerDev=/dev/ttyUSB003
programmerType=stk500v1
cflags=-g -DF_CPU=$(avrFreq) -Wall -Os

El código resultante tiene el siguiente aspecto (sniplet):

00000044 <main>:
  44:   8f ef           ldi     r24, 0xFF       ; 255
  46:   8a bb           out     DDRA, r24       ; 26
  48:   87 bb           out     DDRB, r24       ; 23
  4a:   c0 e4           ldi     r28, 0x40       ; 64
  4c:   cb bb           out     PORTA, r28      ; 27
  4e:   c8 bb           out     PORTB, r28      ; 24
  50:   84 e6           ldi     r24, 0x64       ; 100
  52:   90 e0           ldi     r25, 0x00       ; 0
  54:   e8 df           rcall   .-48            ; 0x26 <milli_delay(int)>
  56:   1b ba           out     PORTA, r1       ; 27
  58:   18 ba           out     PORTB, r1       ; 24
  5a:   84 e6           ldi     r24, 0x64       ; 100
  5c:   90 e0           ldi     r25, 0x00       ; 0
  5e:   e3 df           rcall   .-58            ; 0x26 <milli_delay(int)>
  60:   f5 cf           rjmp    .-22            ; 0x4c <main+0x8>

Y a diferencia de su código donde se escribe DDRA dos veces (una vez 0x00 y una vez 0xff), aquí solo se escribe una vez.

    
respondido por el jippie

Lea otras preguntas en las etiquetas