CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

18F4550 and INT_EXT serial port.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

18F4550 and INT_EXT serial port.
PostPosted: Wed Aug 24, 2016 2:35 pm     Reply with quote

Having some problems getting my 18F4550 up and running with two serial ports. I am using the C6,C7 UART for the PC side that sees the most traffic. I have a second serial port talking to a 16F876 set up to come in on B0 INT_EXT0. I am set up for 9600 baud on the UART and 4800 baud on the INT_EXT UART. Not getting into my ISR when data comes in. O-scope shows data being present but cannot even get an acknowledge that the ISR is firing.
I have #priority set to INT_EXT being highest priority, should be by default. I am also using INT_RTCC and INT_RDA. I have my INT_EXT transition set to H_TO_L and all interrupts are enabled, disabling all interrupts except INT_EXT when in the INT_EXT ISR. Here are a few code snippets.
Code:

#include <18f4550.h>
#DEVICE ADC=10                           
#include <stdlib.h>


//#fuses XT,NOWDT,NOPROTECT,NOLVP
#FUSES HS,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP,NODEBUG, CPUDIV1

#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,stream=USB_SERIAL,ERRORS)
#use rs232(baud=4800,xmit=pin_b1,rcv=pin_b0,stream=CTRL)   // serial comm w/ down hole power module.
#priority INT_EXT,INT_RDA,INT_RTCC

Code:

#int_ext
void DH_serial_isr()   // Reads incoming data from the USART  sent by the down hole power module.  GTS 6-2016
{                   
 
   char cChar;

   disable_interrupts (INT_RDA);
   disable_interrupts (INT_RTCC);
   cChar = fgetc(CTRL);          // get char from down hole
   fprintf(USB_SERIAL, "***%c\n\r",cChar);
   DH_serial_buffer[DH_buffer_index] = cChar;
   DH_buffer_index = DH_buffer_index + 1;
   if(cChar == '#')  {    // The message is complete         
      DH_msg_complete_flg = 1;
      DH_serial_buffer[DH_buffer_index] = '\0';  // end of string char
      DH_buffer_index = 0;
   }
   else {
       DH_msg_complete_flg = 0;            // clear the flag for next time.
   }

   enable_interrupts (INT_RDA);    //re-enable interupts, but check and only turn on INT2 if it was on previously. INT EXT2 should only be on if we were are using the internal GPS   
   enable_interrupts (INT_RTCC);   

}  // end DH_serial_isr()


I know, the ISR is dirty and I am doing the no no of printing from it, trying to see if the code is firing, tomorrow I will just toggle a pin.
wondering what is wrong here, seems like I am doing it right and it is a pretty simple thing to do. open for ideas.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 3:02 pm     Reply with quote

First thing may be to do is put the _faster_ serial on the INT_EXT stream. Otherwise to receive a character on this, you are stuck in the INT_EXT interrupt for 2 byte times of the INT_RDA, and characters will be lost.....
See below.

Then the second is to keep the ISR short. You are doing far too much inside the ISR.

Now some problems at the start. Why on earth are you running so slow?. You need some CPU speed to do this. You are currently selecting 'HS', which is for a crystal faster than 4MHz, but are running at 4MHz. Lets run faster:
Code:

#include <18f4550.h>
#DEVICE ADC=10                           
//Do not load libraries till after the fuses and timing are defined

#FUSES XTPLL, PLL1 ,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#FUSES NODEBUG, CPUDIV3
//This will route your 4MHz crystal into the PLL. /1, *24
//Then divide this by 8 (you'll have to study the data sheet to see why
//'div3' gives /8...

#use delay(clock=12MHz) //96/8

#include <stdlib.h>
//now include other things


Now we need to know more about the nature of the two serials?.
If nothing will come on the second stream at the same time as you are receiving data on the INT_EXT stream, then things can be all right. One thing you could do, is send an 'XOFF' on the RDA stream to prevent problems, or if the nature is such that this is unlikely, and your data format can recover from lost bytes, then again this may be OK. Otherwise you need to think again.

Now, inside your interrupt all other interrupts are disabled already. Get rid of the wasted disable/enable instructions.
You are not using hardware interrupt priorities. #PRIORITY only sets the order that the interrupts are polled.

To use hardware priorities, you need to add #DEVICE HIGH_INTS=TRUE as the line after the ADC=10 line, and declare #INT_EXT HIGH.

So store the character to a buffer, and just exit. If you want to print it to USB, do this in the main code outside.

You don't show us your interrupt setup line. You need to be using H_TO_L on ext_int_edge, to get the correct edge on the data. Also (obviously) enabling this interrupt, and the global.

SAMPLE_EARLY, tells the code to assume there has been some delay in arriving at the read
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 8:06 am     Reply with quote

thanks Ttelmah for all the comments.
I have done the clock changes as you recommended.
Bumped the 4800 rate to 9600
tried to do the DEVICE HIGH_INTS calls but compiler did not like it.
my compiler is PCH version 5.026 xxxxx
Running on windows 10.

I stripped all the unnecessary stuff out of the ISR. I read the char, toggle pin B5 and get out.
the O-scope shows it is not getting into the ISR at all.
my interrupt enables are as follows:

Code:
set_rtcc(0);
setup_timer_0( RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT);  //15 interrupts/sec  18F chip RTCC in 8 bit mode not 16


enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
clear_interrupt(INT_EXT);

enable_interrupts(INT_RTCC);                    // set up the RTCC counter
enable_interrupts(INT_RDA);                     // set up the serial interrupt
enable_interrupts(GLOBAL);                      // turn on all interrupts.

I am open for more ideas.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 11:04 am     Reply with quote

