Need Help SOS

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
Hi guys,
This is my first time here.
I'm having a problem simulating a pic asm code in proteus.
and I'm sure that there is some problem with the code
I just can't figure it out nor can I ask anyone except you guys.
please take a look at my code and tell me what's wrong.
let me learn something.
Thanks

Attached the asm file
 

Attachments

tshuck

Joined Oct 18, 2012
3,534
Hi guys,
This is my first time here.
I'm having a problem simulating a pic asm code in proteus.
and I'm sure that there is some problem with the code
I just can't figure it out nor can I ask anyone except you guys.
please take a look at my code and tell me what's wrong.
let me learn something.
Thanks

Attached the asm file
You should comment your code and tell us what you want it to do. I, for one, am not going to piece together your intention from uncommented code when you've already stated it doesn't do what you want.
 

ErnieM

Joined Apr 24, 2011
8,415
Yeah, we may seem to know everything but really, you didn't even bother to write out what the code is supposed to do, no less what it is not doing.

Sorry to seem rude to a new person but we need some sort of input to form an answer to help you.

And welcome to the forums. :)
 

JohnInTX

Joined Jun 26, 2012
4,787
I agree with the others. Commented code and a schematic is a basic starting point.
But, just looking at the code so far a few things jump out. I've commented the source with some of those things.

