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

UART2 Problem: Please help me

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



Joined: 25 Sep 2013
Posts: 18

View user's profile Send private message

UART2 Problem: Please help me
PostPosted: Thu Sep 26, 2013 10:50 pm     Reply with quote

Device :18f46k22
compiler version : 4.108
My goal:
I want to use UART2 to communicate with PC.

problem :
1. When sending a charcter vai pic tx2 pin, PIC is shut down and freezing.
2. Rx2 interrupt is not working.

Help me, Please
Code:

#include <18f46k22.h>
#device *=16 adc=10
//#device pass_strings=in_ram
#FUSES H4   

#use delay(internal=16Mhz,clock=64Mhz,RESTART_WDT,clock_out))   

#use rs232(UART2,baud=19200,stop=1,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8,restart_WDT,errors,stream=SER2)

#ZERO_RAM

#include <stdio.h>

#use fast_io(a)     
#use fast_io(b)     
#use fast_io(c)     

int32 gtemp1=1234567;
long int Delay_time=1000;
int Serial_1=0;
int Serial_2=0;
int Rx1Flag=0;
char RecvChar=null;

#int_rda2
void rda_isr2(void)
{
    RecvChar = getc(); 
    Delay_time = 100;
    Rx1Flag = 1;

}

#int_ext
Void ext_isr(){
         
         if(Delay_time==100)
         Delay_time=1000;
         else
         Delay_time=100;
}


void main()

   SET_TRIS_A(0b00000000);   
   SET_TRIS_B(0b11000001);   
   SET_TRIS_C(0b11000000);   
   SET_TRIS_C(0b11000000);
   //   Port_B_Pullups(TRUE);
 
   disable_interrupts(INT_RB);
   disable_interrupts(INT_AD);     
   
   disable_interrupts(INT_TBE);

   disable_interrupts(INT_CCP1);     
   disable_interrupts(INT_CCP2);     

   disable_interrupts(INT_EEPROM);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_RDA2);
   enable_interrupts(GLOBAL);
   
   while(true){

#byte ANSELA = 0xF38
#byte ANSELB = 0xF39
#byte ANSELC = 0xF3A
#byte ANSELD = 0xF3B
#byte ANSELE = 0xF3C

ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0;

      delay_ms(500);
      gtemp1+=1;

      fprintf(SER2,"UART2=%lu \r\n", gtemp1);
     fputs("----------------",SER2);
   
      if(Rx1Flag==1)   
         {
             fprintf(SER2,"%c \r\n",RecvChar);
              Rx1Flag   = 0;
         }
               
      output_bit(pin_b1,1);   
   //    led=0b000000010;
      delay_ms(Delay_time);         
      output_bit(pin_b1,0);
   //   led=0b00000000;
      delay_ms(Delay_time);         
   
//      Delay_time +=50;
   }
}
temtronic



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

View user's profile Send private message

PostPosted: Fri Sep 27, 2013 5:23 am     Reply with quote

First, have you confirmed that the pIC is running correctly using the '1Hz flashing LED' program?

If so, here's some suggestions...
1) delete this line ...#device *=16 adc=10
not needed with PIC18 series devices

2) delete these lines ...
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)

Let the compiler handle the I/O settings automatically

3)delete these lines...
SET_TRIS_A(0b00000000);
SET_TRIS_B(0b11000001);
SET_TRIS_C(0b11000000);
SET_TRIS_C(0b11000000);
again, let the compiler handle the I/O settings automatically

4) this is 'messy'....
output_bit(pin_b1,1);
// led=0b000000010;
delay_ms(Delay_time);
output_bit(pin_b1,0);
// led=0b00000000;
delay_ms(Delay_time);

// Delay_time +=50;
use the 'toggle' function CCS supplies to 'flash the LED'.At least for test purposes.

5) What is the INT_EXT input ? It could be falsely triggering,causing the PIC to stay in the ISR...I'd disable it ,for test purposes,until you get the serial port running correctly.

The 'trick' is to make the program as small as possible so you can easily work on one section at a time,get it working, then add the next section.

I do use the 46k22 and know the 2nd serial works fine.

Make the changes,maybe more...,test and repost with what happens,we can then help you further.

hth
jay
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 27, 2013 6:17 am     Reply with quote

A few more hints for improving your code:

