Home work
งานที่ 8
PIC18F4550
ตัวอย่างการใช้งาน
เมาส์ USB ควบคุมจากระยะไกลโดยใช้วงจร PIC18F4550
ตัวรับสัญญาณ IR มี 3 พิน: GND, VCC และ OUT PIN OUT เชื่อมต่อกับ RB0 (INT0 pin)
วงจรที่แสดงด้านบนใช้พลังงานจากแหล่งจ่ายไฟ 5V ภายนอกซึ่งหมายความว่าไม่จำเป็นต้องเชื่อมต่อขา VCC ของตัวเชื่อมต่อ USB แต่สามารถใช้พินนี้เพื่อจัดหาวงจรและดังนั้นจึงต้องถอดแหล่งจ่ายไฟ 5V ภายนอก ในโครงการนี้ไมโครคอนโทรลเลอร์ใช้กับคริสตัลออสซิลเลเตอร์ 8 MHz และฟังก์ชั่นพิน MCLR ถูกปิดใช้
// IR Remote controlled USB mouse using PIC18F4550 microcontroller CCS C code.
// Car MP3 IR remote control is used (NEC protocol)
// http://ccspicc.blogspot.com/
// electronnote@gmail.com
#include <18F4550.h>
#fuses HS, CPUDIV1, PLL2, USBDIV, VREGEN, NOMCLR, NOWDT, NOLVP
#use delay(clock = 8MHz)
#include <usb_desc_mouse.h>
#include<pic18_usb.h>
#include<usb.c>
signed int8 out_data[4] = {0, 0, 0, 0};
short nec_ok = 0, repeated = 0;
int8 i, nec_state = 0;
int32 nec_code;
#INT_EXT // External interrupt
void ext_isr(void){
int16 time;
if(nec_state != 0){
time = get_timer1(); // Store Timer1 value
set_timer1(0); // Reset Timer1
}
switch(nec_state){
case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse)
setup_timer_1( T1_INTERNAL | T1_DIV_BY_2 ); // Enable Timer1 module with internal clock source and prescaler = 2
set_timer1(0); // Reset Timer1 value
nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space)
i = 0;
ext_int_edge( L_TO_H ); // Toggle external interrupt edge
return;
case 1 : // End of 9ms pulse
if((time > 9500) || (time < 8500)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
setup_timer_1(T1_DISABLED); // Stop Timer1 module
}
else
nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse)
ext_int_edge( H_TO_L ); // Toggle external interrupt edge
return;
case 2 : // End of 4.5ms space
if((time > 5000) || (time < 1500)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
setup_timer_1(T1_DISABLED); // Stop Timer1 module
return;
}
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
if(time < 3000) // Check if previous code is repeated
repeated = 1;
ext_int_edge( L_TO_H ); // Toggle external interrupt edge
return;
case 3 : // End of 562µs pulse
if((time > 700) || (time < 400)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
setup_timer_1(T1_DISABLED); // Disable Timer1 module
}
else{
// Check if the code is repeated
if(repeated){
set_timer3(25000);
repeated = 0;
nec_ok = 1; // Decoding process is finished with success
return;
}
nec_state = 4; // Next state: end of 562µs or 1687µs space
}
ext_int_edge( H_TO_L ); // Toggle external interrupt edge
return;
case 4 : // End of 562µs or 1687µs space
if((time > 1800) || (time < 400)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
setup_timer_1(T1_DISABLED); // Disable Timer1 module
return;
}
if( time > 1000) // If space width > 1ms (short space)
bit_set(nec_code, (31 - i)); // Write 1 to bit (31 - i)
else // If space width < 1ms (long space)
bit_clear(nec_code, (31 - i)); // Write 0 to bit (31 - i)
i++;
if(i > 31){ // If all bits are received
nec_ok = 1; // Decoding process OK
}
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
ext_int_edge( L_TO_H ); // Toggle external interrupt edge
}
}
#INT_TIMER1 // Timer1 interrupt (used for time out)
void timer1_isr(void){
nec_ok = 0;
nec_state = 0; // Reset decoding process
ext_int_edge( H_TO_L ); // External interrupt edge from high to low
setup_timer_1(T1_DISABLED); // Disable Timer1 module
clear_interrupt(INT_TIMER1); // Clear Timer1 interrupt flag bit
}
#INT_TIMER3 // Timer1 interrupt (used for time out)
void timer3_isr(void){
nec_code = 0;
setup_timer_3(T3_DISABLED); // Disable Timer3 module
clear_interrupt(INT_TIMER3); // Clear Timer3 interrupt flag bit
}
void main(){
delay_ms(500);
usb_init(); // Initialize USB hardware
enable_interrupts(GLOBAL); // Enable global interrupts
enable_interrupts(PERIPH);
enable_interrupts(INT_EXT_H2L); // Enable external interrupt
clear_interrupt(INT_TIMER1); // Clear Timer1 interrupt flag bit
enable_interrupts(INT_TIMER1); // Enable Timer1 interrupt
clear_interrupt(INT_TIMER3); // Clear Timer3 interrupt flag bit
enable_interrupts(INT_TIMER3); // Enable Timer3 interrupt
while(TRUE){
if(nec_ok){ // If the mcu successfully receives NEC protocol message
nec_ok = 0; // Reset decoding process
nec_state = 0;
setup_timer_1(T1_DISABLED); // Disable Timer1 module
set_timer3(25000);
setup_timer_3( T3_INTERNAL | T1_DIV_BY_8 ); // Enable Timer3 module with internal clock source and prescaler = 8
if(nec_code == 0x40BF30CF) // Button 1 code (mouse left button)
out_data[0] = 1;
if(nec_code == 0x40BFB04F) // Button 2 code (move cursor up)
out_data[2] = -1;
if(nec_code == 0x40BF708F) // Button 3 code (mouse right button)
out_data[0] = 3;
if(nec_code == 0x40BF08F7) // Button 4 code (move cursor left)
out_data[1] = -1;
if(nec_code == 0x40BF8877) // Button 5 code (move cursor down)
out_data[2] = 1;
if(nec_code == 0x40BF48B7) // Button 6 code (move cursor right)
out_data[1] = 1;
while(nec_code != 0)
usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE); // Send USB packet
delay_ms(10);
out_data[0] = 0;
out_data[1] = 0;
out_data[2] = 0;
usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE); // Send USB packet
}
}
}
ไม่มีความคิดเห็น:
แสดงความคิดเห็น