Connect with us

Microcontrollers adding data

Discussion in 'Microcontrollers, Programming and IoT' started by richieec, Nov 10, 2012.

Scroll to continue with content
  1. richieec

    richieec

    4
    0
    Nov 10, 2012
    I'm studying now microcontrollers , and i have to do a program in pic 16f84a in c(pcw ccs compiler). This program must add a bit from PORTA with 05h data and the result must show in PORTB. PORTB = PORTA + 05H.

    SO this is the program i have done, it's compile without errors, but in the circuit it doens't works well. I don't know what are the errors, If someone could help me, i would greatly apreciate.

    #include <16f84a.h>
    #fuses xt, nowdt
    #use delay(clock= 4000000)
    #byte portb = 6
    #byte porta = 5
    int main(){
    int w = 5 ;

    set_tris_b(0x00);
    set_tris_a(0x1F);

    while(true){
    w = porta + w;
    portb = w;
    }
    }
     
  2. Harald Kapp

    Harald Kapp Moderator Moderator

    10,764
    2,424
    Nov 17, 2011
    PICs are not my domain, but:

    1) Have you ensured Port A is set to input and Port B is set to output? Usually you have to do some setup to control the data direction of I/O ports, but I don't see any code for this.

    2) Your compiler may be too "intelligent" for this program :p
    An optimizing compiler will recognize that porta is not changed by the program and thus will (possibly) eliminate the instruction from within the loop. This may not be the case with your compiler, but I don't know. Some compilers require that I/O-ports be defined as "volatile". That way the compiler assumes that the "variable" porta may change any time and will not eliminate the instructions from within the loop.

    3) This loop
    Code:
    while(true){
    w = porta + w;
    portb = w;
    }
    doesn't do what you describe. The line " w = porta + w;" is iterated in every loop cycle. Do the following "Gedankenexperiment":
    assume w=5 (as set by your first statement before the loop)
    assume porta=1
    what becomes of w by "w = porta + w;"?
    When the loop starts the next cycle, what will w be after the same statement? Obviously you should not change w within the loop. Use a separate variable or do something like this:
    Code:
    portb = porta + w;
    4) "portb = porta + w;" may still not work properly. You are assuming that only bit 0 of port A changes from 0 to 1 and back and that all other bits (1...7) are always 0. Can you ensure this? Probably not. You need to "mask out" all other bits. You can use and AND operator for this:
    Code:
    portb = (porta & 0x01) + w;
    "porta & 0x01" sets all bits to 0 except bit 0. If bit 0 = 0, then the result is 0, too. If bit 0 is 1, then the result will be 1, too.

    Let's see if any of this helps.

    Harald
     
  3. richieec

    richieec

    4
    0
    Nov 10, 2012
    i'm ensured that Port A is set to input and Port B is set to output with this exprsions:
    set_tris_b(0x00);
    set_tris_a(0x1F);

    The PORTA is formed by 5 bits and PORT B by 8 bits, so with these registres (TRIS_A , TRIS_B) i control the data direction of I/O ports.

    The variable w is for WORKING REGISTRER(W registrer) involve in every arithmetic operation in a pic.

    I only modify this line: portb = porta + w for this: portb = (porta & 0x01) + w; but the programa doesn't work yet.

    #include <16f84a.h>
    #fuses xt, nowdt
    #use delay(clock= 4000000)
    #byte portb = 6
    #byte porta = 5
    int main(){
    int w = 5 ;

    set_tris_b(0x00);
    set_tris_a(0x1F);

    porta =1;
    while(true){
    w = porta + w;
    portb = (porta & 0x01) + w;
    }
    }
     
    Last edited: Nov 10, 2012
  4. richieec

    richieec

    4
    0
    Nov 10, 2012
    so this is my circuit i made.
     

    Attached Files:

  5. Harald Kapp

    Harald Kapp Moderator Moderator

    10,764
    2,424
    Nov 17, 2011
    Let us go through the code:
    Code:
    porta =1;
    while(true){
    w = porta + w;
    portb = (porta & 0x01) + w;
    }
    
    porta =1; Why? port a is an input and therefore it should not be written, only read.

    w = porta + w; Either I don't understand the operation of the W register or you have not understood my first post. Assume W=5 on entry into the loop and porta=1. Then after this statement w=porta+w=1+5=6. When the PIC enters the next round of the loop, the same statement becomes w=porta+w=1+6=7 (because w=6 from the previous round). And so it goes on W=5, 6, 7, 8, 9, ... As fast as the PIC can run through the loop.

    If portb = (porta & 0x01) + w doesn't work, modify the code using an additional variable or a define:
    Code:
    int main(){
    int add = 5 ;
    int w;
    
    set_tris_b(0x00);
    set_tris_a(0x1F);
    
    porta =1;
    while(true){
    w = (porta & 0x01) + add;
    portb = + w;
    }
    } 
    or
    Code:
    int main(){
    #define Add 5 ;
    int w;
    
    set_tris_b(0x00);
    set_tris_a(0x1F);
    
    porta =1;
    while(true){
    w = (porta & 0x01) + Add;
    portb = + w;
    }
    } 
    Finally an important question
    What does that mean? What is the expected reaction of the program? And more important: what does it do instead?

    So much for the code. Let's come to the circuit.
    Your image is too small to recognize much detail. But from what I see it looks like you have pull-up resistors on port A and pushbuttons to GND on port A. This means that port A = 0b11111=0x1F at all times except when a button is pressed. From your code I take it that you untend to do the reverse: Have port A = 0 at all times but have a 1 at the corresponding input pin once a button is pressed. That means you have to connect the resistors to GND and the pushbuttons to Vcc. Or you have to invert the result from reading porta in software.
    Another thing to consider is debouncing. Read this article. It will show you what this is all about.

    Last not least: If you intend to do more than just outputting porta+5 on port B, tell us the whole story. Your rather simple loop may be inadequate.

    Regards,
    Harald
     
  6. CocaCola

    CocaCola

    3,635
    5
    Apr 7, 2012
    Double click on hit attachment, and get it into it's own browser window and then view 100% it's actually HUGE, but being resized by most browsers due to the extended boarder void...

    Or view my cropped attachment of said image...
     

    Attached Files:

  7. Harald Kapp

    Harald Kapp Moderator Moderator

    10,764
    2,424
    Nov 17, 2011
    I've done that, but even as a full size image details are not very well visible. Probably due to the browser, as you say.

    Your cropped version displays much better, thanks CC.

    Harald
     
  8. richieec

    richieec

    4
    0
    Nov 10, 2012
    Thanks Harald Kapp for your help, the program works well now, but i have reading some books and i realized that i don't needed declare a variable w, because the only thing the program must do it's add the data in port A plus 05h, so i only have to do this in the while loop: portb = porta + 5. Anyway i really apreciate your help, i'm sure the article is going to be very useful for future projects i have in mind.
    I'm a beginner now but i hope further progress in this fascinating area of microcontrollers and embedded systems.

    Regards
    Richie
     
    Last edited: Nov 12, 2012
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-