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

18F4550 USB connection and the problem int_rda

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



Joined: 19 Jan 2010
Posts: 9

View user's profile Send private message Send e-mail

18F4550 USB connection and the problem int_rda
PostPosted: Sat Jun 09, 2012 2:46 am     Reply with quote

Hello friends,
I am working on a project. 18F4550 with USB connectivity, 4x20 LCD, a channel ADC, temperature sensor DS18B20 UFM-m11 with the rf module and that I'm using udea company. Rf module, everything works except for the project. Communicates with the pc via usb circuit with C #. RF module receives power circuit module according to the quality pice 3 bytes "$ BC" is sending data. But that pic is two bytes. Aldıklarıda is wrong datas or data that the first two are correct. 3. data that does not never. Codes below. Meanwhile, strong rf module. 16f628a-related circuit with another circuit "$ BC" comes datas. What is the problem. Please help, I'm about to go haywire.

Code:

#include <18F4550.h>
#device ADC=10                  //10 bit adc kullanılacak.
#include <math.h>
#fuses HSPLL,USBDIV,PLL5,NOPUT,CPUDIV4,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG,MCLR

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STOP=1) // RS232 protokolünün 9600 bit/sn baud hızında olacağını ve
                                                                  // TX,RX uçlarının hangi pinler olacağını tanımlıyor
                                                                  // parity bitinin olmadığını, stop bitinin 1 bit olacağı belirtiliyor
#use fast_io(a)                              //Bu komut satırı yazılmazsa ADC çalışmıyor.
#define USB_HID_DEVICE     FALSE             //İnsan arabirim devresi için burası TRUE olacak ve
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for IN yığın/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for OUT yığın/interrupt transfers 
#define USB_EP1_TX_SIZE    10                //Uçnokta1 için maksimum alınacak ve gonderilecek
#define USB_EP1_RX_SIZE    10                //veri boyutu (32 byte)

#include <Master_LCD420.c>
#include <my_DS18B20.c>       //my_DS18B20.c dosyası programa dahil edildi.
#include <pic18_usb.h>                       //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <MY_USB_Device.h>                   //USB configuration and descriptors for this project
#include <usb.c>                             //handles usb setup tokens and get descriptor reports

#define USB_CON_SENSE_PIN PIN_D2             // wired as above

#define UcNokta1       1
#define Komut  gelen_paket[0] 
#define param1 gelen_paket[1]

//Komutlar
#define LED_Komutu       0x01
#define Role_Komutu      0x02
#define ADC_Komutu       0x03
#define Motor_ISI_Komutu       0x04
#define yesil_LED    PIN_D1
#define kirmizi_LED  PIN_D0
#define role  PIN_E0
#define LED_ON  output_high
#define LED_OFF output_low

char   veri[30];
float body_temp,gerilim;//,ADC_deger1=0;              //float 32 bitlil ondalıklı sayıyı ifade eder.
unsigned int16 ADC_deger1 = 0;
unsigned int8 veri_a,veri_b,isi_a,isi_b; //ADC nin ADRESL ve ADRESH baytları

