|
|
View previous topic :: View next topic |
Author |
Message |
oxxyfx
Joined: 24 May 2007 Posts: 97
|
16F88 - Rb3 issue |
Posted: Fri Aug 10, 2007 7:08 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 7:18 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 7:48 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 8:23 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 9:19 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 9:59 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 10:17 pm |
|
|
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
|
|
Posted: Fri Aug 10, 2007 10:40 pm |
|
|
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. |
|
|
|
|
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
|