View previous topic :: View next topic |
Author |
Message |
DonWells
Joined: 04 Jan 2018 Posts: 5
|
Porting from 16F877 to 16F18877 |
Posted: Thu Jan 04, 2018 5:08 pm |
|
|
I have recently upgraded to CCS V5.075 so as to get support for the more modern chips.
I am now porting a working application from a 16F877 to a 16F1887.
All appears to be working file except for UART Rx.
Tx works ok.
Any suggestions as to what I might have missed? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Thu Jan 04, 2018 5:39 pm |
|
|
We'd have to see code to decide what's wrong. That big nor'easter has obscured my xtal ball.
Post a short, complete program that fails. It'll be about 12 lines if it's similar to the FAQ example for testing SIO.
The register map should be the same, maybe the pin is shorted or open..a hardware issue not code ?
Jay |
|
|
DonWells
Joined: 04 Jan 2018 Posts: 5
|
|
Posted: Thu Jan 04, 2018 6:15 pm |
|
|
Well here goes.
Its an edited version of the code to just include the uart bits.
I'm just trying to find if there are any gotchas porting to the 16f18877
As you can see, my message starts '[' followed by either a 'K' or a 'R'.
I believe the ISR is not being fired.
I believe the hardware is ok 'cos if a plug in a 16F877 it works fine.
Code: |
#include "16f18877.h"
//*******************************************************************************************
// Fuses
//
//
// Internal 32Mhz
// | Watchdog disabled
// | | Power up timer
// | | | No FLASH Program Memory Protection
// | | | | Brownout enabled
// | | | | | No Low Voltage programming
// | | | | | | No EE Memory Code Protection
// | | | | | | | FLASH program memory write enable
// | | | | | | | |
#fuses RSTOSC_HFINTRC_32MHZ, NOWDT, PUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT
#use Delay(clock=32000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BITS=8, PARITY=N, ERRORS)
#define RS232_BUFFER_SIZE 21
// variables used for rs232
byte rs232_index;
byte rs232_data_available;
char rs232_rx_data[RS232_BUFFER_SIZE];
byte start_msg;
// serial interface interrupt routine
#INT_RDA
rs232_isr()
{
char rcvd = 0;
rcvd = getc(); // get data from RS232
if (rcvd == '[') // check for message start "[", begin record
{
rs232_index = 0;
start_msg = 1;
}
if (start_msg == 1)
{
rs232_rx_data[rs232_index] = rcvd;
rs232_index++;
if (rcvd == ']') // check for msg end "]", stop record
{
start_msg = 0;
rs232_data_available = true;
}
if (rs232_index > RS232_BUFFER_SIZE) // reset buffer
{
start_msg = 0;
}
}
}
// the one and only...
main()
{
// 0 - output, 1 - input
set_tris_a(0b00010001); // for leds & buzzer, a4 input, a0 input for adc
set_tris_b(0b11111111); // all inputs
set_tris_c(0b10000000); // c7 rs232 input
// |
// rx
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RDA);
enable_interrupts(PERIPH);
enable_interrupts(GLOBAL);
// loop for a bit
while(TRUE)
{
// other stuff here
if (rs232_data_available == true)
{
rs232_data_available = false;
if (rs232_rx_data[1] == 'K') // mph - kmph message
{
if (rs232_rx_data[2] == 'm')
{
show_mph = TRUE;
}
else
{
show_mph = FALSE;
}
}
if (rs232_rx_data[1] == 'R') // reset
{
// 012
// [R]
ascii_trip_tenths = 0x30; // zero
ascii_trip_units = 0x30; // zero
ascii_trip_tens = 0x20; // blank
ascii_trip_hundreds = 0x20; // blank
write_eeprom(TRIP_EEPROM_ADDR, 0x30);
write_eeprom(TRIP_EEPROM_ADDR + 1, 0x30);
write_eeprom(TRIP_EEPROM_ADDR + 2, 0x20);
write_eeprom(TRIP_EEPROM_ADDR + 3, 0x20);
}
}
} // end of while loop
}
|
Last edited by DonWells on Thu Jan 04, 2018 7:09 pm; edited 2 times in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Thu Jan 04, 2018 6:40 pm |
|
|
Ok 1 thing pops out...
1) no device header....
#include pictype.h
I don't use the 16F1887
then...
2) this...
char rs232_rx_data[RS232_BUFFER_SIZE];
I don't see rs232_buffer_size set to a value... |
|
|
DonWells
Joined: 04 Jan 2018 Posts: 5
|
|
Posted: Thu Jan 04, 2018 7:11 pm |
|
|
Sorry, posting error. I have edited my original post.
The maximum size of a received message is 3 characters. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Thu Jan 04, 2018 7:23 pm |
|
|
OK.. get rid of the tris statements...let the compiler do it automatically.
The register sets for the 2 PIC are different so maybe that will make the program work ?
Not on test PC can't play computer.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 04, 2018 8:57 pm |
|
|
DonWells wrote: | I believe the ISR is not being fired. |
It is setting up a software UART. To make it setup a hardware UART,
add the two lines shown in bold below, in that exact position:
DonWells wrote: | #include "16f18877.h"
#fuses RSTOSC_HFINTRC_32MHZ, NOWDT, PUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT
#use Delay(clock=32000000)
#pin_select U1TX=PIN_C6
#pin_select U1RX=PIN_C7
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BITS=8, PARITY=N, ERRORS)
|
Also, the three byte variables shown below are not initialized,
and they should be:
DonWells wrote: |
byte rs232_index;
byte rs232_data_available;
char rs232_rx_data[RS232_BUFFER_SIZE];
byte start_msg; |
Also, there's a problem in your buffer limit test in your #int_rda isr.
You created a buffer 21 bytes in length. It will have indexes of 0 to 20.
Quote: | if (rs232_index > RS232_BUFFER_SIZE) |
But then in the isr your check for "greater than" 21. You should change
the test to check if it's "equal to" 21.
Also, this line below is not needed. It's done automatically when you
enable GLOBAL interrupts.
Quote: | enable_interrupts(PERIPH); |
I didn't see it in your posted code, but since you set PortB to all inputs,
I think you might enable internal pull-ups at some point. In this PIC,
the CCS pull-up functions take a bitmask as the parameter, instead of
True/False with the 16F877. That's because the pull-ups are individually
configurable instead of all or nothing. |
|
|
DonWells
Joined: 04 Jan 2018 Posts: 5
|
|
Posted: Thu Jan 04, 2018 11:11 pm |
|
|
Thank you PCM Programmer!
Inserting the lines:
Code: | #pin_select U1TX=PIN_C6
#pin_select U1RX=PIN_C7 |
fixed the problem.
I use:
Code: | port_b_pullups(0b11111111); |
but its not shown in my listing
I have initialised the variable as you suggest.
All working now! How come a s/w uart it did not work with the pins in the #use rs232 statement? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 05, 2018 12:51 am |
|
|
DonWells wrote: |
How come a s/w uart it did not work with the pins in the #use rs232 statement? |
Your original posted code did make a software UART.
But the CCS software UART routines can't make an #int_rda interrupt.
Only the hardware UART module can make that interrupt. |
|
|
DonWells
Joined: 04 Jan 2018 Posts: 5
|
|
Posted: Fri Jan 05, 2018 9:32 am |
|
|
Thanks for you help and explanation. |
|
|
|