View previous topic :: View next topic |
Author |
Message |
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
18F2550 clock scaling |
Posted: Wed Jul 14, 2010 7:27 pm |
|
|
scaling question:
I have some code that is refurbished from a pic using 4MHz clock.
I now want to use the code for an 18F2550 that has an internal oscillator of 20MHz.
From my limited understanding this means that I am getting a 5MHz timing on the instructions.
How do I prescale this in order to get the instruction timing to 1MHz???
which would allow me to reuse my existing code (for a universal remote) without having to change much.
(i.e. the pic would be timing like a 4Mhz clock).
Thank all ! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 14, 2010 7:38 pm |
|
|
Use the CCS functions, delay_us() and delay_ms(). If you set the
#use delay() to match your crystal, the compiler automatically
calculates the correct delay routines so that delay_ms(1) is always
the same 1 ms time. |
|
|
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
18f2550 delay |
Posted: Wed Jul 14, 2010 7:41 pm |
|
|
For my previous code I had a delay(4000000), which worked fine. I can't recall what PIC this was with.
When I try the same code for my 18f2550 with a delay(4000000) I get garbage over the serial.
When I change it back to delay(20000000) then it works fine over the serial, but all of the timing seems to be wrong for the universal remote. |
|
|
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
18f2550 code - universal remote |
Posted: Wed Jul 14, 2010 7:44 pm |
|
|
Code: | #include <18F2550.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOLVP //
#FUSES NOPUT
#use delay(clock=4000000) //serial works with #use delay(clock=20000000)
#define RS232_XMIT PIN_C6 //RS232 serial transmit
#define RS232_RCV PIN_C7 //RS232 serial receive
#use rs232(baud=9600,xmit=RS232_XMIT,rcv=RS232_RCV,parity=N,bits=8,stream=COMP)
int counter,i,com,adr;
int16 buffer;
int16 cnt = 0;
#int_ext
void ext_isr(){
output_bit(PIN_C2, 1);
counter=0; //reset counter and buffer
buffer=0;
disable_interrupts(int_ext); //disable interrupts
while(!input(pin_b0)){ //wait for high level
delay_us(15);
++counter; } //time how long has been low
fprintf(COMP,"counter:%u\r\n",counter);
if(counter>=15&&counter<=30){ //if from about 800 to 1000 us
//do routines
delay_us(200);
for(i=0;i<13;i++){ //13 following bits
if(input(pin_b0)){ //if the input high
bit_set(buffer,0); //set the LSB and shift left
buffer<<=1;}
else //otherwise just shift
buffer<<=1;
delay_us(1740); //wait for next bit
}
buffer>>=1; //shift 1 right because of last reading
com=buffer&0b00111111; //command is 6-bit long; ignore the rest
buffer>>=6; //shift 6 right
adr=buffer&0b00011111; //address is 5-bit long; ignore the rest
//display on an LCD
fprintf(COMP,"Address:%u Command:%u\r\n",adr,com); //send bytes to the rs232
delay_ms(150);
} //wait
//return(0); //return to main
}
main(){
delay_ms(100);
//output_bit(PIN_C2, 1);
fprintf(COMP,"on... \n\n");
while(1){
delay_ms(100);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
cnt = cnt + 1;
//fprintf(COMP,"cnt:%lu",cnt);
output_bit(PIN_C2, 0);
delay_ms(50);
}
} |
|
|
|
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
external clock |
Posted: Wed Jul 14, 2010 8:20 pm |
|
|
I added an external clock (4MHz) and it works fine now... problem is that my code does not.
Can someone PLEASE PLEASE help me with this code?
I have a universal remote programmed with a Sony setting (TV).
I am not getting consistent address and command with the above code.
Also, I have to hold the buttons for a long time and many times in order to get any output.
Any suggestions???
Thank you all. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jul 14, 2010 9:12 pm |
|
|
Set this line in comment: Code: | fprintf(COMP,"counter:%u\r\n",counter);
| At 9600 baud it takes about 12ms to print this data causing your program to miss the first few data bits. |
|
|
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
working |
Posted: Thu Jul 15, 2010 8:51 am |
|
|
Thanks for the advice!
I did get it working although not as consistent as I would like...
I need to buy an oscilloscope!
I changed the first delay to 20us, and changed the if statement:
Code: |
while(!input(pin_b0)){
delay_us(20);
++counter; }
if(counter<=75){
//do routines
delay_us(200);
|
Now it is working but not as consistent as I would hope.
Thanks again |
|
|
|