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

16F88 - Rb3 issue

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



Joined: 24 May 2007
Posts: 97

View user's profile Send private message

16F88 - Rb3 issue
PostPosted: Fri Aug 10, 2007 7:08 pm     Reply with quote

Hello,

I have the 16F88 in a diversity receiver project. The program measures the RSSI signal coming from the different receivers (through ADC) and switches to the one with the best signal level. I recently wanted to add a safety frature - meaning - in case I loose the video sync, to also switch to a different receiver which has a valid video sync signal.

The Loss of Sync signal is provided by a MAx chip - if there is video sync then the LOS signal is +5V if the sync is out then it goes down to 0V.

The Max chip requires that this signal line to be pulled up with a 1k resistor.

I modified the program, uploaded it to the PIC and connected the signal to B3. Booted - except there is no boot.... The PIC does not initialize. I removed the signal line - booted again, this time no poblem.

Connected again, no boot. Removed again, boot. I tried to make sure the level is high or low - if it is connected it doesn't matter it won't boot.

I don't think this is a programming issue since the program runs when the signal is not connected.

I checked the datasheet and I saw that the B3 is used for Low voltage programming, I have a this fuse set to NOLVP - in order to use this pin as an i/o pin.

What am I doing wrong?

Thanx, Ox.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 7:18 pm     Reply with quote

Quote:
I checked the datasheet and I saw that the B3 is used for Low voltage
programming, I have a this fuse set to NOLVP - in order to use this pin
as an i/o pin.


1. Try a different pin. See if you still have the same problem.

2. Verify that your programmer is really programming that fuse as
"NOLVP". Use your programmer to read the chip, and then look at
the config bits that it read. (What is your programmer ?)
oxxyfx



Joined: 24 May 2007
Posts: 97

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 7:48 pm     Reply with quote

It is a K150 hobby programmer. I will try a different pin as well and let you know. Thanks for the tip. Up ti now I didn't have any problems programming with this programmer.
oxxyfx



Joined: 24 May 2007
Posts: 97

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 8:23 pm     Reply with quote

I tried two other pins and it boots if it is connected.

How exactly do I have to check the cofiguration bits if I read the program back from the chip? I am using a software called MicroPro to read and write the PIC.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 9:19 pm     Reply with quote

I don't have the Micropro.exe program. Most programmer software
have a menu where you can view the Config bits after you have read
the program in the PIC.
oxxyfx



Joined: 24 May 2007
Posts: 97

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 9:59 pm     Reply with quote

Ok, I did some debugging and it is a programming issue. I disabled the interrupt routine which I use to detect changes in the Loss of Siganl line and now it boots. SO here is the program:

Code:
#include <16F88.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES BROWNOUT                 //Reset when brownout detected
#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                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8,ERRORS)


Code:

#include "F:\Pic Projects\Spatial Diversity Receiver\sdr.h"

#Define RSSI_1      Pin_A0
#Define RSSI_2      Pin_A1
#Define RSSI_3      Pin_A2
#Define RSSI_4      Pin_A3
#Define Beeper      Pin_A4

#Define SwAddr_0     Pin_B0
#Define SwAddr_1     Pin_B1
#Define SwitchSig    Pin_B2
#Define LostSig      Pin_B3
//#Define AudioCh1     Pin_B4
//#Define AudioCh2    Pin_B5
#Define AudioCh3    Pin_B6
#Define AudioCh4    Pin_B7

#Define On        1
#Define Off       0
#Define Maxim     1
#Define Average   0

int8 iX;
int8 rcvs[4];
int8 rssi_value[4];
int8 adcchan;
int8 value;
int8 temp;
int8 activercv;

Int8 adc_conversion(int8 adc_value);
Void Switchoutput(int8 channel);


#int_RB
Void int_RB_isr() {

      If (!Input(LostSig)){
//- Measure the rssi on all active receivers
         For (iX = 0; iX < 4; iX++) {
              if (rcvs[iX] || 0 ){
                     adcchan = iX;
                     rssi_value[iX] = adc_conversion(value);
                     Delay_ms(1);
              }
         }
//-Find the receiver with the lowest rssi value
         temp = rssi_value[0];
         activercv = 0;
         For (iX = 1; iX < 4; iX++) {
            if (rcvs[iX] || 0) {
                     if (rssi_value[iX] < temp){
                         temp = rssi_value[iX];
                         activercv = iX;         
                     }
            }
         }   
         Switchoutput(activercv);
      }
}

int Calctype;
int Flag;
int16 cX;
int8 rcvsno;
int8 temprcv;
int8 channel;
int8 Treshold;
int8 Currentadc;
int8 sensitivity;