EDIT: Be sure to init ALL of the IO (unused lines to output '0' and don't forget things like CMCON etc that take over the pins. There are no shortcuts to a full init.
Also, the 44780 requires a delay after power up before you try to initialize it.

Good luck.
 

Attachments

Last edited:

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
I agree with the others. Commented code and a schematic is a basic starting point.
But, just looking at the code so far a few things jump out. I've commented the source with some of those things.

EDIT: Be sure to init ALL of the IO (unused lines to output '0' and don't forget things like CMCON etc that take over the pins. There are no shortcuts to a full init.
Also, the 44780 requires a delay after power up before you try to initialize it.

Good luck.
Thank you John, I'll try and work things out as you pointed out and study the datasheet and not just the command words of the LCD. I'll get back with the results as soon I have something substantial.
My guess is you are from Texas?
 

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
Yeah, we may seem to know everything but really, you didn't even bother to write out what the code is supposed to do, no less what it is not doing.

Sorry to seem rude to a new person but we need some sort of input to form an answer to help you.

And welcome to the forums. :)
Thanks for the welcome Ernie. I'll make it a point to comment all the code I write from now on.
 

MaxHeadRoom

Joined Jul 18, 2013
30,658
There are Pic tutorials by N.Goodwin that may help.
http://www.winpicprog.co.uk/pic_tutorial.htm
Tutorial 3

Also you can list code with the 'Insert' drop down. e.g.
Code:
;LCD 16 bit counter - using LCD Busy line
;Nigel Goodwin 2002

    LIST    p=16f628a        ;tell assembler what chip we are using
    include "P16F628a.inc"        ;include the defaults for the chip
    ERRORLEVEL    0,    -302    ;suppress bank selection messages
    __config 0x3D18            ;sets the configuration settings (oscillator type etc.)




        cblock    0x20            ;start of general purpose registers
            count            ;used in looping routines
            count1            ;used in delay routine
            counta            ;used in delay routine
            countb            ;used in delay routine
            tmp1            ;temporary storage
            tmp2
            templcd            ;temp store for 4 bit mode
            templcd2

                NumL            ;Binary inputs for decimal convert routine
                NumH  

                TenK            ;Decimal outputs from convert routine
                Thou  
                Hund  
                Tens  
                Ones  
        endc

LCD_PORT    Equ    PORTB
LCD_TRIS    Equ    TRISB
LCD_RS        Equ    0x04            ;LCD handshake lines
LCD_RW        Equ    0x06
LCD_E        Equ    0x07

        org    0x0000
        goto    Start

HEX_Table      ADDWF   PCL       , f
                RETLW   0x30
                RETLW   0x31
                RETLW   0x32
                RETLW   0x33
                RETLW   0x34
                RETLW   0x35
                RETLW   0x36
                RETLW   0x37
                RETLW   0x38
                RETLW   0x39
                RETLW   0x41
                RETLW   0x42
                RETLW   0x43
                RETLW   0x44
                RETLW   0x45
                RETLW   0x46


Text        addwf    PCL, f
        retlw    '1'
        retlw    '6'
        retlw    ' '
        retlw    'B'
        retlw    'i'
        retlw    't'
        retlw    ' '
        retlw    'C'
        retlw    'o'
        retlw    'u'
        retlw    'n'
        retlw    't'
        retlw    'e'
        retlw    'r'
        retlw    '.'
        retlw    0x00

Start        movlw    0x07
        movwf    CMCON            ;turn comparators off (make it like a 16F84)

Initialise:
        clrf    count
        clrf    PORTA
        clrf    PORTB
        clrf    NumL
        clrf    NumH



SetPorts:
        bsf     STATUS,        RP0    ;select bank 1
        movlw    0x00            ;make all pins outputs
        movwf    LCD_TRIS
        movwf    TRISB
        bcf     STATUS,        RP0    ;select bank 0

        call    LCD_Init        ;setup LCD


        clrf    count            ;set counter register to zero
Message:
        movf    count, w        ;put counter value in W
        call    Text            ;get a character from the text table
        xorlw    0x00            ;is it a zero?
        btfsc    STATUS, Z
        goto    NextMessage
        call    LCD_Char
        incf    count, f
        goto    Message

NextMessage:
        movlw    d'2'
        call    LCD_Line2W        ;move to 2nd row, third column
  
        call    Convert            ;convert to decimal
        movf    TenK,    w        ;display decimal characters
        call    LCD_CharD        ;using LCD_CharD to convert to ASCII
        movf    Thou,    w
        call    LCD_CharD
        movf    Hund,    w
        call    LCD_CharD      
        movf    Tens,    w
        call    LCD_CharD
        movf    Ones,    w
        call    LCD_CharD
        movlw    ' '            ;display a 'space'
        call    LCD_Char
        movf    NumH,    w        ;and counter in hexadecimal
        call    LCD_HEX
        movf    NumL,    w
        call    LCD_HEX
        incfsz    NumL,     f
        goto    Next
        incf    NumH,    f
Next:
        call    Delay255        ;wait so you can see the digits change
        goto    NextMessage

  etc etc
 

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
tHANK YOU GUYS!!! SEE ATTACHED FILE, STILL NO DOCUMENTATION BY ME
SPECIAL THANKS TO JOHN
NOW i CAN GET ON WITH THE NEXT PHASE...aTO d CONVERSION...
SO i'LL CLOSE THIS THREAD NOW?
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
Leave the thread open in case you have issues with the ADC.

Before you move to that, take a pass through your code and remove any comments that don't apply any more then add your own to describe each section of code. You will be glad you did that when your program gets bigger.
A few things to consider to make your source easier to read and maintain:

Consider mixed-case - lower case for opcodes, UPPER_CASE for user defined, mixed case for labels etc. LCDwrite. Every programmer has his/her own style but usually employ something like that to help identify things when the code is printed.
Don't use absolute RAM addresses in the code. Use CBLOCK or EQU to declare them with a label then refer to the label.
Use #define to make your IO definitions
Use ASCII characters where appropriate
Use BANKSEL instead of the B?F STATUS,RPx - its easier and less error prone.
Code:
;---------- Declaring RAM  -----------
cblock 02Bh ; RAM in your delay code starts here
  DelayCountH : 1 ; declare 1 byte named DelayCountH - it will be at 02bh
  DelayCountL : 1 ; declare another byte at 02ch
endc ; ends the cblock

; then, in your code:
DLY0:  
     MOVLW 0XFF
     MOVWF DelayCountH
AGAIN:   DECFSZ DelayCountH,F ; use F or W instead of 1 or 0
     GOTO D1
     RETURN

D1:     MOVLW 0XFF
     MOVWF DelayCountL
AGAIN1:   DECFSZ DelayCountL,F
     GOTO AGAIN1
     GOTO AGAIN

;------- Defining IO  -----------
#define LCD_E PORTB,RB2

; then in your code..
;Strobe LCD_E high then low
bsf LCD_E ; strobe high - the text 'LCD_E' will be replaced by PORTB,RB2 by the assembler - nice.
nop ; give it a little time
bcf LCD_E ; then low

;---------- ASCII for characters  ------------
movlw 'H' ; 48h is ASCII 'H' - tells the reader that you are using characters
call LCD_WRT
movlw 'E'
call LCE_WRT

;---------- BANKSEL for banks  ---------------
banksel PORTB ; generate bsf/bcf STATUS.. code to select the bank containing PORTB(and the other PORTS too)
clrf PORTB
clrf PORTA
banksel TRISB ; generate bsf/bcf STATUS.. code to select the bank containing TRISB (and the other TRIS too)
clrf TRISB
clrf TRISA
; etc.
Easier to see what's going on and if you move LCD_E to another pin, you only have to change the #define and rebuild.
There are couple of more things to chew on like how to write strings of characters (like MAX showed but easier maybe?) and explore the dreaded r-m-w problem when writing to PORTs but that can be later.

All said, you are on your way - WELL DONE.
Have fun.
 
Last edited:

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
tHANKS Its lot to take in, but I'll get it in a few days.
and as you said i do have a problem with the a/d conversion.
the problem is this:
after the a/d interrupt routine, the RETFIE instruction returns the pc to the interrupt vector (instead of pc+1) that has the CALL instruction thus looping again back to the routine endlessly and I dont understand why its doing what it is not supposed to be doing...
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
You are not clearing the interrupt flag ADIF in the interrupt routine so as soon as RETFIE re-enables the interrupts, it gets interrupted again immediately. You also have to set GO again to start the next conversion after reading ADRESH/L.

Also in init, you should
1) configure the interrupt sources first
2) clear any associated interrupt flags
3) enable the interrupt(s)