#byte SPBRGH=0xFB0
#byte SPBRG=0xFAF
#byte BAUDCON= 0xFB8
#byte TXSTA=0xFAC
#byte RCSTA=0xFAB
#bit TXEN= TXSTA.5
#bit SYNC=TXSTA.4
#bit SENDB=TXSTA.3
#bit BRGH=TXSTA.2
#bit SPEN=RCSTA.7
#bit BRG16=BAUDCON.3
//******************************************************************************
#int_rda   // RX ucuna veri gelince meydane gelen kesme
void rda_isr()
{
   disable_interrupts(int_rda); // int_rda kesmesini pasif yap
   output_high(pin_d0);  // RC5 çıkışı lojik-1
   output_high(pin_d1);  // RC5 çıkışı lojik-1
   
   //gets(veri);
   veri[0]=getchar();
   write_eeprom(0,veri[0]);
   veri[1]=getchar();
   write_eeprom(1,veri[1]);   
   veri[2]=getchar();
   write_eeprom(2,veri[2]);   

   if ((veri[0]==36)&&(veri[1]==67)&&(veri[2]==79))   //$CO geldi ise, kanal değişiklik onay bilgisi gelmiştir.
   {
         output_low(pin_d0);  // RC5 çıkışı lojik-1   
   }
   clear_interrupt(int_rda);
   //disable_interrupts(int_rda);   
   enable_interrupts(int_rda); //serial işlemi bitince bu kesme aktif yapılmakta.
}
//*********************************ADC OKUNUYOR*********************************
unsigned int16 ADC_Oku(int8 kanal)
{
   unsigned int16 olcum=0;
   set_adc_channel(kanal);    //RA0/AN0 ucundaki analog sinyal 10 bit A/D işlemine tabii tutulacak.
   delay_us(20);              //Kanal seçiminden sonra mutlaka 20us beklenmeli.
   olcum = read_adc();        //AN0 girişindeki analog sinyal okunup dijitale çevrildi. olcum isimli değişkene atıldı.
   return olcum;
}
//***************************LED TERSLE*****************************************
void tersle()
{
   output_toggle(pin_D0);
   delay_ms(500);
}
//******************************************************************************
void isi_oku()
{
   body_temp=ds1820_read();   //Isı sensöründen sıcaklık bilgisi okunup body_temp değişkenine aktarılıyor.
}
//****************************KALAN SÜRE HESAPLANIYOR***************************
void user_init(void)
{
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_DIV_16); 
   
   set_tris_a(0b00000001);    //PORTA0 analog giriş, diğerleri çıkış yapıldı.
   set_tris_b(0b00010000);    //PORTB4 boot butonu nedeniyle giriş
   set_tris_c(0b10000000);    //PORTC İLK 3 PİN ÇIKIŞ DİĞERLERİ GİRİŞ
   set_tris_d(0b00000100);    //PORTD ÇIKIŞ
   set_tris_e(0x00);    //PORTE ÇIKIŞ 
   output_b(0b00000000);      //   
   output_c(0x00);
   output_d(0b00000000);   //ISD nin Play ucuna başalngıçta 1 verip çalmasını engelliyoruz.   
   output_a(0x00);     
   output_e(0x00);
   lcd_init(); // lcd hazırlık     
}
//******************************************************************************
void main(void)
{
   byte sayac=0;
   byte gelen_paket[10];               //gelen paket
   byte gond_paket[10];                //gönderilecek paket
   //Sistemi başlat
   user_init();
   
//   TXEN=1;  //Transmit enabled
   SYNC=0;  //Asynchronous mode
   SPBRGH=0;
   SPBRG=25;   //HSPLL FREKANSI CPUDIV AYARINDAN DOLAYI 6 YA BÖLÜNDÜĞÜNDEN PİCİN ÇALIŞMA FREKANSI 16MHz OLMUŞ OLUYOR.       
   BRG16=0; //8-bit Baud Rate Generator – SPBRG only (Compatible mode), SPBRGH value ignored
   BRGH=0;  //Low speed
//   SPEN=1;  //Serial port enabled (configures RX/DT and TX/CK pins as serial port pins)

   usb_init();                         //USB Başlatılıyor.
   usb_task();                         //USB çevre birimleri ve kesmeleri etkin

   clear_interrupt(int_rda);
   enable_interrupts(int_rda); // int_rda kesmesi aktif, USART arabirim kesmesi aktif.
   enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver
   
   printf("%c%c%c",0x24,0x43,0x30);    //UFM-M11 için 0. kanal seçildi. Kanal 0: 433,05 MHz
   //UFM-M11 kanal değişiklik onay bilgisi olarak 0x24,0x43,0x4F yani $CO gönderir.
   
   while(1)
   {
      //output_low(pin_d1);         //USB bağlantısı yokken d0 lojik0 olur.
      //tersle();
      isi_oku();
      ADC_deger1=ADC_Oku(0);
      veri_a=make8(ADC_deger1,0);//ADC nin ADRESL baytı elde edildi.
      veri_b=make8(ADC_deger1,1);//ADC nin ADRESH baytı elde edildi.
      gerilim=ADC_deger1*0.01956; //10 bit çözünürlük ve max.20V DC ölçülüyor. Bu nedenle 0.01956 ile çarpıldı.
      lcd_gotoxy(1,4);
      printf(lcd_putc,"Vucut Isisi: ");       
      lcd_gotoxy(1,3);
      printf(lcd_putc,"Nabiz: ");       
      lcd_gotoxy(1,2);
      printf(lcd_putc,"Motor Isisi: %4.1f%cC ",body_temp,223);     
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Aku Voltaji: %2.1fV",gerilim);     

   while((usb_enumerated())&& (input(USB_CON_SENSE_PIN)==1))          //Cihaz PC tarafından tanınmışsa (yapılandırılmışsa)
      {
         //output_high(pin_d1);         //USB bağlantısı kurulduğunda d0 lojik1 olur.
           if (usb_kbhit(UcNokta1))             //Eğer pc'den yeni bir paket geldiyse
         {
            usb_get_packet(UcNokta1, gelen_paket, 10); //paketi oku

             switch(Komut)
             {
               case LED_Komutu:  //#define LED_Komutu       0x01
                  if (param1 == 0) {LED_ON(yesil_LED);};               
                  if (param1 == 1) {LED_OFF(yesil_LED);};
                  if (param1 == 2) {LED_ON(kirmizi_LED);};
                  if (param1 == 3) {LED_OFF(kirmizi_LED);};
                  break;
               case Role_Komutu:  //#define Role_Komutu       0x02
                  if(param1==1){output_bit(role,1);};
                  if(param1==0){output_bit(role,0);};
                  break;
               case ADC_Komutu:  //#define ADC_Komutu       0x03
                  ADC_deger1=ADC_Oku(0);
                  gond_paket[0] =  Komut;
                  gond_paket[1] = veri_a; //ADC nin ADRESL baytı pc ye gönderilior.
                  gond_paket[2] = veri_b; //ADC nin ADRESH baytı pc ye gönderilior.
                  sayac = 0x03;
                  break;   
               case Motor_ISI_Komutu:  //#define Motor_ISI_Komutu   0x04
                  isi_a=floor(body_temp);
                  body_temp=ds1820_read();
                  gond_paket[0] =  Komut;
                  gond_paket[1] =  isi_a;
                  gond_paket[2] =  isi_b;
                  sayac = 0x03;
                  break;                 
             
               default: ; break;
             }

               
         }
         if(sayac!=0)
         {
         usb_put_packet(UcNokta1, gond_paket, sayac, USB_DTS_TOGGLE);
         sayac = 0;
         Komut = 0;
         }
      }
   }
}
temtronic



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

