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

pic18f46k22 uart problem

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



Joined: 21 Oct 2010
Posts: 85

View user's profile Send private message

pic18f46k22 uart problem
PostPosted: Wed Jun 29, 2016 5:16 am     Reply with quote

I have a pic 18f46k22 with 3 uart definitions.
two uarts with interrupts and one for output data.

If I send data to the stream SIMCOM, everyting is ok. But when I send data, for example 'x#' to the stream DATA, the output on stream PORT1 is:
Quote:
h??????????????!???1???<2>^&QX?aLen: 1
is should be
Quote:
DataLen: ... DataLen: ...


here is my config:
Code:
^
#include <18F46K22.h>
#device ADC=10
#fuses PROTECT, BROWNOUT, PUT, NOLVP, PLLEN, NOFCMEN
#use delay(crystal=10mhz, clock=40mhz, restart_wdt)


//serial interface
#use rs232(stream=DATA,baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#use rs232(stream=SIMCOM,baud=115200,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8,ERRORS)
#use rs232(stream=PORT1,baud=115200,parity=N,xmit=PIN_B5,rcv=PIN_B0,bits=8,ERRORS)

//pin definiton
#define BLINKER PIN_C0           
#define SCT_LA  PIN_A3           //Global latch

//global constants
#define C_TOTAL_LED     1200     
#define C_INP_DATA_LEN  2404     
#define C_START_S1      0       
#define C_START_S2      2400   


and the program:
Code:

#INT_RDA
void rda_isr(void)
{
   NewData=TRUE;
   chr=fgetc(DATA);
}

#INT_RDA2
void rda2_isr(void)
{
   NewSimComData=TRUE;
   Busy=TRUE;
   chrs=fgetc(SIMCOM);
   SimComData[SimComIndex]=chrs;
   
   if(SimComIndex < 12)
     SimComIndex++;
}
/////////////////////////////////////////////////////////////////////////////
//
// Main
//
/////////////////////////////////////////////////////////////////////////////
void main()
{
   delay_ms(1000);
   
   int16 i;
   char strSymbolID[10];
   strcpy(strSymbolID, "SymbolID:");
   char c;
   int1 off=FALSE;
   
 
   //disable led's
   set_pwm1_duty(0xffff);
   
   //InitialData
   for(i=0;i<C_INP_DATA_LEN;i++) { InputData[i]='0'; }
   
   for(i=0;i<12;i++) { SimComData[i]='0'; }
   
   //inidicates witch sign is acutaly shown
   char SignShown=0; 
   
   //Init external eeprom
   init_ext_eeprom();

   //interupt setup
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_RDA2);
   
   //PWM setup
   setup_timer_2(T2_DIV_BY_16,127,1);      //819 us overflow, 819 us interrupt
   setup_ccp1(CCP_PWM);
   
   //Analog setup
   setup_adc_ports(sAN0);
   setup_adc(adc_clock_internal);
   set_adc_channel(0);
 
   isDataOk=TRUE;
   
   //Set pwm start value to*init display data direct
   value=read_adc();
   set_pwm1_duty(value);
   
   InputIndex=0;
   SimComIndex=0;
   while(TRUE)
   {
      if(NewData)
      {
         if(chr!='#')
         {
            InputData[InputIndex]=chr;
            if(InputIndex<C_INP_DATA_LEN)
               InputIndex++;
            NewData=FALSE;
         }
         else
         {
            NewData=FALSE;
            Busy=FALSE;
            if(InputData[0]=='d' && InputData[1]=='d')
            {
               for(i=0;i<32768;i++)
               {
                  c=read_ext_eeprom(i);
                  fputc(c, PORT1);
               }
            }
           
            if(InputData[0]=='e' && InputData[1]=='e')
            {
               fprintf(PORT1, "erase eeprom...\r");
               for(i=0;i<32768;i++)
               {
                  write_ext_eeprom(i, 0);
               }
               fprintf(PORT1, "erase finish.\r");
            }
           
            if(InputData[0]=='x')
            {
               fprintf(PORT1, "DataLen: %Lu", InputIndex);
               fprintf(PORT1, "DataLen: %Lu", InputIndex);
            }
            //Data message S1:[n] -> symbol1
            //Data message S2:[n] -> symbol2
            if(InputData[0]=='S')
            {   
               fprintf(PORT1, "DataLen: %Ld", InputIndex);
               if(InputIndex==C_INP_DATA_LEN-1)
               {
                  isDataOk=TRUE;
                  fprintf(PORT1, "Data OK#");
                 
                  InputIndex=0;
                  SignShown=0;
                                 
                  //Write to external eeprom
                  fprintf(PORT1,"write data to eeprom...#");
                  WriteToEEPROM(InputData[1]);
                  fprintf(PORT1,"finish write data to eeprom...#");
                 
               }
               else
               {
                  fprintf(SIMCOM, "Data NOK#");
                  InputIndex=0;
                  NewData=FALSE;
               }
            }
         InputIndex=0;
         }
      }
     
   }
}
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Wed Jun 29, 2016 8:33 am     Reply with quote