in that order.
 
Last edited:

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
ok, got it.
I'll get back with results.
I wish they taught us in-such-detail in school.
Anyway I'll stop whining and get to work.
Thank you again
 

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
!!!!!!!!!mERRY cHRISTMAS!!!!!!!!!
GREETINGS FROM mUMBAI, iNDIA!!!!

@JohnInTX - i JUST GOT RID OF THE INTERRUPT SCHEME AS IT TURNS OUT THAT THE STACK WAS OVER AND UNDER FLOWING, INSTEAD OF INTERRUPTING, THE PIC JUST WATCHES THE GO/DONE' BIT FOR CLEARING AND THEN JUMPS TO THE AD READ CODE.
nOW ALL i HAVE TO DO IS TO COMBINE THE LCD AND A/D CIRCUITS USING A SINGLE PIC AND i'LL BE DONE.

@MaxHeadRoom - THANKS FOR THE 'LOOK UP TABLE' EXAMPLE IT WILL COME VERY HANDY IF I CAN GET THE OTHER THINGS CORRECTLY.

tHANK YOU GUYS AND AGAIN ENJOY YOUR HOLIDAYS.
 

bertus

Joined Apr 5, 2008
22,923
Hello,

Is your capslock on?
Why write almost everything in capitals.
Writing all in capitals, is like shouting.

Bertus

PS the same happens in your profile.
 

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
@bertus - Yes my caps were on, sorry.

Another question, I'm getting into stack overflow and underflows in my pic project, any ideas.
Again I'll attach the .asm file. hope it doesn't drive you nuts.

First things last, the project is a Musical Tuner which I'm doing in my own time to learn as I'm not going to school for another 6 months.
so instead of wasting time i thought I try my hand at some practical stuff. before doing this all i had designed was a power supply on a dotmatrix pcb, which is again not really designing, I just wired the stuff and soldered and all...
I'm tired...

ps: I'm using Proteus-Isis to simulate.
 

Attachments

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
Guys I got it. worry not.
It'll take me 1 or 2 days to tie up the loose ends but then I'll submit my first SOLO project here.
godddamit I feel great!!!
 

