[ATmega32A][Assembler] Problem with input register.

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi! I want to learn Assembler, so I bought ATmega32A kit (for education).

I wrote a program, which turn on LED when you press the microswitch (as far as RESET button pressed).
And I have a problem, LED turn automatically (I don't press the microswitch) when I turn on DC. Not always, but usually (randomly).

Code:

.org 0
 ldi r16,0xFF
 out DDRA,r16 //PORTA as output
 out PORTA,r16 //set 0xFF to PORTA
 
 ldi r16,0x00
 out DDRB,r16 //PORTB as input
 ldi r16,0xFF
 out PORTB,r16 //pull-up resistor - ON
 
 
 START:
 sbis PINB,0 //IF "1" on PINB,0 skip next instruction
 cbi PORTA,0 //set "0" to PORTA,0 - LED ON
 
 rjmp START
 .exit 

What can I do?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You turn the LED on but never turn it back off. The false "0" at PINB,0 can easily be sensed shortly after a reset because the internal pullup resistor has a large enough value (~50k) and can't charge the pin stray capacitance in a few CPU cycles after a reset.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Before turn off, PINB,0 is 1 and LED is OFF.
1. I turned off DC.
2. I waited 2 minutes.
3. I turned on DC.
LED is ON!

Why?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 out PORTB,r16 //pull-up resistor - ON
 
 
 START:
 sbis PINB,0 //IF "1" on PINB,0 skip next instruction 

You have too little time between enabling the pull-ups and reading the input the first time. Actually this time is even zero in the moment, because the content of PINB is the input sampled one clock before. Therefore the first loop reacts on the open input (not the pulled up one). You have to insert at least one NOP (perhaps more, depending on the stray capacitance).

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
You have to insert at least one NOP

I added 5 NOP's after:

 out PORTB,r16 //pull-up resistor - ON 

Is better, but 1/10~ resets LED is ON automatically...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

5 NOPs is too few. Add some substantial delay instead. The actual 0->1 pin capacitance precharge time can be estimated as 2.2*R*C = ~2.2 * 50 pf * 50 kOhm = 5500 nS, or ~90 NOPs aasuming a breadboarded MCU running at 16 MHz.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I always put a 100ms to 200ms delay at the start of the code to allow for the AVR and any surrounding electronics to stabilise..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all.
Problem solved :)

I added delay loop (1s) using AVR delay loop generator - http://www.home.unix-ag.org/tjabo/avr/AVRdelayloop.html.

org 0 
 ldi r16,0xFF 
 out DDRA,r16 //PORTA as output 
 out PORTA,r16 //set 0xFF to PORTA 
  
 ldi r16,0x00 
 out DDRB,r16 //PORTB as input 
 ldi r16,0xFF 
 out PORTB,r16 //pull-up resistor - ON

 ; ============================= 
;    delay loop generator 
;     16000000 cycles:
; ----------------------------- 
; delaying 15999993 cycles:
          ldi  R17, $53
WGLOOP0:  ldi  R18, $FB
WGLOOP1:  ldi  R19, $FF
WGLOOP2:  dec  R19
          brne WGLOOP2
          dec  R18
          brne WGLOOP1
          dec  R17
          brne WGLOOP0
; ----------------------------- 
; delaying 6 cycles:
          ldi  R17, $02
WGLOOP3:  dec  R17
          brne WGLOOP3
; ----------------------------- 
; delaying 1 cycle:
          nop
; ============================= 
  
  
 START: 
 sbis PINB,0 //IF "1" on PINB,0 skip next instruction 
 cbi PORTA,0 //set "0" to PORTA,0 - LED ON 
  
 rjmp START 
 .exit