View previous topic :: View next topic |
Author |
Message |
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
RS232 and SPI conflicts? cant work with both at the same tim |
Posted: Thu Mar 06, 2008 10:35 am |
|
|
Need your advice to see what is wrong with my code, it seems to freeze int_rda (rs232) in the Slave after the Master send SPI characters.
I am using PCW 4.065 and PIC18f2520.
Master Code:
Code: |
#include <18F2520.h>
#include <USART_RDA_SPI.c>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
void main() {
char a,b;
delay_ms(300);
set_tris_b(0b00000101);
set_tris_c(0b10010011);
set_tris_a(0b10100000);
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16);
#use delay(clock=20000000)
#use rs232(baud=9600,parity=o,bits=8,xmit=PIN_C6, rcv=PIN_C7)
output_low(pin_b7); //test pin 2
output_low(pin_b6); //test pin 1
output_low(pin_b5);
output_low(pin_b4);
output_low(pin_a3);
output_low(pin_a2);
output_low(pin_a1);
output_low(pin_a0);
enable_interrupts(global);
enable_interrupts(int_rda);
enable_interrupts(INT_SSP);
bputc("\n\r");
printf("Hello World");
bputc("\n\r");
output_high(pin_c2); //test led
delay_ms(200);
output_low(pin_c2); //test led
delay_ms(200);
do {
output_low(pin_c2); //test led
//delay_ms(50);
output_high(pin_c2); //test led
//delay_ms(50);
a=bgetc();
// bputc(a);
bputc("\n\r");
spi_write(a);
delay_ms(15);
b=SPI_read();
bputc(b);
}
while(1);
}//end main
#int_default
default_isr() {
printf("Unexplained interrupt\r\n");
}
|
Slave Code:
Code: |
#include <18F2520.h>
#include <USART1.c>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
void main() {
char a;
set_tris_b(0b00000101);
set_tris_c(0b10011011);
set_tris_a(0b10100000);
setup_spi(spi_slave | spi_L_to_H);
#use delay(clock=20000000)
#use rs232(baud=9600,parity=o,bits=8,xmit=PIN_C6, rcv=PIN_C7)
output_low(pin_b7); //test pin 2
output_low(pin_b6); //test pin 1
output_low(pin_b5);
output_low(pin_b4);
output_low(pin_a3);
output_low(pin_a2);
output_low(pin_a1);
output_low(pin_a0);
output_low(pin_c2);
enable_interrupts(global);
enable_interrupts(int_rda);
enable_interrupts(INT_SSP);
printf(bputc, "Se escribira lo que recibes por SPI");
do {
output_high(pin_c2); //test led
delay_ms(100);
a=bgetc();
bputc("\n\r");
bputc(a);
output_low(pin_c2);
delay_ms(100);
//test led
}
while (1);
}//end main
char c;
#int_SSP
void SPIMANGER() {
c = spi_read();
bputc(c);
spi_write(c);
clear_interrupt(INT_SSP);
}
#int_default
default_isr() {
printf("Unexplained interrupt\r\n");
} |
I am using a software USART to buffer int_rda inputs and trying to develop a function to buffer int_spi |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 06, 2008 1:10 pm |
|
|
Your code has several problems.
This line is in your master code. It will not generate the SPI clock.
You must give it a parameter of 0 (or some other value) to generate
the SPI clock. This should only be done in the Master program. Example:
Quote: | set_tris_b(0b00000101);
set_tris_c(0b10010011);
set_tris_a(0b10100000); |
Here, you are setting the TRIS. But you're not using #fast_io() mode.
This means that compiler will override your TRIS settings above.
The truth is that you don't need to set the TRIS. You don't need those
lines of code. The compiler sets the TRIS automatically, if you use
the CCS library code, or the CCS built-in functions.
Quote: | #use delay(clock=20000000)
#use rs232(baud=9600,parity=o,bits=8,xmit=PIN_C6, rcv=PIN_C7) |
Here, you have placed a 2nd #use delay() statement. What is the reason
for doing this ? It's not needed. Also, normally, the #use rs232()
statement would be placed above main(), and not inside main().
Also, you should add the ERRORS parameter to the #use rs232()
statement. I also see that you're using Odd Parity. Is there a reason
for that ?
Quote: | #include <USART_RDA_SPI.c> |
What code is in this file ?
Quote: | enable_interrupts(global);
enable_interrupts(int_rda);
enable_interrupts(INT_SSP); |
You have enabled INT_SSP interrupts, but I don't see an #int_ssp
interrupt routine in your code. Why did you enable that interrupt
when you don't have an routine to service it ?
Quote: | #int_default
default_isr() {
printf("Unexplained interrupt\r\n");
} |
There should never be any unexplained interrupts. If there are, then
you're doing something wrong, such as enabling interrupts for which you
don't have an interrupt service routine.
You have bputc() statements in your code. This routine is used when
a #int_tbe routine is used. I don't see that routine in your code. |
|
|
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
|
Posted: Thu Mar 06, 2008 2:55 pm |
|
|
Fixed
Quote: |
About SET TRIS
set_tris_b(0b00000101);
set_tris_c(0b10010011);
set_tris_a(0b10100000);
|
I will use:
Quote: |
#use fixed_io (port_inputs=pin_a5, pin_a7...
|
Quote: | #include <USART_RDA_SPI.c> |
Code: |
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
BYTE buffer_SPI[BUFFER_SIZE];
BYTE next_in_SPI = 0;
BYTE next_out_SPI = 0;
BYTE t_buffer[BUFFER_SIZE];
BYTE t_next_in = 0;
BYTE t_next_out = 0;
BYTE t_buffer_spi[BUFFER_SIZE];
BYTE t_next_in_spi = 0;
BYTE t_next_out_spi = 0;
#int_rda
void serial_isr() {
int t;
//output_low(pin_c2);
//delay_ms(100);
//output_high(pin_c2);
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
#int_tbe //Transmiter interrupt
void tserial_isr() {
putc(t_buffer[t_next_out]);
t_next_out=(t_next_out+1) % BUFFER_SIZE;
if(t_next_in==t_next_out)
disable_interrupts(int_tbe);
}
void bputc(char c) { //Send a character
short restart;
int ni;
restart=t_next_in==t_next_out;
t_buffer[t_next_in]=c;
ni=(t_next_in+1) % BUFFER_SIZE;
while(ni==t_next_out);
t_next_in=ni;
if(restart)
enable_interrupts(int_tbe);
}
#int_SSP
void SPI_isr() {
int t_spi;
buffer_spi[next_in_spi]=spi_read();
t_spi=next_in_spi;
next_in_spi=(next_in_spi+1) % BUFFER_SIZE;
if(next_in_spi==next_out_spi)
next_in_spi=t_spi; // Buffer full !!
}
#define bkbhit_SPI (next_in_SPI!=next_out_SPI)
BYTE SPI_getc() {
BYTE c1;
while(!bkbhit_SPI) ;
c1=buffer_SPI[next_out_SPI];
next_out_SPI=(next_out_SPI+1) % BUFFER_SIZE;
return(c1);
}
void spi_putc(char c) { //Send a character
short restart_spi;
int ni_spi;
restart_spi=t_next_in_spi==t_next_out_spi;
t_buffer_spi[t_next_in_spi]=c;
ni_spi=(t_next_in_spi+1) % BUFFER_SIZE;
while(ni_spi==t_next_out_spi);
t_next_in_spi=ni_spi;
if(restart_spi)
enable_interrupts(int_ssp);
}
|
Here I am buffering the inputs for SPI and RS232
Quote: | #int_default
default_isr() {
printf("Unexplained interrupt\r\n");
} |
Is to remove some warnings regarding "disable interrupts to prevent re-entrancy" |
|
|
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
|
Posted: Thu Mar 06, 2008 3:09 pm |
|
|
I uses Odd parity because the PCB which i am interfacing uses Odd parity |
|
|
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
|
Posted: Thu Mar 06, 2008 5:43 pm |
|
|
My main problem is:
1.-I have a board communication to the slave pic via rs232 (int_rda) constantly, it never stops. the slave collect info into a buffer[17]
2.-the master pic request the buffer[17] info to the slave and or send instructions to the slave to send to the final board.
3.-the slave starts collecting the info into the buffer but when the int_ssp is received from the master the slave int_rda is blocked.
Should I disable interrupts when an interrupts is received? or clear interrupt flags maybe? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 07, 2008 11:28 am |
|
|
Quote: | when the int_ssp is received from the master the slave int_rda is blocked. |
Did you add the ERRORS parameter to all of your #use rs232() statements ? You need to do that. |
|
|
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
|
Posted: Fri Mar 07, 2008 2:17 pm |
|
|
Yes, but after I compile it I have a warning "Variable never use it" |
|
|
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
|
Posted: Fri Mar 07, 2008 2:18 pm |
|
|
I use int_rda FAST and it seems to be working |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 07, 2008 3:30 pm |
|
|
temopic wrote: | Yes, but after I compile it I have a warning "Variable never use it" |
That is normal. The compiler adds a variable 'RS232_ERRORS' to contain the data about what errors have occured, and if you don't use it, this warning will be produced. It doesn't matter, but adding 'ERRORS' is essential in the long term, if RS232 problems are to be avoided.
Best Wishes |
|
|
temopic
Joined: 20 Feb 2008 Posts: 27 Location: mexico
|
|
Posted: Sat Mar 08, 2008 1:32 pm |
|
|
Thank you both
Ttelmah and PCM Programmer
you are the best!!!! |
|
|
|