View previous topic :: View next topic |
Author |
Message |
ragipselcuk
Joined: 21 Apr 2008 Posts: 8
|
Sony IR remote control problem |
Posted: Fri Aug 29, 2008 1:46 pm |
|
|
I wrote a code sony remote receiver for PIC16F877 at 4Mhz. This code is successful. But I must use PIC18F452. I convert timer values for 40Mhz, but source code doesnt burn. Where is my mistake? I give my code below.
Help me for configuration PIC18F452, please
Code: |
#include <16f877.h>
#fuses XT,NOWDT,PROTECT,NOBROWNOUT,PUT,NOLVP
#use delay(clock=4000000)
#define START_MIN 100
#define START_MAX 260
#define BITTIME 60
#byte INTCON=0x0B
void wait_for_high_to_low()
{
while(!input(PIN_B0));
delay_us(600);
}
void wait_for_high() {
delay_us(3);
while(!input(PIN_B0));
}
//***********************************************///
#int_ext
void int_ext_(void)
{ gelen_ilk=0;
valid_cod=0;
setup_counters( RTCC_INTERNAL, RTCC_DIV_16); // timer 0 counter , xtal = 4 Mhz için
value = 0;
do { /* start bit */
wait_for_high_to_low(); //
set_rtcc(0);
wait_for_high();
time = get_rtcc();
gelen_ilk++;
if(gelen_ilk==0x7f) break;
} while ((time < START_MIN) || (time > START_MAX));
for (n = 0 ; n <= 7 ; n++){ /*get data bits */
wait_for_high_to_low();
set_rtcc(0);
wait_for_high();
time = get_rtcc();
if (time > BITTIME)
bit_set(value,n);
} //
bit_clear(value,6); //
wait_for_high_to_low(); //
set_rtcc(0); //
wait_for_high();
time = get_rtcc();
if (time > BITTIME)
bit_set(value,6);
remote_value=value;
}
///****************************************///
//80----------->1 94------------>Mute BC------------>Select
//81----------->2 95------------>Standby 96------------>Normal
//82----------->3 92------------>Volume+ B4------------>+
//83----------->4 93------------>Volume- B5------------>-
//84----------->5 90------------>Program+ A5------------>Tv/Video
//85----------->6 91------------>Program-
//86----------->7 BA------------>Dısplay
//87----------->8 8C------------>1-
//88----------->9 8D------------>2-
//89----------->0 B6------------>Sleep
////////////////////////////////////////////////
void main(void)
{ set_tris_b(0x01);
set_tris_c(0);
set_tris_e(0);
set_tris_d(0);
output_d(0);
output_e(0);
output_c(0);
ext_int_edge(H_TO_L);
enable_interrupts(int_ext);
INTCON=0x90;
while(1)
{
// ..............
}
}
This code is working fine for 16F877.
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 29, 2008 2:12 pm |
|
|
Download the 18F452 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/39564c.pdf
Look up the address of the INTCON register in this section of the
data sheet:
Quote: | TABLE 4-1: SPECIAL FUNCTION REGISTER MAP |
Also, why are you directly writing to the INTCON register when
you can use CCS functions to enable/disable interrupts ?
If you had used those functions, the code would be portable
between the 16F and 18F PICs with no problems. By writing
directly to registers, you caused this problem for yourself. |
|
|
ragipselcuk
Joined: 21 Apr 2008 Posts: 8
|
Sony |
Posted: Fri Aug 29, 2008 2:31 pm |
|
|
I converted my code with ccs functions.But it is not burning
Code: |
#include<18F452.h>
#use delay(clock=40000000)
#fuses NOWDT,H4, PROTECT, NOOSCSEN, BROWNOUT, BORV20, PUT, STVREN, NODEBUG
#fuses NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
void wait_for_high_to_low()
{
while(!input(PIN_B0));
delay_us(600);
}
void wait_for_high() {
delay_us(3);
while(!input(PIN_B0));
}
////////////////////////////////////////////////////////////////////////////////
#INT_EXT
void remote_isr(void){
int8 n,time,gelen_deger=0,gelen_ilk=0;
setup_counters( RTCC_INTERNAL, RTCC_DIV_16); // timer 0 counter , for xtal = 4 Mhz
value = 0;
do { /* start bit */
wait_for_high_to_low(); //
set_rtcc(0);
wait_for_high();
time = get_rtcc();
gelen_ilk++;
if(gelen_ilk==0x7f) break;
} while ((time < START_MIN) || (time > START_MAX));
for (n = 0 ; n <= 7 ; n++){ /*get data bits */
wait_for_high_to_low();
set_rtcc(0);
wait_for_high();
time = get_rtcc();
if (time > BITTIME)
bit_set(value,n);
} //
bit_clear(value,6); //
wait_for_high_to_low(); //
set_rtcc(0); //
wait_for_high();
time = get_rtcc();
if (time > BITTIME)
bit_set(value,6);
remote_value = value;
}
void main(void){
set_tris_b(0x01);
set_tris_c(0);
set_tris_e(0);
set_tris_d(0);
output_d(0);
output_e(0);
output_c(0);
output_b(0);
port_b_pullups(FALSE);
ext_int_edge(H_TO_L);
enable_interrupts(int_ext);
enable_interrupts(global);
while(1){
///.........
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 29, 2008 2:42 pm |
|
|
What do you mean it doesn't "burn" ?
"Burn" means to program it with a ICD-U40, or ICD2, or PicStart-Plus,
etc., programmer.
Do you really mean it doesn't "run" ? Or it doesn't "compile" ? |
|
|
ragipselcuk
Joined: 21 Apr 2008 Posts: 8
|
|
Posted: Fri Aug 29, 2008 2:45 pm |
|
|
I mean that is doesnt run for 18f452 at 40Mhz. It is running 16f877 at 4Mhz and it is running 18f452 at 4Mhz.
I am sorry for my english. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 29, 2008 2:51 pm |
|
|
With the 18F452, when you change it to PLL mode (when it was in XT
or HS before), you must unplug the power from the board, and then
plug the power in again. This is necessary to make the board go into
PLL mode. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 29, 2008 5:04 pm |
|
|
Code: | setup_counters( RTCC_INTERNAL, RTCC_DIV_16); // timer 0 counter , for xtal = 4 Mhz | The comment says this line is for 4MHz.... |
|
|
ragipselcuk
Joined: 21 Apr 2008 Posts: 8
|
|
Posted: Fri Aug 29, 2008 11:16 pm |
|
|
Yes,I calculated for 40Mhz but it still doesn't run.
Code: |
setup_counters( RTCC_INTERNAL, RTCC_DIV_256) //for 40Mhz
set_rtcc(96); // offset value is 96 for 40Mhz
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 29, 2008 11:43 pm |
|
|
It looks like you got your code from here, and then you have changed it:
http://home.earthlink.net/~henryarnold/Sony3.txt
For example, the Arnold code has this routine:
Quote: | void wait_for_high_to_low() {
while(!input(PIN_B3)) ; /* if it's high, wait for a low */
delay_us(3); /* account for fall time */
while(input(PIN_B3)); /* wait for signal to go high */
} |
You changed it to this:
Code: | void wait_for_high_to_low()
{
while(!input(PIN_B0));
delay_us(600);
} |
The Arnold appears somewhat suspect, because of this:
He defines a START_MAX value that is greater than a byte. I.e., a
byte value can be up to 255, maximum. He defines a value of 260.
Quote: |
#define START_MIN 100
#define START_MAX 260
|
Then he declares a byte variable:
Then he reads an 8-bit rtcc value and compares it to 260.
How does that work ?
Quote: |
time = get_rtcc();
} while ((time < START_MIN) || (time > START_MAX)); |
|
|
|
ragipselcuk
Joined: 21 Apr 2008 Posts: 8
|
|
Posted: Sat Aug 30, 2008 12:06 am |
|
|
Dear PCM Programmer,
Yes, when I found the this code, it doesn't run for pic16f877 but I changed the some routines and it works fine. You are all right. Time never exceed the MAX_TIME. But I cant still find a solve for 40Mhz. I used this code in my old project with pic16f877.
Can you give me an advice, please.
Best Regards. |
|
|
Ttelmah Guest
|
|
Posted: Sat Aug 30, 2008 2:12 am |
|
|
Obvious question that hasn't been asked. How is the oscillator for your chip arranged?. What crystal?.
40MHz, requires a 10Mhz crystal (for the fuses as shown).
Have you tested a really 'simple' flash the LED type program, at the higher clock rate, and verified that the chip is actually running, and that the on/off times are what you expect?.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Aug 30, 2008 4:29 pm |
|
|
Or use another approach: change one thing at a time.
Try to make the original code run at a 4MHz PIC18 first before increasing the frequency to 40MHz. |
|
|
|