View previous topic :: View next topic |
Author |
Message |
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
Need help ! delay problems on a very simple program |
Posted: Wed Aug 24, 2011 2:44 am |
|
|
Hi , I'm trying to make an program that generates at PIC start, high level with 100uS duration, then low level and pause of 3800uS and the high level forever.
First I tested it with slow timing , (delay_ms(xx)) eg 10ms pulse and watch it with logic analyzer and everything gone OK.
When I change delays to uS , PIC always put output pin a high level.
My program :
Code: |
#include <16f870.h>
#device adc=8
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=16000000)
#use fast_io(B)
#define W PIN_B6 // IMMO PIN
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_INTERNAL);
//set_timer0(0);
//setup_ccp1(CCP_PWM);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
//output routine ----------------------------------------------
output_high(W);
delay_us(100);
output_low(W);
delay_us(3800);
output_high(W);
//output routine ----------------------------------------------
while(1){;}
} |
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Aug 24, 2011 3:33 am |
|
|
You are using fast IO for port B. You must set the port direction registers using SET_TRIS_B(). If you don't the pin will stay as an input all the time and it doesn't matter if you call ouput_high low as your PIC isn't driving that pin.
Its probably better not to use fast IO. Normal IO is not much slower, and you don't have to worry about the directions as much so its much less confusing and simpler. I think that you may have a pull-up resistor or other hardware pulling the pin up, and that is the high state you see.
With normal IO (or fast IO before you set the direction to output) the state of your pin is undefined until the first output_high or output_low. In fact it will be defined by your hardware outside the PIC. You may not see a 100us pulse at startup as the pin is never forced low before your 100us delay.
RF Developer |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Aug 24, 2011 4:11 am |
|
|
And, of course the standard answer to having pins that directly drive to a level, before the code starts, is to use a resistor.
So, you have a resistor pulling the pin high. Your pin will then be high even before the chip starts working. Initial timing will depend on the oscillator you use. With an RC oscillator the chip can start in only a a couple of uSec, but with a crystal oscillator, this takes time to stabilise, and the chip will typically take perhaps 20uSec to actually start (depending also on the rise time of the supply, and what is connected to MCLR)...
This is standard practice on pins driving things like power bridges, where it is vital to ensure that the lines are biased to the 'off' state, when the unit is turned on. It is also 'why' the PIC pins all wake up set as inputs, so that they are not driven to some unexpected level before the code starts.....
Best Wishes |
|
|
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
|
Posted: Wed Aug 24, 2011 4:53 am |
|
|
in first place thank you for your help ! but please note if i change delay times like example in bottom , pic do what i want
I only have problems when i change delay_ms(xx) to delay_us(xx)
Code: |
#include <16f870.h>
#device adc=8
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=16000000)
#use fast_io(B)
#define W PIN_B6 // IMMO PIN
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_INTERNAL);
//set_timer0(0);
//setup_ccp1(CCP_PWM);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
//output routine ----------------------------------------------
output_high(W);
delay_ms(10);
output_low(W);
delay_ms(10);
output_high(W);
//output routine ----------------------------------------------
while(1){;}
} |
the example above works normally .... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Aug 24, 2011 5:04 am |
|
|
Post your compiler version. Some don't allow more than 8bit numbers in the delay_..() functions though if it compiles 'fine' that may not be the problem.
Though not shown ,hopefully you have an ISR for the RTCC.Without one you WILL runs into 'problems'.
The proram you post isn't complete. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Aug 24, 2011 6:27 am |
|
|
Are you running this on real hardware, or are you simulating it? If simulating then anything *may* happen. With real hardware you are not driving the pin at all, unless you have more code than you've shown here. |
|
|
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
|
Posted: Wed Aug 24, 2011 7:08 am |
|
|
I'm running version PCWHD 4.114 and not simulating, I'm doing in hardware and this my complete program. I posted entire program :
Code: |
#include <16f870.h>
#device adc=8
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=16000000)
#use fast_io(B)
#define W PIN_B6 // IMMO PIN
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_INTERNAL);
//set_timer0(0);
//setup_ccp1(CCP_PWM);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
output_high(W);
delay_us(100);
output_low(W);
delay_us(3800);
output_high(W);
while(1){;}
}
|
This is all i need it to do, start at high level for 100us, then low level for 3800uS and high level forever. |
|
|
drh
Joined: 12 Jul 2004 Posts: 192 Location: Hemet, California USA
|
|
Posted: Wed Aug 24, 2011 7:49 am |
|
|
You are enabling RTCC interrupts but you have no interrupt handler. _________________ David |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Aug 24, 2011 8:05 am |
|
|
And, you are still not setting TRIS.
Repeat after me, ten times:
"If I use fast_IO, _I_ must control the TRIS".
RF_Developer has already pointed this out.
Best Wishes |
|
|
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
|
Posted: Wed Aug 24, 2011 9:41 am |
|
|
Corrected program but pin_b6 always high from time I power PIC ...
Code: | #include <16f870.h>
#device adc=8
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=16000000)
#use fast_io(B)
#define W PIN_B6 // IMMO PIN
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_INTERNAL);
//set_timer0(0);
//setup_ccp1(CCP_PWM);
//setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
//enable_interrupts(INT_RTCC);
//enable_interrupts(GLOBAL);
set_tris_b(0xFF);
output_high(W);
delay_us(100);
output_low(W);
delay_us(3800);
output_high(W);
while(1){;}
} |
|
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1346
|
|
Posted: Wed Aug 24, 2011 10:58 am |
|
|
Your code:
Sets all of port B to inputs. You need to set the ones you care about to outputs.
I think a value of 0xBF will probably work, but check the documentation on your chip to verify. |
|
|
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
|
Posted: Wed Aug 24, 2011 11:12 am |
|
|
Corrected but still the same, high level since power PIC.
Code: |
#include <16f870.h>
#device adc=8
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=16000000)
#use fast_io(B)
#define W PIN_B6 // IMMO PIN
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_INTERNAL);
//set_timer0(0);
//setup_ccp1(CCP_PWM);
//setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
//enable_interrupts(INT_RTCC);
//enable_interrupts(GLOBAL);
set_tris_b(0x00);
output_high(W);
delay_us(100);
output_low(W);
delay_us(3800);
output_high(W);
while(1){;}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Aug 24, 2011 11:27 am |
|
|
OK.
The code you have posted _will_ raise pin B6, then lower it, then raise it again, and leave it high.
So, if it doesn't work you need to work out what is wrong in your hardware:
1) Is your clock running, are you sure it is 16MHz?. What is connected to the clock pins?.
2) What is connected to MCLR?.
3) What is the power supply?. How is it decoupled?.
4) How are you detecting the high/low?. What is connected to B6?.
Best Wishes |
|
|
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
|
Posted: Thu Aug 25, 2011 3:04 am |
|
|
1) Is your clock running, are you sure it is 16MHz?. What is connected to the clock pins?. one XTAL 16.000.000Hz
2) What is connected to MCLR?. directly to VSS
3) What is the power supply?. How is it decoupled?. normal power supply with a 78L05 regulator
4) How are you detecting the high/low?. What is connected to B6?. i'm using IKALOGIC hard/software http://ikalogic.com/scanalogic2/
Please note if I change from delay_us(some value) to delay_ms(some value) it works 100% !!!! my problem is when i change to us
my hardware is ok because it works ok when delays are in ms |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Aug 25, 2011 5:11 am |
|
|
We hear you! But delays are just delays, no matter how long they are. They don't change how your ports work. Unless something else, such as the watchdog, or interrupts, is doing stuff.
I looked at the data sheet for the PIC 16F870. I notice that pin B6 is PGC for the ICSP programming/debugging port. As you don't disable ICSP in your fuses B6 will not be in your control.
Try a different pin (NOT B3 or B7!) to see if that helps. Is there a reason why you need to use B6? Its better to keep the ICSP pins free for that purpose and NOT use them for anything else unless you really have to use them.
RF Developer. |
|
|
|