|
|
View previous topic :: View next topic |
Author |
Message |
Prefekt
Joined: 21 Oct 2010 Posts: 85
|
pic18f46k22 uart problem |
Posted: Wed Jun 29, 2016 5:16 am |
|
|
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
|
|
Posted: Wed Jun 29, 2016 8:33 am |
|
|
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
|
|
Posted: Wed Jun 29, 2016 9:50 am |
|
|
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
|
|
Posted: Sat Jul 02, 2016 3:22 am |
|
|
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
|
|
Posted: Sat Jul 02, 2016 4:15 am |
|
|
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. |
|
|
jjcarlospv
Joined: 06 Nov 2016 Posts: 1
|
Solution for Uart problem |
Posted: Sun Nov 06, 2016 7:31 pm |
|
|
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
|
|
Posted: Mon Nov 07, 2016 1:22 am |
|
|
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.... |
|
|
|
|
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
|