/* 직렬 포트 통신을 이용한 LED 컨트롤 */

#include <avr/io.h>

#define CPU_CLOCK 16000000  // MCU의 속도
#define BAUD_RATE 4800    // 통신 속도
#define BAUD_RATE_L (CPU_CLOCK/(16l*BAUD_RATE))-1
#define BAUD_RATE_H ((CPU_CLOCK/(16l*BAUD_RATE))-1)>>8
// 통신속의 결과 값을 입력하기 위해 상하위 비트로 구분
//16l은 16+L, 연산시 값이 너무 커져 overflow발생하므로 32비트 연산
//위해 16에 long을 의미하는 l을 붙임

void init_USART1(void);
unsigned char USART_Receive(void);
void uart_send_byte(unsigned char byte);
void uart_send_string(unsigned char *str, unsigned char len);

int main(void)
{
  unsigned char buf[]="Hellow DK128!";
  unsigned int i;
  unsigned char ch;
  
  DDRF=0xff;
  PORTF=0xff;
  
  init_USART1();
  
  while(1)
  {
  ch =((USART_Receive())-48);
  if(ch==0)
  {
  PORTF=0xff;
  }
  else
  {
  PORTF=~(1<<(ch-1));
  uart_send_byte(ch+48);
  }
  asm("NOP");
  }
  return 1;
}

/* 전체 문자를 전송하기 위한 함수 */
void uart_send_string(unsigned char *str, unsigned char len)
{
  int i;
  for(i=0; i<len; i++)
  {
    if( !(*(str+i)))
    {
      break;
    }
    uart_send_byte(*(str+i));
  }
}

/* 시리얼 통신을 송신 함수 */
void uart_send_byte(unsigned char byte)
{
  while (!(UCSR1A&(1<<UDRE)));  // 전송 버퍼가 비었을 때 까지 대기
  UDR1 = byte;  // 문자 1개씩 전송
}

/* 시리얼 통신을 수신 함수 */
unsigned char USART_Receive(void)
{
  /* 데이터 수신 대기 */
  while(!(UCSR1A&(1<<RXC)))
  {
  
  }
  /* 버퍼에 수신된 데이터를 가져와 리턴 */
  return UDR1;
}

/* 시리얼 통신 포트 1번 사용 함수 */
void init_USART1(void)
{
  UBRR1L = (unsigned char)BAUD_RATE_L;
  UBRR1H = (unsigned char)BAUD_RATE_H;
  
  UCSR1C = (0<<UPM1)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
  UCSR1B = (1<<TXEN)|(1<<RXEN)|(0<<UCSZ2);
}

/* 직렬 포트 통신 */

#include <avr/io.h>

#define CPU_CLOCK 16000000  // MCU의 속도
#define BAUD_RATE 4800    // 통신 속도
#define BAUD_RATE_L (CPU_CLOCK/(16l*BAUD_RATE))-1
#define BAUD_RATE_H ((CPU_CLOCK/(16l*BAUD_RATE))-1)>>8
// 통신속의 결과 값을 입력하기 위해 상하위 비트로 구분
//16l은 16+L, 연산시 값이 너무 커져 overflow발생하므로 32비트 연산
//위해 16에 long을 의미하는 l을 붙임

int main(void)
{
  unsigned char buf[]="Hellow DK128!";
  unsigned int i;
  
  init_USART1();
  
  while(1)
  {
  uart_send_string(buf,sizeof(buf));
  }
  return 1;
}

/* 전체 문자를 전송하기 위한 함수 */
void uart_send_string(unsigned char *str, unsigned char len)
{
  int i;
  for(i=0; i<len; i++)
  {
    if( !(*(str+i)))
    {
      break;
    }
    uart_send_byte(*(str+i));
  }
}

/* 시리얼 통신을 보내는 함수 */
void uart_send_byte(unsigned char byte)
{
  while (!(UCSR1A&(1<<UDRE)));  // 전송 버퍼가 비었을 때 까지 대기
  UDR1 = byte;  // 문자 1개씩 전송
}

/* 시리얼 통신 포트 1번 사용 함수 */
void init_USART1(void)
{
  UBRR1L = (unsigned char)BAUD_RATE_L;
  UBRR1H = (unsigned char)BAUD_RATE_H;
  
  UCSR1C = (0<<UPM1)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
  UCSR1B = (1<<TXEN)|(1<<RXEN)|(0<<UCSZ2);
}



// 두더지 잡기 게임
#include <stdlib.h>
#include "header/io.h"

#define LED_DDR DDRF
#define LED_OUT PORTF
#define KEY PINC
#define FND_DDR DDRE
#define FND_OUT PORTE

#define CPU_CLOCK 16000000
#define TICKS_PER_SEC 1000
#define PRESCALER 128

volatile unsigned int g_elapsed_time; // 시간변수

