📄 main.c
字号:
// AVR Project :: AVR + Sony Decoder
// MCU : ATMega16 , IR Device :: TSOP4838 used for XTAL 16MHz
// by wlasoi@hotmail.com , 24, September 2007
// Dept. of Physics, Fact. of Science, Ubonrajathanee University
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include "delay.h"
#include "myDef.h"
#include "uart.h"
//**************************** Global Constant + Variable ***********************//
const char usartPGM0[] PROGMEM = " >> AVR Project :: AVR + Sony Decoder \n\r";
const char usartPGM1[] PROGMEM = " >> MCU : ATMega16 , IR Device :: TSOP4838 used for XTAL 16MHz \n\r";
const char usartPGM2[] PROGMEM = " >> by wlasoi@hotmail.com\n\r";
const char usartPGM3[] PROGMEM = " >> 24, September 2007\n\r";
PGM_P usartPointer[5] PROGMEM = {usartPGM0,usartPGM1,usartPGM2,usartPGM3};
static volatile unsigned int RC_BUFFER[12];
enum{
STOP = 0,
ICP_CK = 1,
ICP_CK8 = 2,
ICP_CK64 = 3,
ICP_CK256 = 4,
ICP_CK1024 = 5,
ICP_T0_FALLING_EDGE = 128, /* 0x80 */
ICP_T0_RISING_EDGE = 192, /* 0xC0 */
ICP_DISABLE = 0
};
//Port for IR detector used PD6-Input Capture Pin
#define rc5Delay 250 // 250 ms delay
#define FallingCapture (ICP_T0_FALLING_EDGE | ICP_CK8)
#define RissingCapture (ICP_T0_RISING_EDGE | ICP_CK8)
#define DiableCapture ICP_DISABLE
#define upperCheck_Bit_0 1480 // Bit0 pulse period error upper-Torelance
#define lowerCheck_Bit_0 1280 // Bit0 pulse period error lower-Torelance
#define upperCheck_Bit_1 780 // Bit1 pulse period error upper-Torelance
#define lowerCheck_Bit_1 640 // Bit1 pulse period error lower-Torelance
#define upperCheck_Start 2800 // SatrtBit pulse period error upper-Torelance
#define lowerCheck_Start 2550 // StartBit pulse period error lower-Torelance
volatile unsigned int timeCapture;
volatile unsigned char count=0;
static volatile unsigned int RC5_Start;
static volatile unsigned int RC5_Stop;
static volatile unsigned int ChkRC_bit9;
static volatile unsigned char outData;
static volatile unsigned char customData;
static volatile unsigned char delayRC5=0;
static volatile unsigned char captureStatus=0;
static volatile unsigned char RC5disableFlag=0;
//************************ prototype ICP function ***********************************//
extern void initCapture1(void);
extern unsigned int rc5Decoder(void);
extern void EnableICP1(void);
extern void DisableICP1(void);
//****************************** ICP function ***************************************//
extern void initCapture1(void)
{
// used for XTAL 16MHz
// ICNC1: Input Capture Noise Canceler --> 1 Noise Control
// ICES1: Input Capture Edge Select --> 0 Falling edge
// CS12:10: Clock Select --> 010 = 8 clkIO/8 (From prescaler)
// Use 16,000,000 Hz X-tal , Div8 ~ 0.5uS / count
// (ICR1 >> 1) = (ICR1/2) ----> timing pf pulse / second
// bit start ~ 2550-2800 uS >> lower,upper
// bit 0 ~ 1280-1480 uS >> lower,upper
// bit 1 ~ 640-780 uS >> lower,upper
TCNT1 = 0x00;
TIMSK |= (1<<TICIE1);
TCCR1B = FallingCapture; // --> 0x83
}
extern void EnableICP1(void)
{
TCNT1 = 0x00;
TCCR1B = FallingCapture; //set next capture1 stop if Rising Edage
TIMSK |= (1<<TICIE1); //Enable ICP1 interrupt
}
extern void DisableICP1(void)
{
TCCR1B = DiableCapture; //set prescala = 0
TIMSK |= (0<<TICIE1); //disable ICP1 interrupt
}
extern unsigned int rc5Decoder(void)
{
unsigned RC5temp,temp=0;
RC5temp=0;
temp=0;
// turn off ICP1 Interrupt
TCCR1B = DiableCapture; //set prescala = 0
TIMSK |= (0<<TICIE1); //disable ICP1 interrupt
ChkRC_bit9 = RC_BUFFER[8]; // Check bit9 alway to be "0"
RC5_Stop = RC_BUFFER[12];
RC5_Start = RC_BUFFER[0];
if((ChkRC_bit9 > lowerCheck_Bit_0) && (ChkRC_bit9 < upperCheck_Bit_0) && (RC5_Start >= lowerCheck_Start) && (RC5_Start <= upperCheck_Start) && (RC5_Stop >= lowerCheck_Start) && (RC5_Stop <= upperCheck_Start)){
outData=0; // Shift 8bit data binary to variable
for(unsigned char i=1;i<=8;i++)
{
if ((RC_BUFFER[i] > lowerCheck_Bit_0) && (RC_BUFFER[i] < upperCheck_Bit_0)){ // if bit0 shift "0" to outdata
outData |= (0 << (i-1));
}
if ((RC_BUFFER[i] > lowerCheck_Bit_1) && (RC_BUFFER[i] < upperCheck_Bit_1)){ // if bit1 shift "1" to outdata
outData |= (1 << (i-1));
}
}
customData=0; // Shift 3bit data binary to variable
for(unsigned char i=9;i<=11;i++)
{
if ((RC_BUFFER[i] > lowerCheck_Bit_0) && (RC_BUFFER[i] < upperCheck_Bit_0)){ // if bit0 shift "0" to outdata
customData |= (0 << (i-1));
}
if ((RC_BUFFER[i] > lowerCheck_Bit_1) && (RC_BUFFER[i] < upperCheck_Bit_1)){ // if bit1 shift "1" to outdata
customData |= (1 << (i-1));
}
}
RC5temp = (unsigned int)((customData<< 8) | outData);
for(unsigned char i=0;i<=12;i++) // clear RC_BUFFER
{
RC_BUFFER[i]= 0;
}
ChkRC_bit9 = 0;
RC5_Start = 0;
RC5_Stop = 0;
outData = 0;
customData=0;
count = 0;
captureStatus=0;
// turn on ICP1 Interrupt
TCCR1B = FallingCapture; //set prescala = 0
TIMSK |= (1<<TICIE1); //disable ICP1 interrupt
return RC5temp;
}else{
for(unsigned char i=0;i<=12;i++) // clear RC_BUFFER
{
RC_BUFFER[i]= 0;
}
RC5temp = 0;
ChkRC_bit9 = 0;
RC5_Start = 0;
RC5_Stop = 0;
outData = 0;
customData=0;
count = 0;
captureStatus=0;
// turn on ICP1 Interrupt
TCNT1 = 0x00;
TCCR1B = FallingCapture; //set next capture1 stop if falling Edage
TIMSK |= (1<<TICIE1);
return -1; //return error
}
}
//*************************** main Program ***************************************//
int main (void)
{
unsigned int intTemp;
initCapture1();
USART_Init(USART_BAUD_SELECT(USART_BAUD_RATE,F_CPU));
sei();
usart_puts_p(usartPointer[0]);
usart_puts_p(usartPointer[1]);
usart_puts_p(usartPointer[2]);
usart_puts_p(usartPointer[3]);
while(1)
{
if(captureStatus)
{
intTemp = rc5Decoder();
DisableICP1();
usart_16bitHex(intTemp);
usart_puts("\n\r");
delay_ms(rc5Delay);
captureStatus = 0;
EnableICP1();
}
}/* End of While() loop */
return 0;
}/* Eend of main() loop */
//******************************* ICP ISR *************************************//
SIGNAL(SIG_INPUT_CAPTURE1)
{
//check Interrupt and set ICP to Falling edge detect
if(TCCR1B == FallingCapture)
{
TCCR1B = RissingCapture; //set next capture1 stop if Rising Edage
TCNT1 = 0x00;
}
//check Interrupt and set ICP to Rissing edge detect
else if(TCCR1B == RissingCapture)
{
timeCapture = ICR1;
// Use 16,000,000 Hz X-tal , Div8 ~ 0.5uS / count
// (ICR1 >> 1) = (ICR1/2) ----> period of pulse in uS range.
timeCapture = (timeCapture>>1); // ---> timeCapture/2
RC_BUFFER[count] = timeCapture; // kepp Timming to RC_BUFFER[count]
RC5_Start = RC_BUFFER[0];
if((count < 13) && (RC5_Start >= lowerCheck_Start) && (RC5_Start <= upperCheck_Start)){ // Set to next falling Edge Capture
TCNT1 = 0x00;
TCCR1B = FallingCapture;
count++;
}else if((count==13) && (RC5_Start >= lowerCheck_Start) && (RC5_Start <= upperCheck_Start)){ //if Compleate data 13 bit,just to Encoder RC5
TCCR1B = DiableCapture; //set prescala = 0
TIMSK |= (0<<TICIE1); //disable ICP1 interrupt
captureStatus=1;
}else{ // check Error and Clear RC_BUFFER
for(unsigned char i=0;i<=12;i++)
{
RC_BUFFER[i] = 0;
}
RC5_Start=0;
captureStatus=0;
count = 0;
TCNT1 = 0x00; // Restart ICP1 to wait Falling edge
TCCR1B = FallingCapture;
}
}
}
//***************************** End ICP ISR ***********************************//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -