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 CCS Technical Support

Please help!!!

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



Joined: 25 Jan 2010
Posts: 35

View user's profile Send private message MSN Messenger

Please help!!!
PostPosted: Fri Apr 02, 2010 11:46 am     Reply with quote

I have code which uses eeprom in order to remember the last choice. But when I energize the circuit, sometimes it can't write all the things and also program can't give pwm output. I think program is stuck somewhere. Can anyone help?
Here is my code. It's a little bit long. If anyone wants, I'll try to tell what the whole code does.
Code:

#include <16F876.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Resistor/Capacitor Osc with CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stop=1)

#define use_portb_lcd TRUE       // b portundan veri alincak
#include <lcd.c>                 // lcd.c dosyasini programa dahil et

////////////////////////////////////degisken tanimlamalari///////////////////////////////////////////////////
               
int device;                 //gosterilen cihazi tutan degisken
int device_position;        //gosterilen cihazin pozisyonunu tutan degisken
int16 digital;              //ra1 bacagindaki digital input
float32 voltage;            //ra1 bacagindaki analog input
int16 battery_digital;      //pilin doluluk oraninin dijital karsiligi,pin a2 den okunan analog voltajin digital karsiligi
float32 battery_voltage;    //pin a2 den okunan analog voltaj degeri,pilin bataryasi
int duty_cycles[20]={221,100,92,115,100,106,109,98,91,85,10,30,26,2,5,16,23,21,36,31};   //duty cycle lar
int eeprom_adress;          //eeprom un adresini tutan degisken
char temp1;                 //eeprom kontrol icin cihaz ve pozisyon bilgileri
char temp2;                 //eeprom kontrol icin cihaz ve pozisyon bilgileri
int timer1_flag=0;          //backlight i belli bir sure yanik birakmak icin gerekli degisken
int button_flag=0;          //butonlar uzun sure basili kalirsa,timeout saglamak icin degiskenler
int button_tick=0;          //butonlar uzun sure basili kalirsa,timeout saglamak icin degiskenler
char char_input='0';        //seriporttan alinan karakteri tutan degisken
unsigned int temp;          //rda interrupt i icin degisken
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////// kesme servis rutinleri /////////////////////////////////////////////////////

#int_RDA
void  serialport_incoming_char_interrupt(void)     //klavyeden rs232 uzerinden girilen karakterlerin olusturdugu kesme fonksiyonu
{         
           disable_interrupts(INT_RDA);      //int_rda kesmesini pasif yap
           char_input=getc();                //karakteri al ve girdi degiskenine aktar           
           output_high(pin_c5);              //seriporttan veri gelince led yansin
         
           switch(char_input)
           {
                     
                     case '1':              //girilen karakter '1' ise
                     {       
                              temp=read_eeprom(device);
                              temp=temp+1;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device,temp);
                              break;
                     }
                             
                     case '2':            //girilen karakter '2' ise
                     {
                              temp=read_eeprom(device);
                              temp=temp-1;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster                             
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device,temp);
                              break;
                     }
                     
                     case '3':           //girilen karakter '3' ise
                     {
                              temp=read_eeprom(device);
                              temp=temp+5;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device,temp);
                              break;
                     }
                     
                     case '4':         //girilen karakter '4' ise
                     {
                              temp=read_eeprom(device);
                              temp=temp-5;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device,temp);
                              break;
                     }
                     
                     case '6':                //girilen karakter '6' ise
                     {
                              temp=read_eeprom(device+10);
                              temp=temp+1;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device+10,temp);
                              break;
                     }   

                     case '7':                 //girilen karakter '7' ise
                     {
                              temp=read_eeprom(device+10);
                              temp=temp-1;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device+10,temp);
                              break;
                     }   
                     
                     case '8':                 //girilen karakter '8' ise
                     {
                              temp=read_eeprom(device+10);
                              temp=temp+5;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device+10,temp);
                              break;
                     }
                     
                     case '9':                  //girilen karakter '9' ise
                     {
                              temp=read_eeprom(device+10);
                              temp=temp-5;
                              printf(lcd_putc,"\fduty:%u",temp);        //lcd de duty cycle goster
                              delay_ms(500);
                              printf(lcd_putc,"\f");        //ekrani temizle
                              write_eeprom(device+10,temp);
                              break;
                     }                       

           }   
                     output_low(pin_c5);           //seriporttan veri gelince led yansin
                     char_input='0';                   
}