/* 함수 원형 설정 */
void sleep(unsigned int elapsed_time); // sleep함수
void init_LED(void); // LED포트 초기화 함수 원형
void init_TIMER(int timers); // Timer Counter 설정
void init_TC0(void); // Timer0 초기화 함수 원형
void delay(char *a, int speed); // SW입력 대기 함수 원형

int main()
{
/* 변수 설정 */
char count;
char t_count=0;
char led=1;
char score=0;
char score1=0;
char fnd=0;
int delay_ms;
/* 사용 설정 초기화 */
SREG = SREG|(1<<7); // 전체 인터럽트 활성화
DDRC=0x00;
init_LED(); // LED포트 초기화
init_TC0(); // Timer0 초기화
init_TIMER(OCIE0); // 타이머 설정
OCR0 = 0x7D; // 비교매치 인터럽트 비교값 설정
sei(); // 인터럽트 활성화 함수

/* 프로그램 작성 시작 */
while(1) //  난수 함수 시작점을 다르게하기 위한 무한 루프
{
delay_ms=500;
t_count++;
for(count=0; 8>count; count++)
{
LED_OUT=~(1<<count);
delay(&fnd, delay_ms);
if(5==fnd) // 0+1번 스위치가 눌려지면 두더지 게임 시작
{
for(count=0; 8>=count; count++)
{
LED_OUT=~(1<<count);
sleep(200);
}
LED_OUT=0x00;
FND_OUT=0x00;
for(count=5; 1<=count; count--) // 게임 시작 카운트 5~0
{
LED_OUT=0xff;
sleep(500);
LED_OUT=0x00;
FND_OUT=count+(count<<4);
sleep(500);
}
LED_OUT=0xff;
FND_OUT=0;
sleep(1000); // 게임 시작전 0.5초 지연
srand((unsigned int)t_count); // 난수 발생 함수
delay_ms=1000;
break; // 게임 시작을 위해 무한루프 브레이크
}
}
if(5==fnd)
{
fnd=0;
break;
}
}
/* 두더지 게임 시작 */
for(count=0; ;) // 무한 루프
{
for(count=0; count<25; count++) // 25번의 두더지 생성(LED On/off)
{
LED_OUT = ~(led<<rand()%7); // 두더지(LED)의 생성 위치 변경
delay(&fnd, delay_ms); // 1초간 지연하면서 스위치 입력 대기
if(2==fnd) // 두더지를 잡으면 점수 5점씩 올림
{
fnd=0;
score += 5;
if(score==0x0a)
{
score=0x00;
score1+=0x10;
}
}
else if(score1==0xa0||10==fnd) // 6+7번SW or 점수가 100점이 되면 FND,LED on/off 6회반복
{
score=0x00;
score1=0x00;
LED_OUT=0x00;
FND_OUT=0x00;
for(count=0; 6>=count; count++)
{
LED_OUT=~LED_OUT;
FND_OUT=~FND_OUT;
sleep(200);
}
sleep(2000);
FND_OUT=0;
fnd=0;
break; // on/off 6회 반복 끝나면 프로그램 종료!
}
FND_OUT = score+score1; // 점수 표시
LED_OUT = 0xff; // 두더지 숨기(LED off)
sleep(1000); // 1초 지연
}
delay_ms-=200;
if(25<=count) // 100점이면 게임 계속 실행
{ // 100점미만이면 게임 종료
return 0;
}
}
return 1;
}


/* 1초간 스위치 입력 대기 */
void delay(char *a, int speed)
{
g_elapsed_time=0;
while(g_elapsed_time<speed)
{
if(KEY == 0xfc) // 0~1번 SW Start
{
*a=5; // fnd변수에 5대입
break;
}
else if(KEY == 0x3f) // 6~7번 SW clear
{
*a=10; // fnd변수에 10대입
break;
}
else if(LED_OUT == KEY) // LED와 스위치가 같이 같으면 실행
{
*a=2; // fnd변수에 2대입
break;
}
}
}

/* LED포트 초기화 설정 함수 */
void init_LED(void)
{
LED_DDR = 0xFF; // PORTF 출력모드 설정
LED_OUT = 0xFF; // PORTF 초기화
FND_DDR = 0xFF;
FND_OUT = 0x00;
}

/* 타이머 설정 함수 */
void init_TIMER(int timers)
{
TIMSK=(1<<timers);
}

/* Timer0 초기화 설정 함수 */
void init_TC0(void)
{
//TCCR0 = 0x0D; // TCCR0 CTC모드 설정 / 분주비 설정
TCCR0 = 1<<2|0<<1|0<<0; // 이런식으로 설정도 가능함
}

/* 딜레이 함수 */
void sleep(unsigned int elapsed_time)
{
g_elapsed_time=0;
while(g_elapsed_time<elapsed_time)
{
}
}

/*     시그널 함수 */
/*  비교매치 인터럽트 */
void __vector_15(void)
{
g_elapsed_time++;
}

// 각각 LED 난수 발생 on/off
//#include <avr/io.h>
#include "portio.h"
#include "TC0.h"
#include <stdlib.h>