Maybe time to go back to 'square one' ?
Code a simple program that JUSTS looks for the external interrupt to occour and toggle an LED? NO timers, no serial, KISS code. Might even be code in the 'examples' folder ?

OR...

maybe a hardware issue ? bad solder connection, loose wire, etc.

'something' ain't right and the easiest way to debug is go 'low level', one step at a time.

Jay
dan king



Joined: 22 Sep 2003
Posts: 119

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 11:16 am     Reply with quote

why not use the USB port for the PC connection and then the HW uart for the other? The 18f4550 is a USB enabled part.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 11:38 am     Reply with quote

agreed, I am stripping the code down now. more later.
as for USB, not an option this time around need the length of RS-232 transmissions.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 1:17 pm     Reply with quote

ok, found what stops INT_EXT from working right with my serial interrupt.
Code:

enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
clear_interrupt(INT_EXT);

enable_interrupts(INT_RTCC);                    // set up the RTCC counter
enable_interrupts(INT_RDA);                     // set up the serial interrupt
enable_interrupts(GLOBAL);                      // turn on all interrupts.

//SETUP_ADC_PORTS(ALL_ANALOG);                    // all analog ports on
//SETUP_ADC(ADC_CLOCK_DIV_32); 
 

here is a snippet of my initialization routine showing the interrupts I am setting up. note the ADC setup calls are commented out. When I restore them to the code, my INT_EXT ISR stops working. I know this by only toggling a pin in the ISR and watching it with the scope.
perhaps here is a way to still get the analogs enabled and make everyone get along? I need analogs on this project.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 1:27 pm     Reply with quote

it is the setup_adc_ports call that is messing the INT_EXT up. not sure why that is, my INT_EXT is on B0 and B1 and my analogs are on port A.

crazy.
really open for ideas and theories now.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 2:19 pm     Reply with quote

OK, silly question but...
are you 'committed' to the 4550 ?

I ask cause I dumped it years ago for the 46k22...tons of memory and TWO HW UARTs, plus other goodies... $2 ttl-usb module gets me to PC these days.

options, maybe it's one for you ??

BTW, EVERYONE here has been 'bitten' by the 'default' I/O pin assignments at one time or another.....


it's none of those , read 600 pages, plan every pin, see what WILL work, THEN check for default settings... sigh.... too many pins, too many peripherals in PICs these days !

welcome ..lol..

Jay
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 2:31 pm     Reply with quote

I am sorta stuck on the 4550. It is a direct replacement for 16F877 and that fits my upgrade of existing hardware.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 4:46 pm     Reply with quote

Have a look at the 18F46k22 in your spare time... Unless you're using the USB internal peripheral of the 4550, you'll be light years ahead of the game with the 46k22. Yup, I've got 2 tubes of 4550s here, 3 or more of the 877 as well.There isn't anything it hasn't done for me, way 'overkill' for most projects but it does work. Neat stuff like FULL speed at 3 OR 5 volts.
Can run at 64MHz too !

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 5:31 pm     Reply with quote

This discussion isn't solving his problem.
He needs to look in the 18F4550.h file to see what constants are allowed
to setup the analog pins.

Look at the allowable settings below. You are using "ALL_ANALOG".
Look at the comment for that line. It makes pin B0 be analog.
You don't want that. So choose another setting from the list that
gives you the analog pins that you want.
Code:

// Constants used in SETUP_ADC_PORTS() and SET_ANALOG_PINS() are:
// First argument:
#define NO_ANALOGS   0x0F   // None
#define ALL_ANALOG   0x00   // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3 B1 B4 B0     
#define AN0_TO_AN11  0x03   // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3 B1 B4       
#define AN0_TO_AN10  0x04   // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3 B1         
#define AN0_TO_AN9   0x05   // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3             
#define AN0_TO_AN8   0x06   // A0 A1 A2 A3 A5 E0 E1 E2 B2               
#define AN0_TO_AN7   0x07   // A0 A1 A2 A3 A5 E0 E1 E2                   
#define AN0_TO_AN6   0x08   // A0 A1 A2 A3 A5 E0 E1                     
#define AN0_TO_AN5   0x09   // A0 A1 A2 A3 A5 E0                         
#define AN0_TO_AN4   0x0A   // A0 A1 A2 A3 A5
#define AN0_TO_AN3   0x0B   // A0 A1 A2 A3
#define AN0_TO_AN2   0x0C   // A0 A1 A2
#define AN0_TO_AN1   0x0D   // A0 A1
#define AN0          0x0E   // A0
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 7:01 pm     Reply with quote

Ah Yes! thanks guys and thanks PCM programmer, I will look into that tomorrow, you are right do not need all analogs, just the lazy way to turn on what I need.
I will also look at the other chips mentioned for future projects.

thanks all. I will confirm this fixes me tomorrow.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Aug 26, 2016 1:21 am     Reply with quote

What PCM_Programmer has pointed out to you with the printout from the header, is that 'ALL_ANALOGS' sets port B to analog.....

If you are only using port A, then you need to use AN0_TO_AN4, which only enables the five analog pins on port A.

If you look at the PORTB I/O summary table, the second line:
Code:

PORTB<0> data input; weak pull-up when RBPU bit is cleared.
Disabled when analog input enabled(1).


Note the "Disabled when analog input enabled(1)."....

It is _never_ good practice to enable analog pins you are not using. Not only does it do things like this, but it increases analog 'noise' on the other pins. When a pin is selected to feed to the analog input multiplexer, the FET is turned on routing it to the multiplexer, and there is a slight increase in cross-talk to the other analog signals. If you do this with several 'digital' pins, you significantly degrade the analog performance.....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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