Maker Pro
Maker Pro

Microcontrollers adding data

richieec

Nov 10, 2012
4
Joined
Nov 10, 2012
Messages
4
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;
}
}
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,722
Joined
Nov 17, 2011
Messages
13,722
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
 

richieec

Nov 10, 2012
4
Joined
Nov 10, 2012
Messages
4
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:

richieec

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

Attachments

  • circuit.png
    circuit.png
    82.5 KB · Views: 139

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,722
Joined
Nov 17, 2011
Messages
13,722
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
but the programa doesn't work yet.
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
 

CocaCola

Apr 7, 2012
3,635
Joined
Apr 7, 2012
Messages
3,635
Your image is too small to recognize much detail

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...
 

Attachments

  • cropit.jpg
    cropit.jpg
    54.3 KB · Views: 125

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,722
Joined
Nov 17, 2011
Messages
13,722
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
 

richieec

Nov 10, 2012
4
Joined
Nov 10, 2012
Messages
4
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:
Top