BASIC4MCU | 질문게시판 | 제가 짠 코드 엉망진창이네요 조언받습니다 ㅠ
페이지 정보
작성자 우왕우오옹 작성일2020-10-16 21:14 조회6,377회 댓글3건본문
리모컨 수신 코드를 짜봣는데 리모컨 입력시 삑삑거리기는하는데 전원버튼을누르면 전원이라고 LCD에 출력을하는 프로그램을짜보고싶은데 어떤식으로해야할까요
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "OK-2561BR.h"
// Leader_Code = 141
// Low_Bit = 18
// High_Bit = 35
#define Leader_Max 155
#define Leader_Min 126
#define Low_Bit_Max 20
#define Low_Bit_Min 15
#define High_Bit_Max 39
#define High_Bit_Min 31
volatile unsigned char Remocon_state; // step to recognize remocon signal
volatile unsigned char Remocon_count; // 64us base time counter
volatile unsigned char Remocon_data; // temporary byte data of remocon signal
volatile unsigned char Remocon_bit_count; // bit count of data to recognize remocon signal
volatile unsigned char Remocon_OK_flag; // remocon command receive OK
volatile unsigned char Remocon_command[4]; // remocon command string
/* ----- 인터럽트 처리 프로그램 ------------------------------------------------ */
ISR(TIMER3_OVF_vect) /* Timer1 overflow interrupt with 64us*256 period */
{
Remocon_state = 0; // if overflow, the signal is noise
}
ISR(INT7_vect) /* INT6 interrupt by remocon signal */
{
Remocon_count = TCNT1; // read Remocon_count
TCNT1 = 0; // start new Remocon_count
sei(); // global interrupt enable
switch(Remocon_state)
{ case 0 : // if ready state, go to step 1(leader state)
Remocon_state = 1;
Remocon_count = 0;
break;
case 1 : // if leader state, check leader signal
if((Remocon_count >= Leader_Min) && (Remocon_count <= Leader_Max))
{ Remocon_state = 2; // if lead signal, go to step 2(data state)
Remocon_count = 0;
Remocon_data = 0;
Remocon_bit_count = 0;
}
else
Remocon_state = 0; // if not lead signal, go to step 0(ready state)
break;
case 2: // if data state, check data signal 0 or 1
Remocon_data >>= 1;
if((Remocon_count >= Low_Bit_Min) && (Remocon_count <= Low_Bit_Max))
Remocon_data &= 0x7F; // if data 0, add data bit 0
else if((Remocon_count >= High_Bit_Min) && (Remocon_count <= High_Bit_Max))
Remocon_data |= 0x80;
else
Remocon_state = 0; // if not 0 and not 1, go to step 0(ready state)
Remocon_count = 0;
Remocon_bit_count++;
if((Remocon_bit_count % 8) == 0) // if a character complete, store it
{ Remocon_command[(Remocon_bit_count/16)-1] = Remocon_data;
Remocon_data = 0;
}
if(Remocon_bit_count == 32) // if remocon OK, check custom code and checksum
{ if((~Remocon_command[2] & 0xFF) == Remocon_command[3])
{ Remocon_state = 0;
Remocon_OK_flag = 1;
}
else
Remocon_state = 0;
}
break;
default : break;
}
}
/* ----- 메인 프로그램 --------------------------------------------------------- */
int main(void)
{
MCU_initialize(); // initialize ATmega128A MCU
Delay_ms(50); // wait for system stabilization
LCD_initialize(); // initialize text LCD module
// initialize TFT-LCD module
LCD_Cursor(0,1);
LCD_string("OK-2561BR V1.0");
LCD_Cursor(1,2);
LCD_string("REMOCON Test");
Beep();
TCCR1A = 0x01; // Timer 1, mode 5(fast PWM with 0x00FF period)
TCCR1B = 0x0D; // 16MHz/1024 = 15625Hz (64us base time)
TCCR1C = 0x00;
OCR1A = 62499; // clear Timer1 overflow interrupt flag
TCNT3 = 0x0000; // enable Timer1 overflow interrupt
Remocon_state = 0; // remocon ready state
Remocon_OK_flag = 0; // remocon not character
cbi(DDRE,7); // PE6(INT6) = input
EICRB = 0x20; // INT6 = falling edge trigger for remocon signal
EIFR = 0x80; // clear INT6 interrupt flag
EIMSK = 0x80; // enable INT6
sei(); // global interrupt enable
while(1)
{ if(Remocon_OK_flag == 1)
{ Remocon_OK_flag = 0;
LCD_Cursor(0,1); LCD_hexadecimal(Remocon_command[0],2); // code
LCD_Cursor(0,3); LCD_hexadecimal(Remocon_command[1],2);
LCD_Cursor(0,5); LCD_hexadecimal(Remocon_command[2],2);
LCD_Cursor(0,7); LCD_hexadecimal(Remocon_command[3],2);
Beep();
if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x02)) // function
LCD_string("전원");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x01))
LCD_string( "TV/외부입력 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x27))
LCD_string("TV/유선 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x11))
LCD_string("0 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x04))
LCD_string("1 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x05))
LCD_string("2 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x06))
LCD_string("3 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x08))
//LCD_string("4 ");
//else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x09))
LCD_string("5 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x0A))
LCD_string("6 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x0C))
LCD_string("7 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x0D))
LCD_string("8 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x0E))
LCD_string("9 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x12))
LCD_string("채널+ ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x10))
LCD_string("채널- ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x07))
LCD_string("음량+ ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x0B))
LCD_string("음량- ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x1D))
LCD_string("조정+ ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x1C))
LCD_string("조정- ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x0F))
LCD_string("조용히(음소거) ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x3A))
LCD_string("자동채널 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x13))
LCD_string("이전채널 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x19))
LCD_string("기억 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x18))
LCD_string("지움 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x3E))
LCD_string("화면크기 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x03))
LCD_string("취침예약 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x1A))
LCD_string("메뉴 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x4B))
LCD_string("간편메뉴 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x6B))
LCD_string("채널목록 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x4F))
LCD_string("방송안내 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x1F))
LCD_string("정보표시 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x60))
LCD_string("위로 이동 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x61))
LCD_string("아래로 이동 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x65))
LCD_string("좌로 이동 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x62))
LCD_string("우로 이동 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x68))
LCD_string("선택(확인) ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x58))
LCD_string("복귀(이전) ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x2D))
LCD_string("종료(나가기) ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x47))
LCD_string("동영상 재생 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x46))
LCD_string("동영상 정지 ");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x4A))
LCD_string("동영상 일시정지");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x48))
LCD_string("동영상 빨리감기");
else if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x45))
LCD_string("동영상 되감기 ");
else
LCD_string(" ");
}
}
}
댓글 3
조회수 6,377master님의 댓글
master 작성일
EICRB = 0x20; // INT6 = falling edge trigger for remocon signal
인터럽트 함수는 7을 사용하고 있으므로
위 설정에서 인터럽트 7의 트리거는 LOW LEVEL 트리거입니다. (인터럽트6은 하강엣지)
EICRB = 0x80; 을 사용하세요
우왕우오옹님의 댓글
우왕우오옹
수정해봤는데 리모컨을 제대로 수신을 못하네요 +추가로 수정해봣는데 여기서 잘못된거 있나요? (타이머3, int7)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "OK-2561BR.h"
// Leader_Code = 141 // 9ms / 64us = 140.625
// Low_Bit = 18 // 1.125ms / 64us = 17.578
// High_Bit = 35 // 2.25ms / 64us = 35.156
#define Leader_Max 155 // 110% of Leader_Code
#define Leader_Min 126 // 90% of Leader_Code
#define Low_Bit_Max 20 // 110% of Low_Bit_Code
#define Low_Bit_Min 15 // 90% of Low_Bit_Code
#define High_Bit_Max 39 // 110% of High_Bit_Code
#define High_Bit_Min 31 // 90% of High_Bit_Code
volatile unsigned char Remocon_state; // step to recognize remocon signal
volatile unsigned char Remocon_count; // 64us base time counter
volatile unsigned char Remocon_data; // temporary byte data of remocon signal
volatile unsigned char Remocon_bit_count; // bit count of data to recognize remocon signal
volatile unsigned char Remocon_OK_flag; // remocon command receive OK
volatile unsigned char Remocon_command[4]; // remocon command string
/* ----- 인터럽트 처리 프로그램 ------------------------------------------------ */
ISR(TIMER1_OVF_vect) /* Timer1 overflow interrupt with 64us*256 period */
{
Remocon_state = 0; // if overflow, the signal is noise
}
ISR(INT7_vect) /* INT6 interrupt by remocon signal */
{
Remocon_count = TCNT3; // read Remocon_count
TCNT3 = 0; // start new Remocon_count
sei(); // global interrupt enable
switch(Remocon_state)
{ case 0 : // if ready state, go to step 1(leader state)
Remocon_state = 1;
Remocon_count = 0;
break;
case 1 : // if leader state, check leader signal
if((Remocon_count >= Leader_Min) && (Remocon_count <= Leader_Max))
{ Remocon_state = 2; // if lead signal, go to step 2(data state)
Remocon_count = 0;
Remocon_data = 0;
Remocon_bit_count = 0;
}
else
Remocon_state = 0; // if not lead signal, go to step 0(ready state)
break;
case 2: // if data state, check data signal 0 or 1
Remocon_data >>= 1;
if((Remocon_count >= Low_Bit_Min) && (Remocon_count <= Low_Bit_Max))
Remocon_data &= 0x7F; // if data 0, add data bit 0
else if((Remocon_count >= High_Bit_Min) && (Remocon_count <= High_Bit_Max))
Remocon_data |= 0x80;
else
Remocon_state = 0; // if not 0 and not 1, go to step 0(ready state)
Remocon_count = 0;
Remocon_bit_count++;
if((Remocon_bit_count % 8) == 0) // if a character complete, store it
{ Remocon_command[(Remocon_bit_count/8)-1] = Remocon_data;
Remocon_data = 0;
}
if(Remocon_bit_count == 32) // if remocon OK, check custom code and checksum
{ if((~Remocon_command[2] & 0xFF) == Remocon_command[3])
{ Remocon_state = 0;
Remocon_OK_flag = 1;
}
else
Remocon_state = 0;
}
break;
default : break;
}
}
/* ----- 메인 프로그램 --------------------------------------------------------- */
int main(void)
{
MCU_initialize(); // initialize ATmega128A MCU
Delay_ms(50); // wait for system stabilization
LCD_initialize(); // initialize text LCD module
// initialize TFT-LCD module
LCD_Cursor(0,1);
LCD_string("OK-2561BR V1.0");
LCD_Cursor(1,0);
LCD_string("TV Remocon Input");
Beep();
Delay_ms(1500);
LCD_Cursor(1,0);
LCD_string("(**) ************");
Beep();
TCCR3A = 0x01; //TCCR3A = 0x01; // Timer 1, mode 5(fast PWM with 0x00FF period)
TCCR3B = 0x0D; // 16MHz/1024 = 15625Hz (64us base time)
TCCR3C = 0x00;
TIFR3 = 0x04; // clear Timer1 overflow interrupt flag
TIMSK3 = 0x04; // enable Timer1 overflow interrupt
Remocon_state = 0; // remocon ready state
Remocon_OK_flag = 0; // remocon not character
cbi(DDRE,7); // PE6(INT6) = input
EICRB = 0x80; // INT6 = falling edge trigger for remocon signal
EIFR = 0x80; // clear INT6 interrupt flag
EIMSK = 0x80; // enable INT6
sei(); // global interrupt enable
LCD_Cursor(1,0);
while(1)
{ if(Remocon_OK_flag == 1)
{ Remocon_OK_flag = 0;
Beep();
if((Remocon_command[0] == 0x07) && (Remocon_command[2] == 0x02)) // function
LCD_string("전원 ");
else
LCD_string("XXXXX");
}
}
}
master님의 댓글
master 작성일
https://cafe.naver.com/circuitsmanual/40823
https://cafe.naver.com/circuitsmanual/163219