Void LongBeep();
Void Beep();
Void SwBeep();
Void Init(Int8 i);
Void Switchoutput(int8 channel);


void main()
{
   setup_adc_ports(sAN0|sAN1|sAN2|sAN3|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_4MHZ|OSC_TIMER1);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RB);
   ext_int_edge(H_to_L);

//-Turn Video On
   Output_low(SwAddr_0);
   Output_low(SwAddr_1);

//-Define the RSSI calculation type - for Maxim or Average
   Calctype = Maxim;
//-Define the RSSI treshold - absolute maximum and sensitivity;
   Treshold = 90;
   Sensitivity = 7;

//-Beep, so we know we are in business
   Longbeep();

//-Check how many receiveres we are dealing with.
   For (iX = 0; iX < 4; iX++) {
        adcchan = iX;
        delay_ms(100);
        if (adc_conversion(value) == 0) {
            Delay_ms(100);
            if (adc_conversion(value) == 0) rcvs[iX] = 0;
            else rcvs[iX] = 1;
        }
        else rcvs[iX] = 1;
   }
   rcvsno = 0;
   For (iX = 0; iX < 4; iX++) {
         If (rcvs[iX] == 1){
            rcvsno++;
         }
         Delay_ms(250);
   }

//-If there aren't any receivers keep beeping
   if (rcvsno == 0) {
      While (1) {
         LongBeep();
         Delay_ms(150);
      }
   }
//-Once you have number and position of the receivers, beep it back to me
   For (iX = 1; iX < 5; iX++) {
         If (rcvs[iX] == 1){
           
            Init(iX);
         }
         Delay_ms(250);
   }

//-Give us some video output - switch to the first available receiver channel if 1 is not available
   if (rcvs[0] == 0){
      if (rcvs[1] || 0) {
         Switchoutput(1);
      }
      Else if (rcvs[2] || 0) {
         Switchoutput(2);
      }
      Else if (rcvs[3] || 0) {
         Switchoutput(3);
      }
   }

//- Let's see where is our plane:
  //- Measure the rssi on all active receivers
   For (iX = 0; iX < 4; iX++) {
        if (rcvs[iX] || 0 ){
               adcchan = iX;
               rssi_value[iX] = adc_conversion(value);
               Delay_ms(10);
                                                printf("Active     RCV:");
                                                printf("%U",iX);
                                                if (rssi_value[iX]<100) Printf("RSSI   Value: ");
                                                Else Printf("RSSI  Value: ");
                                                printf("%U",rssi_value[iX]);
                                                Delay_ms(500);
                                                printf("                ");
                                                printf("                ");
                                                Delay_ms(250);
        }
   }
  //-Find the receiver with the lowest rssi value
   temp = rssi_value[0];
   activercv = 0;
   For (iX = 1; iX < 4; iX++) {
        if (rcvs[iX] || 0) {
               if (rssi_value[iX] < temp){
                   temp = rssi_value[iX];
                   activercv = iX;         
                }
        }
   }   
                                                printf("Active     RCV:");
                                                printf("%U",activercv);
                                                Delay_ms(500);
                                                printf("R S S I   Value:");
                                                printf("%U",rssi_value[activercv]);
                                                if (rssi_value[activercv]<100) Printf("              ");
                                                else printf("             ");
                                                Delay_ms(250);
                                 
//-Now switch to the active receiver
   Switchoutput(activercv);
   Delay_ms(3000);
//-Now we are ready to loop around and search for the best signal level

While(True) {
            Delay_ms(250);
            adcchan = activercv;
            Currentadc = adc_conversion(value);
            while (rssi_value[activercv] >= Currentadc - sensitivity && rssi_value[activercv] <= Currentadc + sensitivity) {
                  delay_ms(100);
                  Currentadc = adc_conversion(value);
                                                printf("Currentadc Value");
                                                printf("%U",Currentadc);
                                                Delay_ms(500);
                                                if (Currentadc<100) Printf("              ");
                                                else printf("             ");
                                                Delay_ms(250);
            }
            temprcv = activercv;
            //- Measure the rssi on all active receivers
            For (iX = 0; iX < 4; iX++) {
               if (rcvs[iX] || 0 ){
                        adcchan = iX;
                        rssi_value[iX] = adc_conversion(value);
                        Delay_ms(10);
               }
            }
            //-Find the receiver with the lowest rssi value
            temp = rssi_value[0];
            activercv = 0;
            For (iX = 1; iX < 4; iX++) {
               if (rcvs[iX] || 0) {
                     if (rssi_value[iX] < temp){
                        temp = rssi_value[iX];
                        activercv = iX;         
                     }
               }
            }
            if (activercv || temprcv ) {
                  Switchoutput(activercv);
            }

}

}