#int_TIMER1
void  TIMER1_interrupt(void)
{
      timer1_flag=timer1_flag+1;          //timer1 her tastiginda timer1_flag ve button_tick guncellensin
      button_tick=button_tick+1;
     
      if(timer1_flag==20)                 //timer1_flag 20 olunca,backlight sonsun.
         {
              timer1_flag=0;
              output_low(pin_b3);
         }
      else;
     
     
      if(button_tick==25)                 //timer1 10kere tasinca,buton basili ise diger state e gec.
         {
              button_flag=1;
              button_tick=0;              //button_tick i update et.
         }
      else;
     
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);     //timer1 i tekrar ayarla.   
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////fonksiyon tanimlamalari/////////////////////////////////////////////////////
               
int8 my_read_eeprom(int8 Address)             //e2prom dan veri okuyan fonksiyon
{
      return read_eeprom(Address);
}

void my_write_eeprom(int8 Address,int8 Value)     //e2prom a veri yazan fonksiyon
{
      write_eeprom(Address, Value);
}

void calibration_check(void)   //kalibrasyon ledinin yanip yanmayacagini kontrol eden fonksiyon
{

      set_adc_channel(1);           //1 nolu analog pin adc cevriminde kullanilacak
      delay_us(20);
      digital=read_adc();               //analog veriyi oku,digital olarak digital_a1 degiskeninde sakla
      voltage=digital*((float)5)/1024;  //5/1024=0.0048828,her adim 0.0048828 lik degere sahip ve 1024 adim var

       if(voltage<=2.55)             //IR ledini yakmak icin gerekli kisim
       {
         printf(lcd_putc,"\f");
         while(1)
         {
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Dusuk");
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Isik!!!");
         output_high(pin_b3);      //backlight i yak
         timer1_flag=0;            //butona basildi ise,backlight tekrardan 20sn yansin.
         set_pwm1_duty(0);
         
                     set_adc_channel(3);           //3 nolu analog pin adc cevriminde kullanilacak
                     delay_us(20);
                     battery_digital=read_adc();               //analog veriyi oku,digital olarak digital degiskeninde sakla
                     battery_voltage=battery_digital*((float)5)/1024;;          //     5/1024=0.0048828
                     
                     if(battery_voltage>=0 && battery_voltage<=1)
                     {
                           lcd_gotoxy(1,1);
                           printf(lcd_putc,"\fPil");
                           lcd_gotoxy(1,2);
                           printf(lcd_putc,"Bitti!"); 
                           output_low(pin_b3);      //backlight i yak
                           timer1_flag=0;           //butona basildi ise,backlight tekrardan 20sn yansin.
                           while(1);
                     }
         }
       }
     
     
      else if(voltage>=3.15)
      {
         printf(lcd_putc,"\f");
         while(1)
         {
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Yuksek");
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Isik!!!");
         output_high(pin_b3);      //backlight i yak
         timer1_flag=0;            //butona basildi ise,backlight tekrardan 20sn yansin.
         set_pwm1_duty(0);

                     set_adc_channel(3);           //3 nolu analog pin adc cevriminde kullanilacak
                     delay_us(20);
                     battery_digital=read_adc();               //analog veriyi oku,digital olarak digital degiskeninde sakla
                     battery_voltage=battery_digital*((float)5)/1024;;          //     5/1024=0.0048828
                     
                     if(battery_voltage>=0 && battery_voltage<=1)
                     {
                           lcd_gotoxy(1,1);
                           printf(lcd_putc,"\fPil");
                           lcd_gotoxy(1,2);
                           printf(lcd_putc,"Bitti!");   
                           output_low(pin_b3);      //backlight i yak
                           timer1_flag=0;           //butona basildi ise,backlight tekrardan 20sn yansin.
                           while(1);
                     }
         }

      }
     
      else;
}

void battery_check(void)  ///// pil durumunu olcen fonksiyon
{
      set_adc_channel(3);           //3 nolu analog pin adc cevriminde kullanilacak
      delay_us(20);
      battery_digital=read_adc();               //analog veriyi oku,digital olarak digital degiskeninde sakla
      battery_voltage=battery_digital*((float)5)/1024;;          //     5/1024=0.0048828
   
      if(battery_voltage>4 && battery_voltage<=5)
      {
            lcd_gotoxy(6,2);
            printf(lcd_putc,"B:5");
      }
     
      else if(battery_voltage>3 && battery_voltage<=4)
      {
            lcd_gotoxy(6,2);
            printf(lcd_putc,"B:4");
      }
     
      else if(battery_voltage>=2 && battery_voltage<=3)
      {
            lcd_gotoxy(6,2);
            printf(lcd_putc,"B:3");
      }
     
      else if(battery_voltage>=1 && battery_voltage<=2)
      {
            lcd_gotoxy(6,2);
            printf(lcd_putc,"B:2");
      }
     
      else if(battery_voltage>=0 && battery_voltage<=1)
      {
            lcd_gotoxy(6,2);
            printf(lcd_putc,"B:1");
      }
}