1)
Code:
#byte ANSELA = 0xF38
#byte ANSELB = 0xF39
#byte ANSELC = 0xF3A
#byte ANSELD = 0xF3B
#byte ANSELE = 0xF3C

ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0;
It is bad practice to have the #byte defines inside the while loop. Move them to the top of your program where you declare the global variables.
Or even better, use:
Code:
setup_adc_ports(NO_ANALOGS);
This single line replaces your 10 lines above, is portable to other processors and a lot easier to read.

2)
Code:
#use rs232(UART2,baud=19200,stop=1,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8,errors,stream=SER2)
Tricky. The pins to use are now defined two times. Just declaring 'UART2' is enough information to specify the 2nd uart. Declaring the xmit and rcv pins is double information with possible future problems when you change 1 item and forget to change the other. Remove either 'UARTx' or remove the pin specifications.

3) Remove all watchdog code. Hardly any device ever requires a watchdog. From experience I can tell you that watchdogs can create hard to find problems. Don't make your programming task harder than it already is. Removing the watchdog also saves someenergy, makes your program smaller and easier to read.

4) Always specify the UART you want to access.
Code:
RecvChar = getc();
This works as long as you have one #RS232 line. But with two RS232 lines it depends on the sequence of declaration.
Better replace by:
Code:
rlRecvChar = getc(SER2);


5) For debugging it helps to make your program as small as possible. Remove all parts not related to the issue at hand so you can make sure not multiple problems are interacting and you can focus on one problem at a time.
For example, the INT_EXT could be interfering. We can't tell as we don't know your hardware connections. Remove it and see if things improve.

Post your improved and cleaned up code here. It should be at least half the size of what you posted now.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 27, 2013 12:34 pm     Reply with quote

Quote:
setup_adc_ports(NO_ANALOGS);

This single line replaces your 10 lines above, is portable to other processors and a lot easier to read.

Not in his version. He has vs. 4.108 and it produces this code for the 18F46K22:
Code:

.................... setup_adc_ports(NO_ANALOGS);
00026:  MOVLW  00     
00028:  MOVWF  F7E   // PIR5 register
0002A:  BCF    FC1.0   // ADCON1.0 bit  = 0
0002C:  BCF    FC1.1
0002E:  BCF    FC1.2
00030:  BCF    FC1.3
00032:  MOVWF  F7F  // IPR5 register

That's not correct code. FC1 is the ADCON1 register. In the 18F46K22,
bits 0 to 3 do not control the analog/digital settings for the ADC ports.
It's done with the ANSELx registers.

Here is the result when it's compiled with vs. 5.012. It's correct:
Code:

.................... setup_adc_ports(NO_ANALOGS);
0002E:  MOVF   FC1,W
00030:  ANDLW  F0
00032:  MOVWF  FC1
00034:  MOVLW  00
00036:  MOVLB  F
00038:  MOVWF  x38  // ANSELA
0003A:  MOVWF  x3C  // ANSELE
0003C:  MOVWF  x39  // ANSELB
0003E:  MOVWF  x3A  // ANSELC
00040:  MOVWF  x3B  // ANSELD

So he does need a work-around for his version.


Quote:

It is bad practice to have the #byte defines inside the while loop. Move
them to the top of your program where you declare the global variables.

I gave him an example of the work-around that shows it as a routine.
http://www.ccsinfo.com/forum/viewtopic.php?t=43961&start=6
He changed it to inline code.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 27, 2013 12:56 pm     Reply with quote

PCM programmer wrote:
Quote:
setup_adc_ports(NO_ANALOGS);

This single line replaces your 10 lines above, is portable to other processors and a lot easier to read.

Not in his version. He has vs. 4.108 and it produces this code for the 18F46K22:

< cut>

I gave him an example of the work-around that shows it as a routine.
http://www.ccsinfo.com/forum/viewtopic.php?t=43961&start=6
He changed it to inline code.
Alright, now makes sense to me. I don't have v4.108 and in v4.141 it looked al-right.

Then here another hint for the original topic starter:
Always write comments in your code! Especially when you have created some code with a special extra condition like here.

By the way: why did Hwryu make the function inline? The version as posted by PCM was way more easy to read.
hwryu



Joined: 25 Sep 2013
Posts: 18

View user's profile Send private message

Thank you for your help
PostPosted: Mon Sep 30, 2013 7:22 pm     Reply with quote

I struggled to solve this problem. Finally I updated compiler to new version 5.012 so that all these problems are solved.
Thank you for your advice.
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