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 support@ccsinfo.com

Problem when implement ADC, RS-232, Timer0 in Pic16f887

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



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

Problem when implement ADC, RS-232, Timer0 in Pic16f887
PostPosted: Tue May 15, 2012 3:57 am     Reply with quote

Hi all
My project which i'm doing have used ADC, Rs232 and timer 0.
I used timer 0 interrupt to update value temperature from AN0 channel.
and RS-232 to interface with GSM modem.
My code is conflicted when using timer0 (inside timer0 ISR, I update value from ADC channel - AN0 ), RDA interrupt is not working.

I used :
+ pic 16f887
+ PCH version 4.078

and here is mycode :

-- Define in main
Code:

#include <16f887.h>
#include <def_877a.h>
#device *=16 adc=10
#fuses NOWDT, HS
#use   delay (clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,bits=8,stop=1,parity=n)
#include <LCD_DRIVER_4BIT.c>


-- RDA interrupt
Code:

void ngat_rda(void)
{
   char c;
   c=getc();
   //putc(c);
   switch(c)
   {
      case 10: index=0; // bat ki tu LF :ve dau dong
               break;
               
      case 13: kiemtra();// bat ki tu CR    : enter
               break;
               
      default:
               {
                  buffer_gsm[index]=c;
                  index++;
               }
               break;
   }

}


-- timer0 ISR
Code:

#int_timer0
void update_temp()
{
   
   count++;
   if(count==3)
   {
   value_temp =(float)read_adc();
   value_temp = value_temp/2.048;
   delay_ms(100);
   count=0;
   }
}


-- main loop programe
Code:

void main()

{
   
   trisa = 0xFF;
   trisb = 0;
   trisc = 0x80;
   trisd = 0;
   
   portd=0xff;
   porta=0;
   
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(0);
   
   enable_interrupts(global);
   enable_interrupts(int_timer0);
   enable_interrupts(int_rda);
   
   setup_adc_ports(RA0);
   setup_adc(adc_clock_internal);
   set_adc_channel (0);
   delay_ms(100);             

   LCD_init();
   delay_ms(100);
   demo1();
                               
while(1)
   {   
   
    if(check_what==1)
    {
            printf("AT+CMGS=\"0905638093\"");
            putc(13);
            delay_ms(500);
            //printf(" Nhiet do :%3.1f , Gas: %3.1f ",value_temp,value_temp);
            //printf(" Nhiet do , Gas: ");
            printf(" He Thong OK !!! ");
            putc(26);
            delay_ms(1000);
           
            printf("AT+CMGD=1");
            putc(13);
            delay_ms(500);
           
            check_what=0;
         
    }
         
   
    if(value_temp>=35)
    {
       
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Nhiet do cao !!!");
         delay_ms(1000);
       
         printf("AT+CMGS=\"0905638093\"");
         putc(13);
         delay_ms(200);
         printf(" He Thong Qua Nhiet Do Cho Phep !!! ");
         putc(26);
         delay_ms(1000);
             
    }       
    }
}

Pls show mw way to solved problems!
thnks and regards!
_________________
Begin Begin Begin !!!
temtronic



Joined: 01 Jul 2010
Posts: 9170
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue May 15, 2012 5:17 am     Reply with quote

from your code...
#int_timer0
void update_temp()
{

count++;
if(count==3)
{
value_temp =(float)read_adc();
value_temp = value_temp/2.048;
delay_ms(100);
count=0;
}
}

#1 NEVER EVER use floating point functions inside any ISR(they take 'forever'...)

#2 NEVER EVER use delay_xx(nnn) functions inside any ISR(they are HUGE time wasters..)

#3 ALWAYS have very short,fast code inside ALL ISRs.Set flags,capture raw data,reset variables.

#4 in Main, you should do all your setup code before you enable any interrupts.

#5. setup_adc(adc_clock_internal); no....please read the ADC section for correct values for adc setup for your clock value.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue May 15, 2012 5:37 am     Reply with quote

You're breaking the cardinal rule on ISRs.

Do as little as possible. Get in, do what you HAVE to, get out.

In an ISR do NOT:-

(1) Use milli-second delays.
(2) Perform fp maths.

I suggest you reduce your ISR to

Code:

#int_timer0
void update_temp()
{   
   count++;
}

Move every thing else to main().

Always add ERRORS to your RS232 #use.

Its more than likely that the time spent in your ISR is causing the hardware UART to overflow.

Mike
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue May 15, 2012 9:11 am     Reply with quote

Code:

buffer_gsm[index]=c;
                  index++;


is just begging to overflow and corrupt other memory nearby ..........
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Wed May 16, 2012 8:50 pm     Reply with quote

Thank you, temtronic, Mike Walne Smile
I fixed code according to your instructions and it runs correctly.
Thank you, thank you and regards !
_________________
Begin Begin Begin !!!
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Wed May 16, 2012 8:54 pm     Reply with quote

asmboy wrote:
Code:

buffer_gsm[index]=c;
                  index++;


is just begging to overflow and corrupt other memory nearby ..........

Thanks asmboy Smile
This is code to get string data from gms modem.
It uses AT command to interface so that its always beginning and ending with CR LF.
In RDA interrupt, I processed clear index variable with CR or LF.
_________________
Begin Begin Begin !!!
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu May 17, 2012 8:19 am     Reply with quote

The problem is that you don't limit INDEX to size of buffer array
or CHECK that overflow will occur after index++.

What happens if MORE characters are received without line terminator ?

Answer: memory corruption for next data location(s) after buffer allocated size.
CCS compiler does not check in RUNTIME for such things.
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