void duty_high_position(void)
{
       my_write_eeprom(21,device_position);
       set_pwm1_duty(read_eeprom(device));
       lcd_gotoxy(1,2);
}



void duty_low_position(void)
{
       my_write_eeprom(21,device_position);
       set_pwm1_duty(read_eeprom(device+10));
       lcd_gotoxy(1,2);
}




void position_counter()
{
              if (!input(pin_a4))
              {
                        delay_ms(25);         // Butona basilinca meydana gelen arkin etkisini önlemek için verilen gecikme
                        device_position=device_position+1;           // cihaz degeri 1 arttiriliyor
                        output_high(pin_b3);      //led in backlight ini yak
                        timer1_flag=0;            //butona basildi ise,backlight tekrardan 20sn yansin.
                        button_flag=0;                       
                        while(!input(pin_a4) && !button_flag);     //butondan el cekilene kadar ve timeout saglaninca
                                         
                        if (device_position==2)            // cihaz degeri test ediliyor.i degeri 10 olunca sifirlaniyor.
                        {
                                 device_position=0;       // pozisyon 2 olunca,degeri sifirlaniyor
                        }
                   
              }
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////







/////////////////////////////////////////     ana program    //////////////////////////////////////////////
                 
                 
void main()
{
   setup_adc_ports(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_INTERNAL); 
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DIV_BY_16,255,1);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   setup_ccp1(CCP_PWM);                     
   set_pwm1_duty(0);



   set_tris_a(0xff);             //a portu tamamen giris
   set_tris_b(0x00);             //b portu tamamen cikis
   set_tris_c(0xf0);             //c7 c6 c5 c4 ve c0 giris;c3 c2 ve c1 cikis (cikisler pwm icin,girisler rx ve tx icin)
 
   lcd_init();                   //lcd yi initialize et
   delay_ms(250);
   
   output_low(pin_c5);             // RC5 çıkışı ilk anda sıfırlanıyor,seriporttan veri geldigini bu pine bagli ledden anlayacagiz
   output_high(pin_b3);            //led in backlight ini yakmak icin
   lcd_gotoxy(1,1);
   printf(lcd_putc,"\fASELSAN "); // baslangic noktasini gormek icin meraba yaz
   lcd_gotoxy(1,2);
   printf(lcd_putc," PGGTC  ");
   delay_ms(2500);
   printf(lcd_putc,"\f");
   
   
   
   
   temp1=my_read_eeprom(50);   //e2prom da 50. adresi oku,'X' gorursen gec,deilse baslangic degerleri yaz
   
   if(temp1!='X')   
   {
      for(eeprom_adress=0;eeprom_adress<20;eeprom_adress++)        //yuksek cycle degerleri 2-12. adreslere yaziliyor
             my_write_eeprom(eeprom_adress,duty_cycles[eeprom_adress]);
             
      my_write_eeprom(50,'X');  //bi kere e2prom initialize olsun,bi daha buraya girmesin program
   }
               
   else;       




   temp2=my_read_eeprom(51);  //e2prom da 51. adresi oku,'X' gorursen gec,deilse baslangic degerleri yaz
   
   if(temp2!='X')
   {
         device=0;           //'X' görmezsen cihaz ilk kez baslamis demek,ilk baslangic 1. cihaz olsun
         device_position=0;  //ve ilk pozisyonda yuksek pozisyon olsun
         
         my_write_eeprom(51,'X');    //bi kere e2prom initialize olsun,bi daha buraya girmesin program     
   }
   
   else
   {
         device=my_read_eeprom(20);       //daha sonra cihaz nerde ve hangi konumda kaldi ise ordan devam etsin
         device_position=my_read_eeprom(21);
   }

     


   
   while(1)           //sonsuz dongu,program bu dongu icinde calisacak
   
   {     
   
/////////////////////////////////// cihaz secimi ve ona gore duty ayari /////////////////////////////////
     
      enable_interrupts(INT_RDA);
     
      if (!input(pin_a2))
      {
         delay_ms(25);            // Butona basilinca meydana gelen arkin etkisini önlemek için verilen gecikme
         device=device+1;          // cihaz degeri 1 arttiriliyor
         output_high(pin_b3);      //led in backlight ini yak
         timer1_flag=0;            //butona basildi ise,backlight tekrardan 20sn yansin.
         button_flag=0;
         while(!input(pin_a2) && !button_flag);    //butondan el cekilene kadar ve timeout saglaninca
                 
         if (device==10)             // cihaz degeri test ediliyor.i degeri 10 olunca sifirlaniyor.
         {
            device=0;              // cihaz 10 u gecince,cihaz degeri sifirlaniyor
         }
      }

         
         switch(device)
         {
     
            case 0:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M929    ");
               
               position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y4/1 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"D2/4 ");
                                      break;
                     }
                     
              break;
            }
     

            case 1:
            { 
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M929A   ");
               
               position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y4/1 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"D2/4 ");
                                      break;
                     }
                     
              break;
           
            }   


            case 2:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M978    ");
               
                    position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y4/4 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"DN/A ");
                                      break;
                     }
                     
              break;
 
            }
     
           
            case 3:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M978A   ");
               
                   position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y4/5 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"D2/3 ");
                                      break;
                     }
                     
              break;
 
            }
     
     
            case 4:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M983    ");
               
                    position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y4/1 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"D2/4 ");
                                      break;
                     }
                     
              break;
 
            }
           
           
            case 5:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M983A   ");
               
                    position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y4/2 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"D2/6 ");
                                      break;
                     }
                     
              break;
 
            }
           
           
            case 6:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M993    ");
               
                   position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y5/6 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"DN/A ");
                                      break;
                     }
                     
              break;
 
            }
           

            case 7:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M993A   ");
               
                   position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y6/1 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"D2/1 ");
                                      break;
                     }
                     
              break;
 
            }
           

            case 8:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M995    ");
               
                  position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y6/2 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"DN/A ");
                                      break;
                     }
              break;
 
            }
           
               
            case 9:
            {
               my_write_eeprom(20,device);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"M995A   ");
               
               position_counter();
                   
                    switch(device_position)
                    {
                               case 0:duty_high_position();
                                      printf(lcd_putc,"Y6/3 ");
                                      break;
                                           
                               case 1:duty_low_position();
                                      printf(lcd_putc,"DN/A ");
                                      break;
                     }
              break;
 
            }
     
         }  // switch in sonu
     
 //////////////////////////////////////////////////////////////////////////////////////////
                 