JohnInTX

Joined Jun 26, 2012
4,787
Merry Christmas and Holiday Greetings to you as well.
Ideas? Always!
Code:
START:        ;MAIN LOOP BEGINS HERE
        BCF STATUS,RP0    ;BANK0
        CALL DLY_AQ
        BSF ADCON0,2    ;START CONVERSION
WAIT:    BTFSC ADCON0,2    ;LOOK FOR DONE' OR GO BEING CLEARED
        GOTO WAIT
        CALL DLY0        ;WAIT FOR DATA TO SETTLE IN ADRESL


********
        GOTO AD_READ
        you are GOTOing a subroutine ending in RETURN - STACK UNDERFLOW HERE

***********
      CALL LUT ;
you don't ensure that W is < A0h, the end of your table.  W >=A0h will cause it to jump off the end of the table, NOP its way to 100h (unprogrammed memory is NOP)
and work its way down to calling the table again - and again. - DATA DEPENDENT STACK OVERFLOW HERE.
Be sure that W is < the number of entries in the table - especially important when the value is driven by the outside world, in this case the ADC reading. 
Also, be sure that the table does not span ROM banks.
Since your lookup does not manage PCLATH, it will just wrap around in one 256 word bank.
Qualifying W and ensuring table location is critical when you use ADDWF PCL,F.

        CALL LCD_WRT
        GOTO START         ;BEGIN ALL OVER AGAIN
If Proteus does not allow you to step your code, build it in MPLAB 8.x or MPLABX and use MPSIM to step the code, watch the stack, trace where the table lookups go. You can also load the .COF file from another assembler into MPLAB and still use MPSIM. If you haven't used MPSIM to debug, this will get you started.

Off to see family down south. Replies will be a bit spotty if any.
Good luck!​
 
Last edited:

Thread Starter

Zahir_s

Joined Dec 23, 2014
32
The 'Tuner' works fine on Proteus, now I want to reduce its size and for that I need to use a small PIC and use the Display in the 4-bit mode.
So the problem is, I am testing the display in the 4-bit mode and it is just throwing up garbage values, for example, in place of 'L' I'm getting a '$' and likewise.
Any Ideas on how to debug, I tried breakpointing, but I can't figure out the source of this erroneous data.

Code:
;====================================================================
; Main.asm file generated by New Project wizard
;
; Created:   Fri Dec 26 2014
; Processor: PIC16F877
; Compiler:  MPASM (MPLAB)
;====================================================================

;====================================================================
; DEFINITIONS
;====================================================================

    #include p16f877.inc    ; Include register definition file

    __CONFIG _WDT_OFF
    ORG 0X0000
    GOTO INIT
    ORG 0X0004
    GOTO START
   
    CBLOCK 0X0020
        TEMP
        T_S
        T_L
        T_L_2
    ENDC
   
    #DEFINE FN 0X24
    #DEFINE DO 0X0F
    #DEFINE EM 0X06
    #DEFINE DS 0X14
    #DEFINE CD 0X01
    #DEFINE CH 0X02
    #DEFINE COUNT_S 0XFF
    #DEFINE COUNT_L 0XFF
    #DEFINE NO_ANLG 0X06

    ORG 0X0030
INIT:
        BCF STATUS,RP1
        BSF STATUS,RP0    ;BANK1
        CLRF TRISA
        CLRF TRISB
        CLRF TRISC
        CLRF TRISD
        CLRF TRISE
        BCF STATUS,RP0    ;BANK0
        CLRF PORTA
        CLRF PORTB
        CLRF PORTC
        CLRF PORTD
        CLRF PORTE        ;PIC INITIALIZATION DONE
        CLRF TEMP
        CLRF ADCON0
        BCF STATUS,RP1
        BSF STATUS,RP0
        MOVLW NO_ANLG
        MOVWF ADCON1
        BCF STATUS,RP0    ;BANK0
       
       
