2010. 4. 14. 10:05ㆍ2010년/4월
-network-
#include<stdio.h>
typedef struct _test
{
int a;
char b[4];
double c;
short d[2];
char e;
}TEST;
int main()
{
void *P;
TEST ex;
ex.a=10;
ex.b[0]='a';
ex.b[1]='b';
ex.b[2]='c';
ex.b[3]='d';
ex.c=3.14;
ex.d[0]=20;
ex.d[1]=30;
ex.e='A';
P=&ex;
printf("%d\n",*((int*)P));
P=((int *)P+1);
printf("%c\n",*((char*)P));
P=((char *)P+1);
printf("%c\n",*((char*)P));
P=((char *)P+1);
printf("%c\n",*((char*)P));
P=((char *)P+1);
printf("%c\n",*((char*)P));
P=((char *)P+1);
printf("%.2f\n",*((double*)P));
P=((double *)P+1);
printf("%d\n",*((short*)P));
P=((short *)P+1);
printf("%d\n",*((short*)P));
P=((short *)P+1);
printf("%c\n",*((char*)P));
return 0;
}
주소값을 가져오면 안에 캐스팅을 통해서 증가시키고
출력하면 가능하다~!
- ATMEGA-
배율을 128을 하게 되는경우 분주기가 변하게 된다. 기존에 사용하는 배율 64일경우 분주기가 0~215까지 이게 된다 하지만 128이면 0~125가 된다 그렇게 되는경우 초기값을 변경시켜줘야하는데
TCNT0 =256-(CPU_CLOCK/TICKS_PER_SEC/PRESCALER);
CPU_CLOCK=16000000
TICKS_PER_SEC=1000
PRESCALER= 128
이기 때문에 결국에는 초기값이 131이 된다.
그래서 131~255까지 증가하게 된다.
-CTC-
기본적으로 인터럽트는 종류가 많다. 하지만 저번시간까지 배운 내용은 오버플로우가 발생시 되는 인터럽트였다 하지만 오늘내용은 CTC라고 비교 매치 인터럽트이다. 사용자가 정해주는값과 증가하는 값이 같을때까지 우리가 정해주는 값은 OCR0에 값을 넣을 수 있다.
그래서 보다시피 Normal모드에서는 WGM01과 WGM00에 0값을 넣었을경우 자동으로 사용이 되었다 하지만 비교매치인터럽트를 위해서는 WGM01에 1값을 넣고 WGM00에 0값을 넣으면 된다.
그래서 TCCR0에 값에 6번째 비트에 0 3번째 비트에 1 배율을 64하기 위해서 2번째 비트에 1을 넣고 1번째와 0번째 비트에 0을 넣는다.
그리고 TCNT0에 기본 값으로 0을 넣어준다.
TCCR0값과 OCR0 값이 같아지면 인터럽트를 발생하게 된다. 그래서 TCCR0는 배율이 64에 초기값이 0이되고 그러면 분주기가 250이 된다. 여기서 OCRO 값을 250을 넣게 되면 이제 한분주기마다 인터럽트를 발생할수있게 된다.
그리고 우리가 주기적인 인터럽트를 받기위해서는 TIMSK를 값을 변경해줘야한다.
OCIE0에 1을 넣게 되면 결국에 비교매치인터럽트를 활성화시킨다.
TIMSK=(TIMSK)|(1<<1)이렇게 하면된다.
그리고 여기서 중요한점은
1. TCCR0값과 OCR0 값이 같아지면 인터럽트를 발생하게 되면 기본적으로 오버플로우같은경우 초기값을 항상 지정을 해줘야했다 하지만 비교매치인터럽트는 비교를 해서 참이 되면 그때 인터럽트를 발생하고 TCCR0에 값을 자동으로 초기화한다.
2.SIGNAL(SIG_OUTPUT_COMPARE0)와 SIGNAL(SIG_OVERFLOW0)
SIGNAL(SIG_OVERFLOW0)같은경우는 오버플로우인터럽트가 발생하면 저함수가 실행이된다
하지만 우리가 사용하는 비교매치인터럽트경우 SIGNAL(SIG_OUTPUT_COMPARE0)를 사용해야한다. 그래서 인터럽트를 사용에 따라 틀리다.
-소스-
#include<atmega.h>
#include<avr/io.h>
#include<avr/interrupt.h>
volatile unsigned int g_elapsed_time;//시간변수
void intiLED(void); //LED초기화
void setTCCR0(void); //TCCR0설정
void initTCNT0(void); //TCNT0초기화
void setTIMSK(void); //TIMSK 설정
void toggleLED(char * state); //LED 반전
void sleep(unsigned int elapsed_time); //1 초 대기
SIGNAL(SIG_OUTPUT_COMPARE0); //비교연산 인터럽트사용
int main(void)
{
char state=0;
intiLED();
setTCCR0();
initTCNT0();
setTIMSK();
SREG=0x80;
while(1)
{
toggleLED(&state);
sleep(1000);
}
return 0;
}
void intiLED(void)
{
DDRE=0xFF;
PORTE=0xFF;
}
void setTCCR0(void)
{
TCCR0=(TCCR0|(1<<2)); //분주비64
TCCR0=(TCCR0&(~(1<<0)));
TCCR0=(TCCR0&(~(1<<1)));
TCCR0=(TCCR0|(1<<3)); //CTC사용
TCCR0=(TCCR0&(~(1<<6)));
}
void initTCNT0(void)
{
TCNT0 =0;
OCR0=250; //비교되는 값 설정
}
void setTIMSK(void)
{
TIMSK=(TIMSK)|(1<<1); //비교매치 인터럽트 사용
}
void toggleLED(char * state)
{
if(*state==0)
{
PORTE=0x00;
*state=1;
}
else
{
PORTE=0xFF;
*state=0;
}
}
void sleep(unsigned int elapsed_time)
{
while(g_elapsed_time<elapsed_time);
g_elapsed_time=0;
}
SIGNAL(SIG_OUTPUT_COMPARE0)
{
g_elapsed_time++;
}
----------------------------------------------------------
분주기가 125이고 배율이 128인경우
#include<atmega.h>
#include<avr/signal.h>
#include<avr/interrupt.h>
#define CPU_CLOCK 16000000 //CPU clock=16000000Hz
#define TICKS_PER_SEC 1000 //Ticks per sec =1000
#define PRESCALER 128 //클럭의 배수
volatile unsigned int g_elapsed_time;//시간변수
void intiLED(void); //LED초기화
void setTCCR0(void); //TCCR0설정
void initTCNT0(void); //TCNT0초기화
void setTIMSK(void); //TIMSK 설정
void toggleLED(char * state); //LED 반전
void sleep(unsigned int elapsed_time); //1 초 대기
SIGNAL(SIG_OVERFLOW0); //timer0의 오버플로우 함수
int main(void)
{
char state=0;
intiLED();
setTCCR0();
initTCNT0();
setTIMSK();
SREG=0x80;
while(1)
{
toggleLED(&state);
sleep(1000);
}
return 0;
}
void intiLED(void)
{
DDRE=0xFF;
PORTE=0xFF;
}
void setTCCR0(void)
{
TCCR0=(TCCR0|(1<<2));
TCCR0=(TCCR0|(1<<0));
TCCR0=(TCCR0&(~(1<<1)));
}
void initTCNT0(void)
{
TCNT0 =256-(CPU_CLOCK/TICKS_PER_SEC/PRESCALER);
}
void setTIMSK(void)
{
TIMSK=(TIMSK)|(1<<0);
}
void toggleLED(char * state)
{
if(*state==0)
{
PORTE=0x00;
*state=1;
}
else
{
PORTE=0xFF;
*state=0;
}
}
void sleep(unsigned int elapsed_time)
{
g_elapsed_time=0;
while(g_elapsed_time<elapsed_time);
}
SIGNAL(SIG_OVERFLOW0)
{
initTCNT0();
g_elapsed_time++;
}
-------------------------------------
C과제
1. 문자가 숫자인지 알려주는 isdigit 함수를 구현하세요. 문자 ch를 입력 받고, ch가 숫자인지 출력하세요. 맞다면 YES, 아니면 NO를 출력합니다.
출력) 문자 : P
결과 : NO
문자 : 2
결과 : YES
#include<stdio.h>
void abc(char ch);
int main()
{
char cnum;
scanf("%c",&cnum);
abc(cnum);
return 0;
}
void abc(char ch)
{
if(48<=ch&&57>=ch)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
2. 정수 N을 입력하면 2의 N승을 출력하는 프로그램을 작성하세요. 단, 비트 연산을 이용합니다.
그리고 -1을 입력할 경우 프로그램은 종료됩니다.
출력) 입력 : 6
출력 : 2^6= 64
입력 : 4
출력 : 2^4 = 16
입력 : -1
프로그램 종료
#include<stdio.h>
int main()
{
int inum;
int icnt;
int result=1;
printf("입력 :");
scanf("%d",&inum);
for(icnt=0;icnt<inum;++icnt)
{
result=result<<1;
}
if(inum==-1)
{
printf("프로그램종료 \n");
}
else
{
printf("출력 2 ^ %d= %d\n",inum,result);
}
return 0;
}
3. 다음과 같은 형태로 문자열이 출력되는 프로그램을 작성하시오.
1)
A
A B
A B C
A B C D
A B C D E
#include<stdio.h>
int main()
{
char cnum;
int inum;
int jnum;
int sum=1;
cnum='A';
for(inum=1;inum<6;inum++)
{
for(jnum=0;jnum<inum;jnum++)
{
printf("%c",cnum+jnum);
printf(" ");
}
printf("\n");
}
return 0;
}
2) a
b a
c b a
d c b a
e d c b a
#include<stdio.h>
int main()
{
char cnum;
int inum;
int jnum;
int Knum;
int sum=0;
cnum='a';
for(inum=1;inum<6;inum++)
{
for(jnum=5;jnum>inum;jnum--)
{
printf(" ");
}
sum=inum;
for(Knum=0;Knum<inum;Knum++)
{
printf("%c",cnum+sum-1);
--sum;
}
printf("\n");
}
return 0;
}
'2010년 > 4월' 카테고리의 다른 글
4월19일 network(nagle알골/넌블로킹client)/Atmaga(C코딩,컴직렬통신) (0) | 2010.04.19 |
---|---|
4월15일 ATmega(StopWatch) (0) | 2010.04.15 |
4월13일 ATmega(타이머 카운터) (0) | 2010.04.13 |
4월 12일 network(c/s send recv 스레드 분리) ATmega(적외선 감지증가) (0) | 2010.04.12 |
4월9일 network(스레드) ATmega(적외선) (0) | 2010.04.09 |