////////////////////////////////////pil durumu olcumu /////////////////////////////////////
                                                     
      battery_check();
                   
         
////////////////////////////////// kalibrasyon ledi ile ilgili kisim /////////////////////////
                 
      calibration_check();
     
/////////////////////////////////////////////////////////////////////////////////////////////     
         
   }     //while in sonu
     
}        //main in sonu

_________________
compiler version: 4.105
pic: 16f876
clock frequency: 4MHz
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Apr 02, 2010 12:17 pm     Reply with quote

I haven't studied all your code, it is too large. But a few things came to my attention:

Code:
setup_spi(SPI_SS_DISABLED);
This is a bug in the CCS setup wizard and creates an invalid hardware configuration. To disable SPI you should change it to:
Code:
setup_spi(FALSE);


Interrupt routines should be as fast as possible to make sure you don't miss events. For this reason never use a delay_ms or printf call inside an interrupt.

Code:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stop=1
Add the 'errors' directive. Without this directive the hardware UART will stall on receiving more than 3 characters and never start receiving again. With your 500ms delay routines it is very likely you got yourself into this situation.

Always post your compiler version number!!
memoally



Joined: 25 Jan 2010
Posts: 35

View user's profile Send private message MSN Messenger

PostPosted: Fri Apr 02, 2010 4:28 pm     Reply with quote

Thank you ckielstra.
I solved my problem but I did not apply your advices, but of course I will add Smile
I don't know how to use ''errors'' directive. Could you give an example?

delay_ms parts are necessary, so how could I change it?

My compiler version is 4.105
_________________
compiler version: 4.105
pic: 16f876
clock frequency: 4MHz
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Apr 04, 2010 6:36 am     Reply with quote

Quote:
I don't know how to use ''errors'' directive. Could you give an example?
RTFM
Code:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stop=1, ERRORS)


