더블클릭
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바이트씩 출력하여 확인할 수 있었다.