더블클릭

main.c
#include "port.h"

#define LED_ON(led)    PORTF &= (~(0x01 << led))
#define LED_OFF(led)  PORTF |= (0x01 << led)

int main(void)
{
  unsigned int us = 0;
  unsigned int ms = 0;
  char click_count = 0;  // 
클릭 횟수 카운트
  char start_flag = 0;  // 
더블 클릭 시간감지 플래그
  char action = 0;    // 
클릭에 대한 액션을 결정

  DDRF = 0xff;  // 
포트 최기화
  PORTF = 0xff;
  DDRC = 0x00;
  PORTC = 0x00;
  
  while(1)
  {
    if(ms >= 500)  // 
시간 카운트 종료
    {
      start_flag = 0;
      ms = 0;
      action = click_count;
      click_count = 0;
    }
    else if((PINC & 0x01== 0)  // 
버튼을 눌렀을 
    {
      if(click_count == 0 || (click_count % 2== 0)
      {
        start_flag = 1;
        click_count++;  // 
버튼을 눌렀을  카운트 
      }
    }
    else if((PINC & 0x01&& start_flag)  // 
버튼 땠을 
    {
      if((click_count % 2== 1)
      {
        click_count++;  // 
버튼을 땠을  카운트
      }
    }

    us++;
    if(us >= 1000)
    {
      if(start_flag)  // 
시간 카운트 시작
      {
        ms++;
      }
      us = 0;
    }

    // 
클릭에 대한 동작 코드
    if(action)
    {
      LED_OFF(0);
      LED_OFF(1);
      LED_OFF(2);

      switch(action) 
      {
        case 1:
        case 2:
          LED_ON(0);  // 
 클릭 했을 
          break;
        case 3:
        case 4:
          LED_ON(1);  // 
더블 클릭 했을 
          break;
        case 5:
        case 6:
          LED_ON(2);  // 
트리플 클릭 했을 
          break;
        defalut :
          break;
      }
      action = 0;
    }
  }
  
  return 0;
}

// DK128에서 스위치 1번을 한번 클릭 했을 때 첫 번째 LED를 ON시키고, 더블 클릭 했을 때 두 번째 LED를 ON, 트리플 클릭 했을 때 세 번째 LED를 ON 시키는 코드이다.
// 스위치를 눌렀을 때 카운트를 하나씩 올리고 땔 때 다시 카운트를 올린다. 즉 카운트 값이 1이나2이면 한번 클릭을 한것이다.

FND 제어

delay_m.h
void delay(unsigned int ms);

void delay(unsigned int ms)
{
  unsigned int u = 0;
  unsigned int m = 0;

  while(1)
  {
    u++;
    if(u >= 1000)
    {
      m++;
      u=0;
    }
    if(m >= ms)
    {
      break;
    }
  }
}


main.c
#include "port.h"
#include "delay_m.h"

int main(void)
{
  unsigned char fnd1 = 0x00;  // 1
자리
  unsigned char fnd2 = 0x00;  // 10
자리

  DDRF = 0xff;  // 
 초기화
  PORTF = 0x00;
  DDRC = 0x00;
  PORTC = 0x00;
  
  while(1)
  {
    if((PINC & 0x01== 0)  // 
스위치를 눌렀을 
    {
      PORTF = fnd2 | fnd1;
    }
    else          // 
스위치가 눌러지지 않았을 
    {
      PORTF = fnd2 | fnd1;
      fnd1++;
      if(fnd1 >= 0x0A)  // 1
자리가 9 되면
      {
        fnd1 = 0x00;
        if(fnd2 == 0x90)  // 10
자리가 9 되면
        {
          fnd2 = 0x00;
        }
        else
        {
          fnd2 += 0x10;
        }
      }
    }
    delay(600);
  }
  return 0;
}
// 7-segment를 1부터 99까지 카운트하는 코드이다. 스위치를 누르면 카운트를 중지한다.
// 각 자리 수를 변수 2개를 OR연산해서 구현하였다.

포인터 연산

P5-4.c
#include <stdio.h>

int main()
{
  int inum;
  int *ip;
  short *sp;
  unsigned char *c;
  int i;

  inum = 0x0F5A0B43;
  ip = &inum;
  c = (unsigned char *)ip;

  printf("inum: %x  *ip: %p \n", inum, ip);
  sp = (short *)ip;  
  printf("sp: %p  *sp: %x \n", sp, *sp);
  sp++;    // short
형이라 증감연산시 2 증가 한다
  printf("sp: %p  *sp: %x \n", sp, *sp);

  for(i = 0 ; i < 4 ; i++)  // Little Endian
 확인하는 코드
  {
    printf("addr:%p  *c: %02x \n", c, *c);
    c++;  // char
형이라 증감연산시 1 증가 한다
  }

  return 0;
}


// 포인터 연산은 덧셈과 뺄셈만 허용된다. 덧셈과 뺄셈 연산 시 가리키는 자료형의 크기만큼 변한다.
// 인텔 x86 cpu들은 Little Endian 방식을 사용한다. 이를 확인하기 위해서 char형 포인터를 이용하여 1바이트씩 출력하여 확인할 수 있었다.

+ Recent posts