#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
//------------------------------------------------------------------
//bit제어를위해 설정
#define sbit(x,y) (x |= (1<<y))
#define cbit(x,y) (x &= ~(1<<y))
#define tbit(x,y) (x & (1<<y))
//------------------------------------------------------------------
volatile uint8_t msec,m00;
volatile int16_t seed;
volatile uint8_t key1,key1_temp,key_flag,start_flag;
volatile uint8_t key1_on,key1_up,key1_down;
volatile uint8_t data[128],data_count,data_count_end,key_data,timer;
//==================================================================
void port_init(void)
{
DDRC = 0xF0; // PC7-PC4 = LED output
PORTC = 0x00;
//
DDRF = 0x00; // PORTF = KEY input
PORTF = 0xFF;
}
//==================================================================
void timer_init(void)
{
TCCR0 = 0x0C; // 1/64
ASSR = 0x00;
OCR0 = 249; // 16MHz/64/(1+249) = 1ms
TCNT0 = 0x00;
TIMSK = 0b00000010; // enable OC0 interrupt
TIFR = 0x00;
}
//------------------------------------------------------------------
prog_int8_t data_table[4] = {0x10,0x20,0x40,0x80};
//==================================================================
void keyread(void)
{
unsigned char i,j;
//
key1=~PINF&0xf0; //값을 읽어와 필요부분만 유효화한다.
//------------------------------------------------------------------
if(key1_temp==key1) //2회 동일값이면
{
//---------------------------------------------키를 누를때 1회 on
i=key1_on; //이전값
j=key1_temp; //현재값
j=(i^j)&j; //새로운값만 유효
key1_down=j;
//---------------------------------------------키를 눌렀다 뗄때 1회ON
j=key1_temp; //현재값
j=(i^j)&i; //off된 이전값만 유효
key1_up=j;
//---------------------------------------------키가눌려져 있는 동안 on
key1_on=key1_temp; //현재값
}
//---------------------------------------------이전 값과 일치하지 않으면
else key1_temp=key1;
}
//==================================================================
//10ms 마다 이함수로 진입
//------------------------------------------------------------------
void plc(void)
{
uint8_t i;
//------------------------------------------------------------------
if(data_count_end>100) start_flag=0;//최대 100회 반복
//start
if(start_flag==0)
{
srand(seed);
data_count=0;
data_count_end=0;
start_flag=1;
key1_down=0;
for(i=0;i<100;i++)//난수 100개를 저장
{
data[i] = rand()%4;
}
}
//data 표시
if(start_flag==1)//
{
timer++;
if(timer<50)
{
m00=pgm_read_byte(&data_table[data[data_count_end]]);
}
else
{
timer=0;
m00=0;
start_flag=2;
}
}
//key 변환
if(start_flag==2)//
{
if(key1_down>0)
{
if(tbit(key1_down,4)) key_data=0;
else if(tbit(key1_down,5)) key_data=1;
else if(tbit(key1_down,6)) key_data=2;
else key_data=3;
start_flag=3;
}
}
//check
if(start_flag==3)//
{
if(key_data==data[data_count])
{
data_count++;
start_flag=2;
if(data_count>data_count_end)
{
start_flag=1;
data_count=0;
data_count_end++;
}
}
else
{
start_flag=4;
}
}
//error
if(start_flag==4)//
{
timer++;
if(timer<100)
{
m00=0xff;
}
else if(timer<150)
{
timer=0;
m00=0x00;
start_flag=0;
}
}
//-------------------------------------------------------------------
//out
PORTC=(PORTC&0x0f)|m00;
//
key1_down=0;key1_up=0;
}
//---------------------------------------------------------------------
ISR(TIMER0_COMP_vect) // OC0 interrupt function
{
sei(); //인터럽트 허용
msec++;
if(msec==10)//10ms
{
msec=0;
seed++; //난수의 씨앗
keyread();
plc(); // 10ms를 초과하지말것.(가능하면 5ms이내로할것.)
}
}
//=======================================================================
int
main (void)
{
port_init();
timer_init();
sei();
while(1)
{
}
}
이런 작업은 직접하시는게 좋을 듯 합니다
컴파일러에 따라 달라지는 아래 구문과 DDR Port정도만. 변경해주시면됩니다.
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
//-------------------