View user's profile Send private message

PostPosted: Sat Jun 09, 2012 4:58 am     Reply with quote

first....
You must add 'errors' to the uses rs232(...options). This will prevent UART 'stalling' ot 'lockup'.

try with that modification and report back...
ckielstra



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

View user's profile Send private message

PostPosted: Sat Jun 09, 2012 5:57 am     Reply with quote

Code:
#byte SPBRGH=0xFB0
#byte SPBRG=0xFAF
#byte BAUDCON= 0xFB8
#byte TXSTA=0xFAC
#byte RCSTA=0xFAB
#bit TXEN= TXSTA.5
#bit SYNC=TXSTA.4
#bit SENDB=TXSTA.3
#bit BRGH=TXSTA.2
#bit SPEN=RCSTA.7
#bit BRG16=BAUDCON.3
Remove all this and related code. The CCS compiler will configure these registers for you in the #use RS232 line.
If you don't trust the compiler, then have a look at the list file (*.lst) and compare with your settings.

Code:
set_tris_a(0b00000001);    //PORTA0 analog giriş, diğerleri çıkış yapıldı.
   set_tris_b(0b00010000);    //PORTB4 boot butonu nedeniyle giriş
   set_tris_c(0b10000000);    //PORTC İLK 3 PİN ÇIKIŞ DİĞERLERİ GİRİŞ
   set_tris_d(0b00000100);    //PORTD ÇIKIŞ
   set_tris_e(0x00);    //PORTE ÇIKIŞ
