Problem with holding an output state

General discussion on mikroBasic PRO for AVR.
Post Reply
Author
Message
robert_d1968
Posts: 145
Joined: 14 Nov 2012 00:30
Location: China
Contact:

Problem with holding an output state

#1 Post by robert_d1968 » 29 Nov 2012 04:51

Hello there,

I wrote a nice program that works in the IDE. but it would not work correctly on the AVR. I've traced the problem down to the outputs.

So I made a very basic program to test four outputs on the avr. This works in the debugger, I set all the bits in the watch window, set break points on all the outputs (so I could step through them) and then ran it. Now If I change PIND.B2 from 0 to 1 and back to zero again, all the outputs change their states as they should, no problem at all.

I then load the program into the AVR, this is where the trouble starts. If I press the button that controls PIND.B2 I can see the outputs trying to change states. They go from zero to about 3.47 vdc. 3.47 vdc? how is that? So I put my scope on one of the output pins, and sure enough it's being driven high then low again. Just like it was being pulse width modulated.

I checked PIND.B2 with the scope and it's nice and smooth from 0 to 4.96 Vdc on the input.

Why will the output not turn fully on? And why are the output pins being Pulse width modulated?

I certainly can not use this IDE if it can't hold an output pin in the correct state.

Below is the test program that I'm using to test the four output pins with. This is set to use the ATMega88PA AVR. with the internal oscillator at 8 MHZ and no CKDIV8 fuse.


program MyProject

' Declarations section

main:

DDRD = 0xF8 '- Set Port D0-D2 to be inputs, D3-D7 are outputs.
PortD = 0x07 '- Enable internal pullup resistors on PORTD D0-D2.
PortD = 0x00 '- Set Port D to all off.

while TRUE

if PIND.B2 = 1 then ' If PORTD.2 is High
PIND.B6 = 0 '- LED three off
PIND.B5 = 0 '- LED two off
PIND.B3 = 0 '- LED one off
PIND.B7 = 0 '- LED four off
else ' If PORTD.2 is Low
PIND.B6 = 1 '- LED three on
PIND.B5 = 1 '- LED two on
PIND.B3 = 1 '- LED one on
PIND.B7 = 1 '- LED four on
end if

wend ' endless loop

end.

I also tried setting the output states to one and then tried just zero, same results. the output never turns fully on.

I then wrote the same program in assembly language, in avr studio. it works fine then. Only when I put the mikroBasic program on the avr does it have this behavior.

So what gives here? why do the output pins have this behavior in Mikro basic?


Robert

User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Problem with holding an output state

#2 Post by dejan.odabasic » 29 Nov 2012 13:08

Hello,

You need to use appropriate PORT output register.

PIND - input register of PORTD
PORTB - output register of PORTB

try changing the code:

Code: Select all

if PIND.B2 = 1 then ' If PORTD.2 is High
  PORTD.B6 = 0 '- LED three off
  PORTD.B5 = 0 '- LED two off
  PORTD.B3 = 0 '- LED one off
  PORTD.B7 = 0 '- LED four off
else ' If PORTD.2 is Low
  PORTD.B6 = 1 '- LED three on
  PORTD.B5 = 1 '- LED two on
  PORTD.B3 = 1 '- LED one on
  PORTD.B7 = 1 '- LED four on
end if
Also please check the pullup setup:

Code: Select all

PortD = 0x07 '- Enable internal pullup resistors on PORTD D0-D2.
PortD = 0x00 '- Set Port D to all off.
Best regards.

robert_d1968
Posts: 145
Joined: 14 Nov 2012 00:30
Location: China
Contact:

Re: Problem with holding an output state

#3 Post by robert_d1968 » 29 Nov 2012 19:21

Thank you for the timely response,

I did in fact try that before, and the outputs would not change states in the IDE.
I also tried using it without the internal pullups enabled. It still had the same affect.

Alas, I did check my code from the other attempts. it was more along the lines of:
if PIND.B2 = 1 then ' If PORTD.2 is High
PORTD.6 = 0 '- LED three off
end if.

I'm guessing this it what happens when you write code with no sleep. (over 32 hours)
I did make a couple of post on here with "PINA.B0 = 0 ' Turn off PortA bit zero"
I will have to go back and correct that mistake.

Yes, even in assembly language PORTB = 0xFF is an output for the entire register.
And the setting of the bits:

Pause:
sbic PIND,PD2 ; PD2 Switch 2 pressed ?
ret ; if Not, Return
rjmp WPause ; If pressed, jump to WPause to check for release
WPause:
sbis PIND,PD1 ; Wait for switch to be released
rjmp WPause ; if Not, released loop until it is
rjmp LEDS_ON ; Pause button released, Jump to LEDS_ON
LEDS_ON:
sbi PORTD, PD3 ; Mode 1 LED on
sbi PORTD, PD5 ; Mode 2 LED on
sbi PORTD, PD6 ; Mode 3 LED on
sbi PORTD, PD7 ; Mode 4 LED on
ret

But in assembly language language, to enable the pullup resistors, it's done right after setting the PORT direction. IE:
ldi Wreg, 0b11111000 ; set Port D0-D2 to be inputs, D3-D7 are outputs.
out DDRD, Wreg ; Data Direction register.
ldi Wreg, 0b00000111 ; Enable internal pullup resistors on PORTD D0-D2.
out PORTD, Wreg ; Write it to the port.
ldi Wreg, 0b00000111 ; set Port D to all off.
out PORTD, Wreg ; Write it to the port.


I will try again with:

if PIND.B2 = 1 then ' If PORTD.2 is High
PORTD.B6 = 0 '- LED three off
PORTD.B5 = 0 '- LED two off
PORTD.B3 = 0 '- LED one off
PORTD.B7 = 0 '- LED four off
else ' If PORTD.2 is Low
PORTD.B6 = 1 '- LED three on
PORTD.B5 = 1 '- LED two on
PORTD.B3 = 1 '- LED one on
PORTD.B7 = 1 '- LED four on
end if

and play with the internal pull up

I'm sure it will work fine, Thank you for pointing that out.

regards,

Robert
Last edited by robert_d1968 on 29 Nov 2012 21:09, edited 1 time in total.

robert_d1968
Posts: 145
Joined: 14 Nov 2012 00:30
Location: China
Contact:

Re: Problem with holding an output state

#4 Post by robert_d1968 » 29 Nov 2012 21:09

OK,

I tried it again using the correct output statement of PORTD.B3, this works very well. :)

Also great catch on the pullup resistors setup. :D

DDRD = 0xF8 '- Set Port D0-D2 to be inputs, D3-D7 are outputs.
PortD = 0x07 '- Enable internal pullup resistors on PORTD D0-D2.
PortD = 0x00 '- Set Port D to all off. <------------------------ "ERROR"

Should in fact be:

DDRD = 0xF8 '- Set Port D0-D2 to be inputs, D3-D7 are outputs.
PortD = 0x07 '- Enable internal pullup resistors on PORTD D0-D2
PortD = 0x07 '- Set Port D to all off. <------------------------ "Now it's happy"

Thanks,

Robert

Post Reply

Return to “mikroBasic PRO for AVR General”