Well, a couple of things to try:

1.) Configure your UARTS for hardware. They probably are hardware but the configuration you chose doesn't always default to that state and can sometimes default to SW on some revs of the compiler:

Code:

#use rs232(stream=DATA,baud=115200,parity=N,UART1,bits=8,ERRORS)
#use rs232(stream=SIMCOM,baud=115200,parity=N,UART2,bits=8,ERRORS)
#use rs232(stream=PORT1,baud=115200,parity=N,xmit=PIN_B5,rcv=PIN_B0,bits=8,FORCE_SW, DISABLE_INTS)

My guess is since PORT1 is a software UART, the interrupts from the one of the others is affecting your output and messing it up. You have to disable interrupts when using the SW UART. This can be problematic for your program though if the other UARTs need to function in the background since disabling interrupts while you print on PORT1 means that neither SIMCOM nor DATA can receive during that time.

2.) This is more of a side note, but do not put restart_wdt in the #use delay() statement. Don't even bother with the watchdog until you got everything else working and then (if you really do need a WDT) manually strobe it where you need to.
Prefekt



Joined: 21 Oct 2010
Posts: 85

View user's profile Send private message

PostPosted: Wed Jun 29, 2016 9:50 am     Reply with quote

thank your for the hints.
I will try this. disable interrupts while using the PORT1 sounds good.

The restart_wdt() is an remain and I will delete it .
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Sat Jul 02, 2016 3:22 am     Reply with quote

Baud rate of 115200 not too high for software rs232 at 40MHz?
Hardware rs232 that worked for me is what I got from PCM programmer:
Code:
#use rs232(baud=9600, UART1, stream=PORT1, errors)
#use rs232(baud=9600, UART2, stream=PORT2, errors)

Tested also with baud=115200 at 32MHz with 18F26K22 and 16F1847.
Can see in the LST if it is hardware or software rs232.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sat Jul 02, 2016 4:15 am     Reply with quote

Hardware.

If you use 'UARTx', then this forces the hardware UART 'x' to be used.

Historically CCS, had two different ways of working with different hardware.

So #USE RS232, selected the hardware, if you used the hardware pins, unless you used 'force_sw'. #USE I2C, defaulted instead to using software, unless you used 'force_hw'.
Could be confusing.

Now a few dozen versions ago, the 'device name' syntax was introduced, and this applies to all peripherals. If you use 'I2Cx' on a #USE I2C, or 'UARTx' on a #USE RS232, this syntax _forces_ the hardware to be selected (also applies to SPI). Better, and safe. It is also the way to go with devices with moveable pins. So on these you use '#PIN SELECT' to set the peripheral pins up, and then the hardware peripheral to talk to it:
Code:

#pin_select TX2=PIN_C0
#pin_select RX2=PIN_C1 //Uart 2 pins selected
#use rs232(baud=9600, parity=N, UART2, bits=8, stream=SOMETHING errors ) //UART2 setup
 
#pin_select SDO2=PIN_B2
#pin_select SDI2=PIN_B1
#pin_select SCK2IN=PIN_D5 
#pin_select SCK2OUT=PIN_D5 //SPI2 pins selected
#USE SPI(SPI2, MODE=0, STREAM=FAST_STREAM) //SPI2 setup

Forces both UART2, and SPI2 to use the hardware.

This is on an 18F47J53, which specifically tells you in the data sheet that both the clock in and out devices _must_ be selected.

Much better. Smile
jjcarlospv



Joined: 06 Nov 2016
Posts: 1

View user's profile Send private message

Solution for Uart problem
PostPosted: Sun Nov 06, 2016 7:31 pm     Reply with quote

Hi guys. I'm not sure if late for posting this but I'd like to share my solution for this problem. I've just solved this with next code.
Code:

#fuses  HSH, PRIMARY_ON, NOPLLEN, NOPROTECT, NOWDT,NOLVP, NOXINST
#use delay(clock=20000000) //cristal de 20MHz
#use rs232(stream=UART_1,baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use rs232(stream=UART_2,baud=9600,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8)

The most important are FUSES...I got a mistake for the fuse NOPLLEN and the transmision of byte were wrong because my SPBRG2 value should be 31 but it didn't work because the PLL was increasing the FOSC ... Terrible!! .. well I hope this info be useful for you.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Mon Nov 07, 2016 1:22 am     Reply with quote

Which is why you will see repeated here hundreds of times the line:
"Do an LED test program and make sure the timing is right".

At the end of the day, nothing is going to work as it should if the clock is not what you expect, so this really is one of the basic tests when switching to a chip using fuses you have not used before....
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