|
|
View previous topic :: View next topic |
Author |
Message |
Jack
Joined: 10 May 2007 Posts: 2
|
PIC with two software UARTs |
Posted: Sat May 19, 2007 3:02 am |
|
|
Hi,
I am doing a project with a PIC 16F877A communicating with two sonmicro SM130 modules, each via a seperate software UART. The received response from the modules are to be send to a LCD. Furthermore, I use the debugger to print the response to the compilers monitor.
The problem is:
When I send a command to one of the modules I don't get a response everytime. I experience the same problem when only one module is connected. Has it anything to with the PIC not being able to handle the UART operations fast enough? Should I insert delays between these operations?
Thank you in advance!
Regards, Jack
Here is the code for setting two diodes on on one of the modules via UART2:
#include "C:\Documents and Settings\-\Desktop\Grp4_2\Grp4_2\Grp4\SetOutputPorts_UART2.h"
#include <lcd16216.c>
#include <stdio.h>
#define OFF 0
#define ON 1
#use rs232(stream=UART2,baud=19200, XMIT=PIN_A3, RCV=PIN_A2, parity=N, bits=8, DISABLE_INTS,FORCE_SW, BRGH1OK)
void SetOutputPortsUART2(short output2, short output1) {
char header, reserved, length=0, cmd, data, csum;
char header_str[4],reserved_str[4],length_str[4],str[4],cmd_str[4], data_str[4], csum_str[4];
char csum_tmp;
char ctrl;
ctrl = (output2 << 1) + output1;
//Sending Command
fputc(0xFF,UART2);
fputc(0x00,UART2);
fputc(0x02,UART2);
fputc(0x92,UART2);
fputc(ctrl,UART2);
csum=0x02+0x92+ctrl;
fputc(csum,UART2);
csum=0;
//Receiving response from module:
header=fgetc(UART2);
reserved=fgetc(UART2);
length=fgetc(UART2);
//csum_tmp=length;
cmd=fgetc(UART2);
//csum_tmp|=cmd;
data=fgetc(UART2);
//csum_tmp|=data;
csum=fgetc(UART2);
//Printing to compilers monitor
#use rs232(debugger)
printf("Sendt csum: %x\n",csum);
printf("Header: %x\n",header);
printf("Reserved: %x\n",reserved);
printf("Length: %x\n",length);
printf("Command: %x\n",cmd);
printf("Data: %x\n",data);
printf("Checksum: %x\n\n",csum);
#use rs232(stream=UART2,baud=19200, XMIT=PIN_A3, RCV=PIN_A2, parity=N, bits=8, DISABLE_INTS,FORCE_SW, BRGH1OK)
//Converting to Hex
sprintf(header_str,"%x",header);
sprintf(reserved_str,"%x",reserved);
sprintf(length_str,"%x",length);
sprintf(cmd_str,"%x",cmd);
sprintf(data_str,"%x",data);
sprintf(csum_str,"%x",csum);
//Printing to LCD
clear_lcd();
print_lcd(header_str);
lcd_gotoxy(4,1);
print_lcd(reserved_str);
lcd_gotoxy(7,1);
print_lcd(length_str);
lcd_gotoxy(10,1);
print_lcd(cmd_str);
lcd_gotoxy(1,2);
print_lcd(data_str);
lcd_gotoxy(4,2);
print_lcd(csum_str);
lcd_gotoxy(7,2);
}
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
//Problems with executing one command and also executing the loop:
SetOutputPortsUART2(ON,ON);
while(1) {
SetOutputPortsUART2(ON,OFF);
delay_ms(500);
SetOutputPortsUART2(OFF,ON);
delay_ms(500);
}
} |
|
|
Ttelmah Guest
|
|
Posted: Sat May 19, 2007 4:13 am |
|
|
Read the sticky thread at the top of the forum about how to post code. Your posting has parts missing...
'BRGH10K', and 'FORCE_SW', do nothing. The former, is a fix, for a specific hardware BRG problem, and you are not on the hardware UART pins, so the latter does nothing.
What is your clock rate?. The ability to correctly time things, is totally dependant on this.
Are you actually using interrupts elsewhere in the code?. If not, then having 'DISABLE_INTS', adds extra instructions to the software UART code, which are doing nothing. If you are using interrupts elsewhere, how long are the handlers?. DISABLE_INTS, turns off the interrupts, _during_ the transmission/reception of a single character, to prevent the timings being damaged. However it does nothing 'between' the characters. So, in the example given, if (for instance), an interrupt event triggered between sending the checksum byte, and looking for the return byte, and took longer than 26uSec in total to be handled, then the result _will_ be damaged data in the receive....
Best Wishes |
|
|
Jack
Joined: 10 May 2007 Posts: 2
|
|
Posted: Sat May 19, 2007 6:12 am |
|
|
Thanks for the reply Ttelmah,
My compiler version is 4.013
The clockrate is 20 MHz
I don't use any interrupts elsewhere in the code so I see your point and remove DISABLE_INTS and BRGH10K. Still I can send and receive commands repeately via the UARTs.
Here is a more viewable code:
Code: |
#include "C:\Documents and Settings\-\Desktop\Grp4_2\Grp4_2\Grp4\SetOutputPorts_UART2.h"
#include <lcd16216.c>
#include <stdio.h>
#define OFF 0
#define ON 1
#use rs232(stream=UART2,baud=19200, XMIT=PIN_A3, RCV=PIN_A2, parity=N, bits=8, DISABLE_INTS,FORCE_SW, BRGH1OK)
void SetOutputPortsUART2(short output2, short output1) {
char header, reserved, length=0, cmd, data, csum;
char header_str[4],reserved_str[4],length_str[4],str[4],cmd_str[4], data_str[4], csum_str[4];
char csum_tmp;
char ctrl;
ctrl = (output2 << 1) + output1;
//Sending Command
fputc(0xFF,UART2);
fputc(0x00,UART2);
fputc(0x02,UART2);
fputc(0x92,UART2);
fputc(ctrl,UART2);
csum=0x02+0x92+ctrl;
fputc(csum,UART2);
csum=0;
//Receiving response from module:
header=fgetc(UART2);
reserved=fgetc(UART2);
length=fgetc(UART2);
//csum_tmp=length;
cmd=fgetc(UART2);
//csum_tmp|=cmd;
data=fgetc(UART2);
//csum_tmp|=data;
csum=fgetc(UART2);
//Printing to compilers monitor
#use rs232(debugger)
printf("Sendt csum: %x\n",csum);
printf("Header: %x\n",header);
printf("Reserved: %x\n",reserved);
printf("Length: %x\n",length);
printf("Command: %x\n",cmd);
printf("Data: %x\n",data);
printf("Checksum: %x\n\n",csum);
#use rs232(stream=UART2,baud=19200, XMIT=PIN_A3, RCV=PIN_A2, parity=N, bits=8, DISABLE_INTS,FORCE_SW, BRGH1OK)
//Converting to Hex
sprintf(header_str,"%x",header);
sprintf(reserved_str,"%x",reserved);
sprintf(length_str,"%x",length);
sprintf(cmd_str,"%x",cmd);
sprintf(data_str,"%x",data);
sprintf(csum_str,"%x",csum);
//Printing to LCD
clear_lcd();
print_lcd(header_str);
lcd_gotoxy(4,1);
print_lcd(reserved_str);
lcd_gotoxy(7,1);
print_lcd(length_str);
lcd_gotoxy(10,1);
print_lcd(cmd_str);
lcd_gotoxy(1,2);
print_lcd(data_str);
lcd_gotoxy(4,2);
print_lcd(csum_str);
lcd_gotoxy(7,2);
}
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
//Problems with executing one command and also executing the loop:
SetOutputPortsUART2(ON,ON);
while(1) {
SetOutputPortsUART2(ON,OFF);
delay_ms(500);
SetOutputPortsUART2(OFF,ON);
delay_ms(500);
}
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Sat May 19, 2007 7:02 am |
|
|
OK. The only thing that would cause problems then, is if the device at the other end, begins it's reply _before_ the command is copletely finished. With the software UART,the code must be sitting and waiting for the data to arrive. However the modules you have should not do this.
I'd try issuing a reset, before sending the first set output port packet, and delaying at the start of the code for a significant time before sending anything. If the line floated 'low' during initialisation, there may be a garbage character seen by the module, and I can't remember seeing any specification for how quickly the module 'powers on' after power is applied. Several mSec, may well be needed.
Best Wishes |
|
|
|
|
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
|