Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Basic counter for a PIC16F877A...

Status
Not open for further replies.

triplestak

New Member
Hey, I'm new in here and was seeking some advice on a simple program I'm having to write for one of my Electronics classes. It's a basic program written for the PIC16F877A and bit zer0 (SW0) on the switch board (Port B) resets the outputs on Port A and the bit 1 (SW1) starts a count on the LEDs and increments them one value at a time. The code works fine in the MPLAB IDE debugger, but when I send the Hex file to the Control board, the reset button works and the run button only turns on the first bit or the bit zero LED, but it doesn't increment. Here is a copy of the code. Any help would be greatly appreciated...

list p=16f877a ; list directive to define processor
#include <p16f877a.inc> ; processor specific variable definitions


PORTA EQU 005h ;Port A Data Register
PORTB EQU 006h ;Port B Data Register
TIMER EQU 020h ;Spare register for delay
STATUS EQU 003h
TRISA EQU 085h
ADCON1 EQU 09Fh

inres EQU b'00000000' ;'Reset' input button SW0
inrun EQU b'00000001' ;'Run' input button SW1

bcf STATUS,RP0
bcf STATUS,RP1 ;Selects Bank 0
clrf PORTA ; clears port A
bsf STATUS,RP0 ;Selects Bank 1
movlw 006h
movwf ADCON1
movlw b'00000'
movwf TRISA ;Prepares port A for Output
bcf STATUS,RP0
bcf STATUS,RP1 ;Selects Bank 0
clrf PORTA

movlw b'00000' ;Port A Data Direction Code
TRIS PORTA ;Load the DDR code into F86

goto reset

delay movwf TIMER ;is loaded into spare register

down decfsz TIMER ;decrement timer register
goto down ;and repeat until zero then
RETURN ;return to main program

reset clrf PORTA ;Clear Port A Data

start btfsc PORTB,inres ;Test SW0 input button
goto reset ;and reset Port A

btfss PORTB,inrun ;Test SW1 input button
goto start ;and run count if pressed

INCF PORTA ;Increment count at Port A
movlw 002 ;Delay count literal
CALL delay ;Execute delay subroutine
goto start ;Repeat main loop

END ;Terminate source code
 
You did not make the TRISB pins inputs! The fact that one button works sometimes is because you didn't clear port b and it's reading the 1's?

Next time use code blocks please!
 
Thanks...

I really appreciate it Birdman. Question, I was under the impression that most I/O ports default to input unless you specify otherwise. And when you say code blocks you mean the separation asterisks between different sets of code, correct?
 
I really appreciate it Birdman. Question, I was under the impression that most I/O ports default to input unless you specify otherwise. And when you say code blocks you mean the separation asterisks between different sets of code, correct?

hi,
D' means like this.... use the '#' option on the post menu to enclose your text to keep the formatting.

Code:
PORTA    equ    005h        ;Port A Data Register
PORTB    equ    006h        ;Port B Data Register
TIMER    equ    020h        ;Spare register for delay
STATUS    equ    003h
TRISA    equ    085h
ADCON1    equ    09Fh

inres    equ    b'00000000'    ;'Reset' input button SW0
inrun    equ    b'00000001'    ;'Run' input button SW1

    bcf    STATUS,RP0
    bcf    STATUS,RP1    ;Selects Bank 0
    clrf    PORTA        ; clears port A
    bsf    STATUS,RP0    ;Selects Bank 1
    movlw    006h
    movwf    ADCON1
    movlw    b'00000'
    movwf    TRISA        ;Prepares port A for Output
    bcf    STATUS,RP0
    bcf    STATUS,RP1    ;Selects Bank 0
    clrf    PORTA

    movlw    b'00000'    ;Port A Data Direction Code
TRIS    PORTA            ;Load the DDR code into F86

    goto    reset

delay    movwf    TIMER        ;is loaded into spare register

down    decfsz    TIMER        ;decrement timer register
    goto    down        ;and repeat until zero then
    return            ;return to main program

reset    clrf    PORTA        ;Clear Port A Data

start    btfsc    PORTB,inres    ;Test SW0 input button
    goto    reset        ;and reset Port A

    btfss    PORTB,inrun    ;Test SW1 input button
    goto    start        ;and run count if pressed

    incf    PORTA        ;Increment count at Port A
    movlw    002        ;Delay count literal
    call    delay        ;Execute delay subroutine
    goto    start        ;Repeat main loop

    end            ;Terminate source code
 
Not so far...

I tried what you said by adding this to the code:

Code:
bsf	 	STATUS,005h
	    movlw 	b'11111111'		   
        movwf 	TRISB
        bcf	 	STATUS,005h

Any other suggestions?
 
hi,
D' means like this.... use the '#' option on the post menu to enclose your text to keep the formatting.

Code:
PORTA    equ    005h        ;Port A Data Register
PORTB    equ    006h        ;Port B Data Register
TIMER    equ    020h        ;Spare register for delay
STATUS    equ    003h
TRISA    equ    085h
ADCON1    equ    09Fh

inres    equ    b'00000000'    ;'Reset' input button SW0
inrun    equ    b'00000001'    ;'Run' input button SW1

    bcf    STATUS,RP0
    bcf    STATUS,RP1    ;Selects Bank 0
    clrf    PORTA        ; clears port A
    bsf    STATUS,RP0    ;Selects Bank 1
    movlw    006h
    movwf    ADCON1
    movlw    b'00000'
    movwf    TRISA        ;Prepares port A for Output
    bcf    STATUS,RP0
    bcf    STATUS,RP1    ;Selects Bank 0
    clrf    PORTA

    movlw    b'00000'    ;Port A Data Direction Code
TRIS    PORTA            ;Load the DDR code into F86

    goto    reset

delay    movwf    TIMER        ;is loaded into spare register

down    decfsz    TIMER        ;decrement timer register
    goto    down        ;and repeat until zero then
    return            ;return to main program

reset    clrf    PORTA        ;Clear Port A Data

start    btfsc    PORTB,inres    ;Test SW0 input button
    goto    reset        ;and reset Port A

    btfss    PORTB,inrun    ;Test SW1 input button
    goto    start        ;and run count if pressed

    incf    PORTA        ;Increment count at Port A
    movlw    002        ;Delay count literal
    call    delay        ;Execute delay subroutine
    goto    start        ;Repeat main loop

    end            ;Terminate source code

Thank you so much for the heads up on the code blocks!!!
 
Code:
list p=16f877a ; list directive to define processor
#include <p16f877a.inc> ; processor specific variable definitions

inres EQU 0  ;'Reset' input button SW0
inrun EQU 1 ;'Run' input button SW1

cblock 0x20
TIMER        ;Spare register for delay
TIMER1
endc

org 0x00
goto Init

org 0x04
retfie

Init:
clrf PORTA ; clears port A
bsf STATUS,RP0 ;Selects Bank 1
clrf TRISA ;Prepares port A for Output
movlw 0xff
movwf PORTB
bcf STATUS,RP0

start:
btfsc PORTB,inres ;Test SW0 input button
clrf  PORTA;  reset Port A

btfss PORTB,inrun ;Test SW1 input button
goto start ;and run count if pressed   

incf PORTA ;Increment count at Port A
movlw 255  ;Delay count literal
call delay ;Execute delay subroutine
goto start ;Repeat main loop

delay:
movwf TIMER ;is loaded into spare register
down:
decfsz TIMER1 ;decrement timer register
goto down ;and repeat until zero then
decfsz TIMER
goto down
return ;return to main program

end ;   Terminate source code


Moved a whole bunch around, made delay longer.
After this i think your problem would be hardware or configurations.

Update me!
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top