|
|
View previous topic :: View next topic |
Author |
Message |
Baby_Boy Guest
|
Pls help, conver code to pic16F877 and send data to RS232 |
Posted: Sat Apr 01, 2006 7:33 pm |
|
|
Original code :
'IR Remote Code Grabber S/W
'Posted: Sat Dec 18, 2004 1:42 pm
'--------------------------------------------------------------------------------
'I just finished doing a little program that grabs the 32 bit code from an infra-red remote (i.e. a TV or stereo's remote) and displays it on an LCD. I thought that someone else may find it useful. For the schematic, refer to me labs' lab-x1 board found here: http://www.melabs.com/downloads/labx1sch.pdf
'The IR remote receiver itself is the Sharp GP1UD262XK (part # 425-1117-ND from digikey: http://www.digikey.ca) The GP1UD is a 3 pin device - simple hookup: supply 5V to Vcc, ground the GND pin, and the signal out pin is hooked to the PIC's EXT0 pin (pin B0).
'Here is a good link regarding IR remotes and their data format: http://www.tapspring.com/HATcker_AP_TV.htm Edit: I just tried this link, and it seems to be down for the moment. Anyway, a remote starts a packet with a lead-in sequence. In the absence of IR light, the output of the decoder is normally high. The lead-in sequence consists of a logic low lasting about 8 - 9 ms, followed by a high lasting about 4 ms. Data transfer starts immediately after that, MSbit first. A logic 0 consists of pulsetrain starting with a low level lasting about 0.5 - 0.6 ms, followed by a high level lasting about 0.4 ms. A logic 1 consists of a pulsetrain starting with a low level lasting about 0.5 - 0.6 ms, followed by a high level lasting about 1.4 ms.
'I should point out that most remotes send a bare minimum of 64 bits, in two 32 bit "packets". For some functions, the two packets are identical. For others, the two packets are different - thus the reason why the code grabs two packets and displays them.
'Code:
#include <18F452.h>
#device adc=8
#use delay(clock=20000000,RESTART_WDT)
#fuses HS, BROWNOUT, BORV20, PUT, STVREN, NOLVP
struct lcd_pin_map {
boolean junk;
boolean unused;
boolean junk2;
boolean junk3;
int data : 4;
boolean rs;
boolean enable;
boolean rw;
} lcd;
#byte lcd = 0xf83 // 18f452
//#byte lcd = 8 // 16f877
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
STRUCT lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
STRUCT lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
byte lcd_read_byte() {
byte low,high;
set_tris_d(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_d(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( byte address, byte n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
byte i;
set_tris_d(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( byte x, byte y) {
byte address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
#define LEAD_IN_LOW 40000 // 8 ms
#define LEAD_IN_TOTAL 60000 // 12 ms
#define MIN_TIME 3000 // 0.6 ms
#define THRESHOLD 8000 // 1.6 ms
#define MAX_TIME 11500 // 2.3 ms
unsigned int8 overflow_count = 0, rx_state = 0xff;
unsigned int32 timer_at_start, timer_at_end, low_time, timer_at_mid, period, first_data = 0, second_data = 0;
unsigned int32 temp1, temp2, timer_at_mid_start;
int1 full_cycle = FALSE, got_first = FALSE, data_avail = FALSE, caught_rise = TRUE;
#int_TIMER1
void TIMER1_isr(void) {
++overflow_count; // increment when an overflow occurs
}
#int_EXT
void ext_isr(void) {
if (caught_rise) { // this is a falling edge
timer_at_end = get_timer1();
period = (0x10000 * overflow_count) + timer_at_end - timer_at_start;
overflow_count = 0;
timer_at_start = timer_at_end;
full_cycle = TRUE;
caught_rise = FALSE;
rx_state++;
ext_int_edge(0,L_TO_H);
}
else { // this is a rising edge
timer_at_mid = get_timer1();
low_time = (0x10000 * overflow_count) + timer_at_mid - timer_at_start;
if (rx_state == 33) {
rx_state = 0xff;
if (!got_first) {
got_first = TRUE;
}
else {
got_first = FALSE;
data_avail = TRUE;
}
}
caught_rise = TRUE;
ext_int_edge(0,H_TO_L);
}
}
void decode_info(void) {
// each tick = 200 ns
int i;
if (rx_state == 1) { // end of first period - lead in
if ((low_time < LEAD_IN_LOW) || (period < LEAD_IN_TOTAL)) {
rx_state = 0xff; // reset
caught_rise = TRUE;
ext_int_edge(0,H_TO_L);
}
}
else if ((rx_state > 1) && (rx_state < 34)) { // valid data
i = 33 - rx_state;
if (period < MIN_TIME) {
rx_state = 0xff; // reset
caught_rise = TRUE;
ext_int_edge(0,H_TO_L);
}
if (period < THRESHOLD) { // logic zero
if (!got_first) {
bit_clear(first_data, i);
}
else {
bit_clear(second_data, i);
}
}
else if (period < MAX_TIME) { // logic one
if (!got_first) {
bit_set(first_data, i);
}
else {
bit_set(second_data, i);
}
}
else if (period >= MAX_TIME) { // reset
rx_state = 0xff;
caught_rise = TRUE;
ext_int_edge(0,H_TO_L);
}
}
}
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_ON);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
ext_int_edge(0,H_TO_L);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_EXT);
enable_interrupts(global);
set_tris_e(0x00);
set_tris_c(0xff);
port_b_pullups(TRUE);
set_tris_b(0xff);
lcd_init();
lcd_putc("\fReady...");
rx_state = 0xff;
while (TRUE) {
restart_wdt();
if (full_cycle) {
full_cycle = FALSE;
decode_info();
}
if (data_avail) {
data_avail = FALSE;
printf(lcd_putc,"\fCMD1 = %lx\nCMD2 = %lx", first_data, second_data);
}
}
} |
|
|
mpfj
Joined: 09 Sep 2003 Posts: 95 Location: UK
|
|
Posted: Sun Apr 02, 2006 1:14 pm |
|
|
So you'd like someone on this forum to take this existing code, convert it to work on a different PIC, and output the data to the RS232 port instead of an LCD ?
Sure, please send me some more details and I'll quote you for my time and effort.
*OR* you could maybe try to do it yourself and ask us for some help if you get stuck. |
|
|
|
|
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
|