#define LED_DDR DDRF
#define LED_OUT PORTF

#define CPU_CLOCK 16000000
#define TICKS_PER_SEC 1000
#define PRESCALER 128

volatile unsigned int g_elapsed_time; // 시간변수
void sleep(unsigned int elapsed_time); // sleep함수
//SIGNAL(SIG_OVERFLOW0); // timer0의 오버플로우 시그널함수
//SIGNAL(SIG_OUTPUT_COMPARE0); // timer0의 비교매치 시그널함수

int minute(int sec);

void init_LED(void); // LED포트 초기화 함수 원형
void init_TIMER(int timers); // Timer Counter 설정
void init_TC0(void); // Timer0 초기화 함수 원형


int main()
{

int count;
SREG = (1<<7)|SREG; // 전체 인터럽트 활성화
init_LED(); // LED포트 초기화
init_TC0(); // Timer0 초기화
init_TIMER(OCIE0); // 타이머 설정
OCR0 = 0x7D; // 비교매치 인터럽트 비교값 설정
//TCNT0 = 0x83; // 오버플로 인터럽트 시작점 설정
//TIFR |= 0x01; // TOV0 오버플로 클리어
sei(); // 인터럽트 활성화 함수
srand((unsigned int)CPU_CLOCK); // 난수 발생 함수

while(1)
{
for(count=0; 7>=count; count++)
{
asm("NOP");
LED_OUT=~(rand()%2<<count); // 난수 LED / ON
sleep(500);
//LED_OUT=0xFF; // LED off
//sleep(500);
}
}
return 1;
}
// LED포트 초기화 설정 함수
void init_LED(void)
{
LED_DDR = 0xFF; // PORTF 출력모드 설정
LED_OUT = 0xFF; // PORTF 초기화
}
// 타이머 설정 함수
void init_TIMER(int timers)
{
TIMSK=(1<<timers);
}
// Timer0 초기화 설정 함수
void init_TC0(void)
{
//TCCR0 = 0x0D; // TCCR0 CTC모드 설정 / 분주비 설정
TCCR0 = 1<<2|0<<1|0<<0; // 이런식으로 설정도 가능함
}

int minute(int sec)
{
int min;
min=min|sec;
return min;
}

void sleep(unsigned int elapsed_time)
{
g_elapsed_time=0;
while(g_elapsed_time<elapsed_time)
{
}
}

/*     시그널 함수 */
/*  비교매치 인터럽트 */
void __vector_15(void)
{
g_elapsed_time++;
}

/* 오버플로 인터럽트
SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 256-(((CPU_CLOCK/TICKS_PER_SEC)/PRESCALER));
g_elapsed_time++;
}
*/


T/C 총 4가지.
T/C 0, 2 = 8bit
T/C 1, 3 = 16bit

T/C0 을 사용할 것임.

XTAL = 16Mhz 사용 (1초당 16만번의 클럭발생) 
1/1000로 클럭을 나눔 = 1000번을 수행해야 1초

// FND(60초) LED(60초마다 on) Count 오버플로인터럽트 사용
#include <avr/stdio.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

#define CPU_CLOCK  16000000
#define TICKS_PER_SEC  1000
#define PRESCALER  64

volatile unsigned int g_elapsed_time;  // 시간변수
void sleep(unsigned int elapsed_time);  // sleep함수
SIGNAL(SIG_OVERFLOW0);      // timer0의 오버플로우 시그널함수

int main()
{
  int min=0;
  int sec=0;
  int total=0;
  DDRC = 0xFF;  // PORTC 출력모드 설정
  DDRF = 0xFF;  // PORTF 출력모드 설정
  PORTF = 0xFF;  // PORTF 초기화
  PORTC = 0x00;  // PORTC 초기화
  TCCR0 = 0x04;  // TCCR0 노말모드 설정
  TCNT0 = 0x06;  // TCNT0 초기화
  TIMSK = 0x01;  // 오버플로 인터럽트 설정
  //TIFR |= 0x01;  // TOV0 오버플로 클리어    
  SREG = (1<<7)|SREG;  // I비트 1설정
  sei();    // 인터럽트 활성화 함수

  while(1)
  {
    asm("NOP");

    if(9>=total)
    {
      sleep(1000);
      total++;
      sec++;
    }
    else if(0x50>=sec)
    {
      total=0;
      sec=0;
      min=min+0x10;
      sec=min;
    }
    else if(0>=PORTF)
    {
      PORTF=0xFF;
    }
    else
    {
      total=0;
      sec=0;
      min=0;
      PORTF=PORTF<<1;
    }
    PORTC=sec;
  }
  return 1;
}

void sleep(unsigned int elapsed_time)
{
  g_elapsed_time=0;
  while(g_elapsed_time<elapsed_time)
  {
  }
}

SIGNAL(SIG_OVERFLOW0)
{
  TCNT0 = 0x06;
  g_elapsed_time++;
}



_M#]



+ Recent posts