Quote:
delay_ms parts are necessary, so how could I change it?
Normally you would only set a flag in your interrupt routine and then in the main function you would test the flag and act upon it. This way you create an event driven system which is easy to maintain and extend.
To modify your program for this is a major rewrite but in my opinion the only way to make your program stable.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Sun Apr 04, 2010 10:15 am     Reply with quote

The easiest way to get rid of the delay_ms, in the interrupts, is to use your existing timer interrupt.
Can't be bothered to calculate how often this ticks, but (for example), if this ticks every 60mSec for example, then have something like this:
Code:

//Have a global 'tick' variable
int8 tick=0;

//Inside the timer interrupt, add something like:
if (tick) {
   //Only get here if tick is _non zero_
   --tick;
   //Now if 'tick' has _gone_ to zero
   if (tick==0) {
       printf(lcd_putc,"\f");        //ekrani temizle
       write_eeprom(device,temp);
       output_low(PIN_C5);
   }
}


Then in your RDA interrupt, after sending the first string, when you want to wait for 500mSec, just set 'tick' to the number of counts of the timer interrupt that this needs, and get rid of dropping C5, in the RDA code.

Now, this is not a truly elegant way of doing this, but will solve a _lot_ of problems. As it stands, interrupts will be disabled in all delays in the 'main' code, leading to large gaps in the scanning of incoming data etc...

Get rid of disabling INT_RDA in the interrupt code. There is no point in this at all. Enable INT_RDA once at the start of main, and don't have the enable in the while loop.

ERRORS is documented in #use RS232.
The key point is that if characters arrive, and are _not handled_, this locks up the RS232 hardware. This _will_ happen with your code, if characters arrive at any speed. ERRORS adds the code to clear this. It should _allways_ be used with the hardware UART, unless you are manually adding your own code to handle this.

Best Wishes
asmboy



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

View user's profile Send private message AIM Address

am i the only one to notice ??
PostPosted: Wed Apr 07, 2010 9:26 am     Reply with quote

HOW TERRIBLY risky the RDA interrupt handler is written?
did u calculate the total time in msec U have between streaming chars at your baud rate ? and c if what u wrote in worst case can EXECUTE in less than one "character time" ?

when u start adding the delays for accessing
EEPROM especially and making decisions INSIDE the handler
with INTS off - this code has HUGE potential for bad real time misbehavior.

IMB
way better to run a circular buffer - load IT from thr INT handler
fast and efficient and
THEN process what you get in MAIN as read data is available

overloading your handler in the time domain is just plain risky dude!
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Wed Apr 07, 2010 12:14 pm     Reply with quote

I very very very strongly recommend you take asmboy's advice it will serve you well.
Any isr should be as short as possible but for async communications it is almost mandatory to set up a circular buffer. Another approach might work but might or most often isn't a robust solution.
memoally



Joined: 25 Jan 2010
Posts: 35

View user's profile Send private message MSN Messenger

PostPosted: Fri Apr 09, 2010 12:01 pm     Reply with quote

Guys thank you for your advices...

Asmboy, I did not understand what you mean by
Quote:

when u start adding the delays for accessing
EEPROM especially and making decisions INSIDE the handler
with INTS off - this code has HUGE potential for bad real time misbehavior.

because of my bad english, sorry for that.

Actually there is a bad behaviour of my circuit in which it sometimes goes into an unidentified state and then stays there forever, and I could not find how to fix it. I think some errors occur in eeprom part, but so far I could not fix this. It stucks somewhere on the code, for example I could not see device position parts sometimes, and also because lack of this part, PIC does not give pwm output.


I also did not understand what is the problem on ''int rda''. Could you change my code with your advices??


I think it will be good if i try to tell what i am aiming.here it is;


-Battery measurement
-Calibration control (only measures a pin - whether it is below 2.55 volts or above 3.17 volts)
- Recognizes 10 different devices and generates 2 different duty cycles for each device, one is low duty cycle and other is high duty cycle.

There are 2 buttons. One is for choosing device (10 device exist) and other is for choosing the position, duty high or duty low positions. And all of the stuff will be displayed on a 8x2 lcd display.

I initially put this duty cycles into eeprom and program reads it. I am also supposed to change this initial duty cycles via serial port. In RDA_interrupt service routine I tried to read the data first and update it according to the character which is entered from the keyboard.

I want pic to work where it was closed. I mean think about you power off the pic when the device 4 is selected, and when you power up pic again, it should start from device 4 not device 1.
_________________
compiler version: 4.105
pic: 16f876
clock frequency: 4MHz
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