Void Init(int8 i){
  for (ix=0; iX<i; iX++) {
         Beep();
         Delay_ms(200);
   }
}

Void Beep() {
     for ( cX = 0; cX < 50; cX++ ) {
     Output_high(Beeper);
     delay_us ( 160 );
     Output_low(Beeper);
     delay_us ( 240 );
     }
}

Void SwBeep() {
     for ( cX = 0; cX < 40; cX++ ) {
     Output_high(Beeper);
     delay_us ( 110 );
     Output_low(Beeper);
     delay_us ( 200 );
     }
}

Void LongBeep() {
     for ( cX = 0; cX < 600; cX++ ) {
     Output_high(Beeper);
     delay_us ( 110 );
     Output_low(Beeper);
     delay_us ( 200 );
     }
}

Int8 adc_conversion(int8 adc_value) {
int8 v[50];
int16 Total;
      Total = 0;
      set_adc_channel( adcchan );
      Delay_us(20);
      For(cX = 0; cX < 50; cX++) {
         v[cX] = read_adc();
         delay_us(10);
      }
      Total = v[0];
      If (Calctype == Maxim) {     
            For (cX=1; cX < 50; cX++){
               If (v[cX] < Total) Total = v[cX];
            }
            value = Total;
      }
      Else {
            For( cX=0; cX < 50; cX++) {
                Total = Total + v[cX];
            }
            value = Total / 50;
      }
      return(value);
}

Void Switchoutput(int8 channel){

      If (!Input(SwitchSig))While (!Input(Switchsig)){}
      Else While (Input(Switchsig)){}
         Switch (channel) {
            Case 0:
               Output_low(SwAddr_0);
               Output_low(SwAddr_1);
//               Output_high(Audioch1);
//               Output_low(Audioch2);
               Output_low(Audioch3);
               Output_low(Audioch4);
                                                Delay_ms(250);
                                                printf("Switched to RCV0");
                                                Delay_ms(250);
               Break;
            Case 1:
               Output_low(SwAddr_0);
               Output_high(SwAddr_1);
//               Output_low(Audioch1);
//               Output_high(Audioch2);
               Output_low(Audioch3);
               Output_low(Audioch4);
                                                Delay_ms(250);
                                                printf("Switched to RCV1");
                                                Delay_ms(250);
              Break;
            Case 2:
               Output_high(SwAddr_0);
               Output_low(SwAddr_1);
//               Output_low(Audioch1);
//               Output_low(Audioch2);
               Output_high(Audioch3);
               Output_low(Audioch4);               
               Break;
            Case 3:
               Output_high(SwAddr_0);
               Output_high(SwAddr_1);
//               Output_high(Audioch1);
//               Output_low(Audioch2);
               Output_low(Audioch3);
               Output_high(Audioch4);               
               Break;
         }
         Beep();
     
}


Please ignore the printf routines, I have an LCD display connected which displays some verable values back to me.

If I rem out the #Int_rb routine, than it will boot with this program.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 10:17 pm     Reply with quote

Well, there was a previous thread on this topic and it was your thread,
where we went over some of this topic.
http://www.ccsinfo.com/forum/viewtopic.php?t=31423&highlight=intrb

You've still the setup_spi(FALSE) statement in your code. That statement
is going to change the TRIS settings on the three hardware SPI pins, C3,
C4, and C5. It may change them to settings that you don't want, and
there's no reason to have that statement in there. The SPI module is
disabled upon power-on reset anyway.

The key points are:

1. Inside the INT_RB isr, you must read Port B to clear the "mismatch"
condition that causes the INT_RB interrupt. If you don't do this, you
will get constant interrupts. You'll go right back into the INT_RB isr
just as soon as you exit from it. The program will appear to hang.

2. Before you enable INT_RB interrupts in your main() code, you must
read Port B, to clear any pre-existing "mismatch" condition.
In addition to that, you must call the clear_interrupt(INT_RB) function,
to clear the interrupt flag, in case it was set by a pre-existing
mis-match condition. These two things prevent you from jumping
into the INT_RB code (perhaps falsely) immediately after enabling
interrupts.

You can read Port B by using the input_b() function. Example:
Quote:

int8 c;

c = input_b();
oxxyfx



Joined: 24 May 2007
Posts: 97

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 10:40 pm     Reply with quote

Thank you, I remember that discussion. However there the problem was using the Fast_io directives and the set_tris_a/b statements. Once I disabled those the program started working as expected.

I will implement your reccomandations and will let you know the results. Your help is much appreciated,

Thank you.
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