|
|
View previous topic :: View next topic |
Author |
Message |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
Porting 16F722 code to 16F1527 |
Posted: Mon Nov 24, 2014 8:33 am |
|
|
Code that ran on a 16F722 will not run on a 16F1527.
I tried a simple program to test flashing an output. Some things work, some don't. I thought C was supposed to be transportable within limits but I can't understand why portC=0x00; does not work. The commented out lines work on the 16F722. Setting and clearing pins like RS in this example are the problem and will require extensive editing of my program.
PCM C Compiler, Version 5.019
Code: | #include <16F1527.h>
#FUSES INTRC_IO, NOWDT, PUT, BROWNOUT, MCLR
#use delay(clock=16000000)
#byte portB = 6
#byte portC = 7
#bit RB3 = portB.3
#define RS RB3
// *******************
// Main Function
void main()
{
set_tris_b (0x00);
set_tris_c (0x00);
while (true)
{
output_low (pin_c7); // this works
output_B(0x00); // this works
// RS=0; // does not work
// portC=0x00; // does not work
delay_ms (2000);
OUTPUT_HIGH (PIN_C7); // this works
output_B(0xff); // this works
// RS=1; // does not work
// portC=0xff; // does not work
delay_ms (2000);
}
}
// the above blinks pin C7 and all of RBx but the commented-out items do not work |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19559
|
|
Posted: Mon Nov 24, 2014 9:38 am |
|
|
Note that all the bits that are directly 'C' work.
It's where you start to not use C, but instead do direct I/O that it goes wrong.
If you use the C function 'output_b' or 'output_c' it'll work.
You are _manually_ setting the address of 'portB' to 6, and 'portC' to 7. Are these the addresses of these ports on the 1527?. Answer. No.
CCS C, 'knows' where portb, and portc are, and correctly accesses these for you if you use it's functions. You are doing direct accesses and getting the addresses wrong.....
In fact the compiler can fill these in for you:
Code: |
#byte portB = getenv("SFR:PORTB")
#byte portC = getenv("SFR:PORTC")
|
The compiler will then look up the addresses of these special function registers, and fill them in for you. It's because you have bypassed C, and assumed that the registers are at the same addresses, that the code doesn't work..... |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Nov 24, 2014 11:06 am |
|
|
Thanks Ttelmah, I wondered about the port addresses but these have worked for years on various chips. I can now easily correct my program. The test program works when modified to:
Code: | #include <16F1527.h>
#FUSES INTRC_IO, NOWDT, PUT, BROWNOUT, MCLR
#use delay(clock=16000000)
#byte portB = getenv("SFR:PORTB")
#byte portC = getenv("SFR:PORTC")
#bit RS = portB.3
// *******************
// Main Function
void main()
{
set_tris_b (0x00);
set_tris_c (0x00);
while (true)
{
RS=0; // works
portC=0x00; // works
delay_ms (2000);
RS=1; // works
portC=0xff; // works
delay_ms (2000);
}
}
// the above blinks pin B3 and all of RCx |
|
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
Include files and variables |
Posted: Mon Nov 24, 2014 4:33 pm |
|
|
I decided to display the values for the ports since the project was an LCD display.
I have the following in an include file of functions, it returns with the correct address of 13 for portB:
Code: | #byte portB = getenv("SFR:PORTB") // 13 |
If I try to use portB in my Main program as a constant it is garbage.
Code: | printf (WriteData, "portB=%2u", portB); // does not work |
If I use the following in Main it is correct and 13 is displayed:
Code: | char B = getenv("SFR:PORTB"); // 13
printf (WriteData, "portB=%2u", B); // displays “portB=13
|
Can someone explain what is happening? It seems to be with the way the programs are compiled and linked.
Last edited by rovtech on Mon Nov 24, 2014 7:30 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 24, 2014 4:54 pm |
|
|
Quote: | If I try to use portB in my Main program as a constant it is garbage |
It's not a constant. It's a variable that you can read/write to.
If you want to write 0x55 to PortB, you do this:
So if you put your scope on Pin B0, you would see a high level, and
on pin B1, you would see a low level, and so on.
Since it's a variable, if you want to display the address of it, you do this:
Code: | printf("%lx \r", &PortB); |
I am running this in MPLAB simulator, just to save time.
If you run that code, you will get this displayed:
That's the address of the variable, and it is correct. |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Nov 24, 2014 6:03 pm |
|
|
Thanks PCM programmer. It is somewhat obvious now. Somehow I had it in my mind that portB was a pointer to PORT B at address 13 (or 6 on other PICs).
Why does the following work if portB is a variable being overwritten?
Code: |
#byte portB = getenv("SFR:PORTB") // 13
#bit RB0 = PORTB.0
#bit RB1 = PORTB.1
#bit RB2 = PORTB.2
#bit RB3 = PORTB.3
#bit RB4 = PORTB.4
#bit RB5 = PORTB.5
#bit RB6 = PORTB.6
#bit RB7 = PORTB.7
|
I can display as you suggested but only in Hex as in the top line. I get compile errors if I use the second line:
Code: | printf (WriteData, "portA=%1x", &portA); |
Code: | printf (WriteData, "portA=%2u", &portA); |
or other variations. I would like an integer display.
This works and displays "portA=12"
Code: | char Z;
Z=&portA;
printf (WriteData, "portA=%2u", Z); |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 24, 2014 7:42 pm |
|
|
The RAM and SFR addresses in this PIC are 12 bits. This requires
%lx or %lu to display it properly. I'm not sure why the compiler
allows %x, because it is insufficient. If you do this, it will compile,
but it will only display the lower 8 bits, which is 0x99:
Code: | printf ("RC1REG=%x", &RC1REG); |
The correct way is to use %lx, then it displays 0x0199:
Code: | printf ("RC1REG=%lx", &RC1REG); |
If you want an unsigned decimal value, then you need to do this:
Code: | printf ("RC1REG=%lu", &RC1REG); |
|
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Nov 24, 2014 8:14 pm |
|
|
If I use
Code: | printf (WriteData, "portA=%1u", &portA); |
I get "Print format is invalid".
The 1x works only it's hex. Using an intermediate variable and 2u works and 3u gives a leading space.
Code: | printf (WriteData, "portA=%lu", &portA); |
OOPS - that's an ell not a one. Now I get it. l for long
It works.
Thanks, |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|