START:
        CALL LCD_INIT
        CALL DLY_L
       
        BSF PORTE,0
        BCF PORTE,1        ;R/W=0,RS=1, WRITE DATA TO LCD
       
       
        MOVLW 'L'
       
        CALL LCD_OUT
       
        MOVLW 'C'
       
        CALL LCD_OUT
       
        MOVLW 'D'
       
        CALL LCD_OUT
       
        MOVLW ' '
       
        CALL LCD_OUT
       
        MOVLW '4'
       
        CALL LCD_OUT
       
        MOVLW '-'
       
        CALL LCD_OUT
       
        MOVLW 'B'
       
        CALL LCD_OUT
       
        MOVLW 'i'
       
        CALL LCD_OUT
       
        MOVLW 't'
       
        CALL LCD_OUT
       
        MOVLW 'M'
       
        CALL LCD_OUT
       
        MOVLW 'o'
       
        CALL LCD_OUT
       
        MOVLW 'd'
       
        CALL LCD_OUT
       
        MOVLW 'e'
       
        CALL LCD_OUT
       
       
        GOTO $
       
LCD_OUT
        BCF STATUS,RP0
        BCF STATUS,RP1    ;BANK 0
        MOVWF TEMP         ;SAVE A COPY OF W DATA TEMPORARILY
        SWAPF TEMP,W
        ANDLW 0X0F        ;MASK THE LSB THAT ARE IN MSB POSITION IE MAKE ALL 4 BITS 0
        MOVWF PORTD        ;OUT WITH MSB
        BSF PORTE,2
        BCF PORTE,2        ;STROBE E
        CALL DLY_S
       
        MOVF TEMP,W
        ANDLW 0X0F
       
        MOVWF PORTD    ;OUT WITH LSB
        BSF PORTE,2
        BCF PORTE,2 ;STROBE E
       
        CALL DLY_L
       
        RETURN
       
LCD_INIT
        BCF STATUS,RP0
        BCF STATUS,RP1    ;BANK 0
        BCF PORTE,0
        BCF PORTE,1        ;RS,R/W=0 I.E. COMMAND
        MOVLW FN        ;FUNC SET
       
        CALL LCD_OUT
        BSF PORTE,2
        BCF PORTE,2
        CALL DLY_L
       
        MOVLW DO        ;DISP ON OFF
       
        CALL LCD_OUT
        BSF PORTE,2
        BCF PORTE,2
        CALL DLY_L
       
       
        MOVLW EM        ;ENTRY MODE
       
        CALL LCD_OUT
        BSF PORTE,2
        BCF PORTE,2
        CALL DLY_L
       
        MOVLW DS        ;DISP SHIFT
       
        CALL LCD_OUT
        BSF PORTE,2
        BCF PORTE,2
        CALL DLY_L
       
        MOVLW CD        ;CLEAR DISP
        CALL LCD_OUT
        BSF PORTE,2
        BCF PORTE,2
        CALL DLY_L
       
        MOVLW CH        ;CURSOR HOME
        CALL LCD_OUT
        BSF PORTE,2
        BCF PORTE,2
        CALL DLY_L
        RETURN
       
DLY_S
        BCF STATUS,RP0
        BCF STATUS,RP1
        MOVLW COUNT_S
        MOVWF T_S
AGAIN:    DECFSZ T_S,F
        GOTO AGAIN
        RETURN
       
DLY_L
        BCF STATUS,RP0
        BCF STATUS,RP1
        MOVLW COUNT_L
        MOVWF T_L
REPEAT:    DECFSZ T_L,F
        GOTO NEST1
        RETURN
        MOVLW COUNT_L
        MOVWF T_L_2
NEST1:  DECFSZ T_L_2,F
        GOTO NEST1
        GOTO REPEAT
       
      END
 

John P

Joined Oct 14, 2008
2,060
ORG 0X0004
GOTO START???

0x04 is where the interrupts jump to. I suppose it's OK if you aren't actually using interrupts.

Is there any pattern to what appears on the LCD versus what you think is being sent to it? Because if there's a predictable effect, it might be a result of having the data wires in the wrong order.
 
Top