Normally you don't have to set the TRIS registers as the CCS compiler will set them for you on every I/O operation. Only in special situations where you need the maximum speed you can choose to set the TRIS registers yourself, but that is in the end of your project when you are optimizing. You then have to overrule the compiler by defining fast_io for these ports. Now you have only defined fast_io for port_A, this is not consistent. Either set fast_io for all ports, or set only the TRIS register for the fast ports.

Code:
void rda_isr()
{
   disable_interrupts(int_rda); // int_rda kesmesini pasif yap
...
enable_interrupts(int_rda); //serial işlemi bitince bu kesme aktif yapılmakta.
Not an error but unnecessary code. Once you are in the interrupt handler the PIC hardware will have disabled the global interrupt flag. Hence, no other interrupts can occur and it doesn't make any sense to add extra code for disabling/enabling the interrupt.
Also, the interrupt will be cleared by reading the character from the UART. Calling clear_interrupt(int_rda) from inside the ISR is therefor wrong; if a second character is waiting to be read you will remove it with this call and loose the character.

Just a few more hints for writing more readable programs:
Code:
if ((veri[0]==36)&&(veri[1]==67)&&(veri[2]==79))   //$CO geldi ise, kanal değişiklik onay bilgisi gelmiştir.
can be replaced by
Code:
if ((veri[0]=='$')&&(veri[1]=='C')&&(veri[2]=='O'))   //$CO geldi ise, kanal değişiklik onay bilgisi gelmiştir.


Add #case to your program, it will make the compiler case sensitive. Sometimes annoying but it will ensure you write all variables with the same capitalization and so easier to read. Good practice is to write constants in all capital characters (int_rda and pin_d0 become INT_RDA & PIN_D0)
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Sat Jun 09, 2012 7:35 am     Reply with quote

The big problem though is int_rda.

You need to remove just about everything you have inside it....
First, there is no point in disabling the interrupt, or clearing the interrupt, or enabling the interrupt inside the handler. The compiler clears the interrupt for you, Unless_ you specify 'no_clear', and all interrupts are automatically disabled when a handler is called.

The big problem though is that you wait for multiple characters. You _must not_ do this. The interrupt means that _one_ character is ready for you to read. Just one. You wait for three characters to arrive, and write these to the EEPROM. EEPROM writes take about 4mSec each. So your code is effectively 'stuck' inside the INT_RDA handler for at least 12mSec (longer if the characters do not arrive immediately). USB, _requires_ that replies are issued to certain commands inside 10mSec. All the time you are stuck inside INT_RDA, USB responses are not happening. Also the time taken to write, is longer than the time between characters, so characters will be missed if they arrive without break.

You need to start again. Base your INT_RDA code on EX_SISR, making a _circular_ buffer, that stores just one character, and gets out ASAP.

Then have you main code implement a little state machine, (a search here, or online, will find examples), which if the three required characters come, drops D0, and stores the characters as required into the EEPROM.

Though there are times when it can be ignored, the old 'mantra' really does apply, especially when running USB - interrupt handlers should do the _minimum_ necessary to handle the event the interrupt signifies, and get out again ASAP.

There is a separate problem that your CPU is _not_ clocking at 20MHz.
You have HSPLL selected, which means that the CPU clock comes from the USB PLL. With a 20MHz crystal (presumably, since you have PLL5, which implies division by 5 before feeding the PLL). The output of the PLL is 96MHz, which is then divided by 2 to feed the USB. CPUDIV4, then gives '11' as the bit pattern to the divider chain, which when operating from the USB clock divides this by 6 (I know silly isn't it...). So your CPU is actually running at 16MHz, not 20MHz, which will prevent RS232 from receiving characters properly....

Best Wishes
ceronimo



Joined: 19 Jan 2010
Posts: 9

View user's profile Send private message Send e-mail

PostPosted: Sat Jun 09, 2012 8:05 am     Reply with quote

# use rs232 added a routine part of ERRORS.

Fast_io for all ports have added.
DS18B20 has been canceled. Operation of stopped.

Trying to uninstall the DS18B20 fast_io routines for all ports, but this time the ADC is disabled.

also
Code:
#byte SPBRGH=0xFB0
#byte SPBRG=0xFAF
#byte BAUDCON= 0xFB8
#byte TXSTA=0xFAC
#byte RCSTA=0xFAB
#bit TXEN= TXSTA.5
#bit SYNC=TXSTA.4
#bit SENDB=TXSTA.3
#bit BRGH=TXSTA.2
#bit SPEN=RCSTA.7
#bit BRG16=BAUDCON.3


and

Code:
   SPEN=1;
   SYNC=0;  //Asynchronous mode
   SPBRGH=0;
   SPBRG=25;   //HSPLL FREKANSI CPUDIV AYARINDAN DOLAYI 6 YA BÖLÜNDÜĞÜNDEN PİCİN ÇALIŞMA FREKANSI 16MHz OLMUŞ OLUYOR.       
   BRG16=0; //8-bit Baud Rate Generator – SPBRG only (Compatible mode), SPBRGH value ignored
   BRGH=0;  //Low speed


rs232 communication routines in the program did not improve and when. Lack of communication continues.
ceronimo



Joined: 19 Jan 2010
Posts: 9

View user's profile Send private message Send e-mail

PostPosted: Sat Jun 09, 2012 8:23 am     Reply with quote

Hi Ttelmah,

Can you write it for me sample code in accordance with my program you mind?
ceronimo



Joined: 19 Jan 2010
Posts: 9

View user's profile Send private message Send e-mail

PostPosted: Mon Jun 11, 2012 2:36 pm     Reply with quote

I wrote a simple code in the following link. nidhimittalhada wrote the code works.
http://www.ccsinfo.com/forum/viewtopic.php?t=43483

Code:

#include <18F4550.h>
#fuses HSPLL, NOWDT, PLL5, CPUDIV1, USBDIV, NOXINST
#use delay (clock=48000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STOP=1)

void main() {
   char c[5];
   printf("%c%c%c",0x24,0x43,0x30);

   while(TRUE) {
      output_toggle(pin_d0);
      if (kbhit() ) {
         c[0]=getc();
         c[1]=getc();
         c[2]=getc();
         write_eeprom(0,c[0]);
         write_eeprom(1,c[1]);
         write_eeprom(2,c[2]);
      }
   }
}


Here the following events,
UFM-M11 module is sent to the channel selector code. 0x24, 0x43, 0x30
0. the channel is said to be used. Ok when you receive this code in the module as a pic18f4550 of data 0x24, 0x43, 0x4F, ie "$ CO" needed to send.
3 bytes of data sent to the above program is run (0x24, 0x43, 0x30
) Just taken. It seem to have a reverberation. I use 4093 version of the compiler

Please help.[url][/url]
ceronimo



Joined: 19 Jan 2010
Posts: 9

View user's profile Send private message Send e-mail

PostPosted: Mon Jun 11, 2012 2:58 pm     Reply with quote

I using micro-easypic5 board.
I noticed that. 18F4550 programmed on the system board. I did read through the plate without removing. has just sent in the eeprom data. Other 18F4550 did the same procedure. The same conclusion. 20 MHz crystal. 22pF capacitor.
Bi very strange situation.
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