|
|
View previous topic :: View next topic |
Author |
Message |
sri...
Joined: 14 Jun 2010 Posts: 2
|
controller freezes after receiving response from modem. |
Posted: Mon Jun 14, 2010 7:16 am |
|
|
dear frnds,
i have designed a board for sim300 modem with pic18f97j60 controller,with tx(c6),rx(c7),rts(d0) and cts(d1) lines connected to modem,pin g1 and g2 connected to pc.
Using the INT_RDA and INT_RDA2 interrupts in code.Now my problem is as long as i send command at\r pic receives OK and send the response data to pc.When i use any other command other than at\r,the PIC freezes.
please help me in solving the issue,is there any thing related to CTS and RTS lines.any changes required in code for cts and rts lines,i cant eliminate those lines.
Code: |
#include <18F97J60.h>
#device adc=8
#FUSES HS,NOWDT,WDT1,PROTECT
#use delay(clock=22118400,RESTART_WDT)
#use i2c(Master,sda=PIN_D5,scl=PIN_D6,restart_wdt)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stop=1,STREAM=PMU,timeout=1000)
#USE rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,stop=1,parity=n,STREAM=GSM,TIMEOUT=1000)
#byte PORTJ = 0xF88
#byte PORTH = 0xF87
#byte PORTG = 0xF86
#byte PORTF = 0xF85
#byte PORTE = 0xF84
#byte PORTD = 0xF83
#byte PORTC = 0xF82
#byte PORTB = 0xF81
#byte PORTA = 0xF80
char buf[200]={"\0"},buf1[200]={"\0"};
int1 RC_timeout=false;
unsigned int8 waitfor;
#define second (77)
CHAR ctrlZ = 26,b=34;
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#int_timer0
void timer0isr()
{
if (waitfor) --waitfor;
else RC_timeout=true;
}
void ftget_string(char *s, int max, int ticks){
int len;
char c;
waitfor=ticks;
RC_timeout=false;
set_timer0(0);
clear_interrupt(int_timer0);
enable_interrupts(INT_TIMER0);
--max;
len=0;
do{
while(!kbhit(GSM)){
if(RC_timeout){
c=10;
break;
}
}
if (kbhit(GSM))
c=fgetc(GSM);
if ((c>=' ')&&(c<='~'))
if(len<=max){
s[len++]=c;
}
}while(c!=10);
s[len]=0;
disable_interrupts(INT_TIMER0);
}
#INT_RDA
void serial_isr()
{
ftget_string(buf, 200, second);
}
void btget_string(char *s, int max, int ticks){
int len;
char c;
waitfor=ticks;
RC_timeout=false;
set_timer0(0);
clear_interrupt(int_timer0);
enable_interrupts(INT_TIMER0);
--max;
len=0;
do{
while(!kbhit(PMU)){
if(RC_timeout){
c=10;
break;
}
}
if (kbhit(PMU))
c=fgetc(PMU);
if ((c>=' ')&&(c<='~'))
if(len<=max){
s[len++]=c;
}
}while(c!=10);
s[len]=0;
disable_interrupts(INT_TIMER0);
}
#int_RDA2
void serial_isr2(void)
{
btget_string(buf1, 200, second);
}
void main()
{
set_tris_a(0X03);
set_tris_b(0x00);
set_tris_c(0xad);
set_tris_d(0x01);
set_tris_e(0x00);
set_tris_f(0x00);
set_tris_g(0x04);
set_tris_h(0xfd);
set_tris_j(0x00);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0);
set_adc_channel(0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_8);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
while(true)
{
fprintf(GSM,"AT\r");
delay_ms(500);
fprintf(PMU,"Response:%s\r\n",buf);
fprintf(GSM,"AT\r");
delay_ms(500);
fprintf(PMU,"Response:%s\r\n",buf);
fprintf(GSM,"AT\r");
delay_ms(500);
fprintf(PMU,"Response:%s\r\n",buf); // works good till here
fprintf(GSM,"AT+CMGF=1\r"); //hangs which ever command other than at\r is used here
delay_ms(2000);
fprintf(PMU,"Response:%s\r\n",buf);
fprintf(GSM,"AT+CMGS=%c9999999999%c\r",b,b);
delay_ms(2000);
fprintf(PMU,"Response:%s\r\n",buf);
fprintf(GSM,"Modem is working%c",ctrlZ);
delay_ms(5000);
fprintf(PMU,"Response:%s\r\n",buf);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Jun 14, 2010 8:22 am |
|
|
Understand, when INT_RDA fires, is means that _one_ character is waiting in the hardware buffer. Just one.
You then try to get an entire input 'string'. Your code will sit inside the interrupt, and do nothing else, till that happens. It'll miss characters on the other serial, and won't respond to the timer interrupt. This is _not_ the way to use interrupts. Look at ex_sisr, for how to handle a serial interrupt. Your string fetching routines, needs to be in the main code, not the interrupt, looping, polling the buffers, and assembling the strings as needed. Done in the external code, you then can use a timer interrupt to provide a watchdog if required.
As a further comment, INT_RTCC, and INT_TIMER0, are the same interrupt. Use one or the other, not both...
Best Wishes |
|
|
sri...
Joined: 14 Jun 2010 Posts: 2
|
|
Posted: Tue Jun 15, 2010 8:08 am |
|
|
thx Ttelmah,its working with the Ex_sisr routines but i am still not able to understand wat's wrong in my previous code,bcoz it works gud in my last project.
Please if u find time can u tell me why its wrong,still i can get "ok" for "at\r" but not for other commands. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Jun 15, 2010 9:17 am |
|
|
First add the 'errors' keyword to the RS232 definitions. Without this, if characters are not handled, the UART hardware _will_ hang. As already pointed out, if any serial data arrives on one UART, while you are receiving on the other, these won't be handled, and as a result the UART will be hung up....
Second, the timeout won't work. Did the other code possibly have 'high_ints=true'?. If so, then the timer interrupt could have been programmed as a high priority interrupt, allowing the timeout to work.
As written, it is 'poor design'. If it worked, it was 'luck'...
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
|