카테고리 없음
20160315_최기영_업무일지
embsoft90
2016. 3. 16. 11:47
오전
11일에 작성한 소스와 14일에 작성한 함수를 합쳐보자
/*
FND가 깜빡거리긴하는데 제대로 작동하는지 모르겠다.
*/
#include "main.h"
int main(void)
{
volatile unsigned int uiCnt;
volatile unsigned int uiLoop;
uiCnt = 0;
DDRA = 0xFF;
PORTA = 0x00; //전체 LED를 켠다.
EICRA = (3<<ISC0); //상승엣지 binary 11= decimal 3이므로
EIMSK = (1<<INT0);
SREG = SREG | (1<<7);//sei(); 와 같은 말, 기존에 있던 값을 유지해야하기 때문에 SREG | 를 추가 해야한다.
//sei(); 어셈블리 명령어로 7번 비트만 1로 만드는 것
while(1)
{
PORTA = ((uiCnt/10)<<4)|(uiCnt%10);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
++uiCnt;
if(uiCnt > 99)
{
uiCnt = 0;
}
sleep();
}
return 0;
}
void __vector_1(void)
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
PORTA = 0xFF;
} |
|
/*
보이드 벡터를 주석 처리했더니 리셋이 가능해졌다....
*/
#include "main.h"
int main(void)
{
volatile unsigned int uiCnt;
volatile unsigned int uiLoop;
uiCnt = 0;
DDRA = 0xFF;
PORTA = 0x00; //전체 LED를 켠다.
EICRA = (3<<ISC0); //상승엣지 binary 11= decimal 3이므로
EIMSK = (1<<INT0);
SREG = SREG | (1<<7);//sei(); 와 같은 말, 기존에 있던 값을 유지해야하기 때문에 SREG | 를 추가 해야한다.
//sei(); 어셈블리 명령어로 7번 비트만 1로 만드는 것
while(1)
{
PORTA = ((uiCnt/10)<<4)|(uiCnt%10);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
++uiCnt;
if(uiCnt > 99)
{
uiCnt = 0;
}
sleep();
}
return 0;
}
/*
void __vector_1(void)
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
PORTA = 0xFF;
}*/ |
|
위의 소스를 함수를 만들어서 분리해보자
- void Init(void){} 추가
- void Port_Init(void){} 추가
- void INT_Init(void){} 추가
/*
파일 이름 : main.c
작성 날짜 : 2016-03-15
작성 시간 : 09:40
*/
#include "main.h"
int main(void)
{
volatile unsigned int uiCnt;
volatile unsigned int uiLoop;
uiCnt = 0;
DDRA = 0xFF;
PORTA = 0x00; //전체 LED를 켠다.
EICRA = (3<<ISC0); //상승엣지 binary 11= decimal 3이므로
EIMSK = (1<<INT0);
SREG = SREG | (1<<7);//sei(); 와 같은 말, 기존에 있던 값을 유지해야하기 때문에 SREG | 를 추가 해야한다.
//sei(); 어셈블리 명령어로 7번 비트만 1로 만드는 것
while(1)
{
PORTA = ((uiCnt/10)<<4)|(uiCnt%10);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
++uiCnt;
if(uiCnt > 99)
{
uiCnt = 0;
}
sleep();
}
return 0;
}
void Init(void)
{
INT_Init();
Port_Init();
}
void Port_Init(void)
{ }
void INT_Init(void)
{ }
void __vector_1(void)
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
PORTA = 0xFF;
} |
/*
파일 이름 : main.h
작성 날짜 : 2016-03-15
작성 시간 : 09:40
*/
#ifndef __MAIN_H__
#define __MAIN_H__
#define PINA (*((volatile unsigned char *)0x20))
#define DDRA (*((volatile unsigned char *)0x21))
#define PORTA (*((volatile unsigned char *)0x22))
#define EICRA (*((volatile unsigned char *)0x69))
#define EICRB (*((volatile unsigned char *)0x6A))
#define EIMSK (*((volatile unsigned char *)0x3D))
#define SREG (*((volatile unsigned char *)0x5F))
#define sei() __asm__ __volatile__ ("sei" ::)
#define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: ) //무한 while보단 좋다.
#define INT7 7
#define INT6 6
#define INT5 5
#define INT4 4
#define INT3 3
#define INT2 2
#define INT1 1
#define INT0 0
#define ISC7 6
#define ISC6 4
#define ISC5 2
#define ISC4 0
#define ISC3 6
#define ISC2 4
#define ISC1 2
#define ISC0 0
void __vector_1 (void) __attribute__((signal, used, externally_visible)); //0번 인터럽트에 대한 코드 pdf에 있는것 +1==>인터럽트 0번
void Init(void);
void INT_Init(void);
void Port_Init(void);
#endif //__MAIN_H__
|
#include "main.h"
int main(void)
{
volatile unsigned int uiCnt;
volatile unsigned int uiLoop;
uiCnt = 0;
Init(void);
while(1)
{
PORTA = ((uiCnt/10)<<4)|(uiCnt%10);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
++uiCnt;
if(uiCnt > 99)
{
uiCnt = 0;
}
sleep();
}
return 0;
}
void Init(void)
{
Port_Init();
INT_Init();
}
void Port_Init(void)
{
DDRA = 0xFF;
PORTA = 0x00; //전체 LED를 켠다.
}
void INT_Init(void) //인터럽트 초기화
{
EICRA = (3<<ISC0); //상승엣지 binary 11= decimal 3이므로
EIMSK = (1<<INT0);
SREG = SREG | (1<<7);//sei(); 와 같은 말, 기존에 있던 값을 유지해야하기 때문에 SREG | 를 추가 해야한다.
//sei(); 어셈블리 명령어로 7번 비트만 1로 만드는 것
}
void __vector_1(void)
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
PORTA = 0xFF;
} |
|
#include "main.h"
int main(void)
{
volatile unsigned int uiCnt;
volatile unsigned int uiLoop;
uiCnt = 0;
Init(void);
while(1)
{
PORTA = ((uiCnt/10)<<4)|(uiCnt%10);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
++uiCnt;
if(uiCnt > 99)
{
uiCnt = 0;
}
sleep();
}
return 0;
}
void Init(void)
{
Port_Init();
INT_Init();
}
void Port_Init(void)
{
DDRA = 0xFF;
PORTA = 0x00; //전체 LED를 켠다.
}
void INT_Init(void) //인터럽트 초기화
{
EICRA = (3<<ISC0); //상승엣지 binary 11= decimal 3이므로
EIMSK = (1<<INT0);
SREG = SREG | (1<<7);//sei(); 와 같은 말, 기존에 있던 값을 유지해야하기 때문에 SREG | 를 추가 해야한다.
//sei(); 어셈블리 명령어로 7번 비트만 1로 만드는 것
}
void __vector_1(void)
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
PORTA = ~PORTA;
}
void __vector_2(void)
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
PORTA = ~PORTA;
} |
#ifndef __MAIN_H__
#define __MAIN_H__
#define PINA (*((volatile unsigned char *)0x20))
#define DDRA (*((volatile unsigned char *)0x21))
#define PORTA (*((volatile unsigned char *)0x22))
#define EICRA (*((volatile unsigned char *)0x69))
#define EICRB (*((volatile unsigned char *)0x6A))
#define EIMSK (*((volatile unsigned char *)0x3D))
#define SREG (*((volatile unsigned char *)0x5F))
#define sei() __asm__ __volatile__ ("sei" ::)
#define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: ) //무한 while보단 좋다.
#define INT7 7
#define INT6 6
#define INT5 5
#define INT4 4
#define INT3 3
#define INT2 2
#define INT1 1
#define INT0 0
#define ISC7 6
#define ISC6 4
#define ISC5 2
#define ISC4 0
#define ISC3 6
#define ISC2 4
#define ISC1 2
#define ISC0 0
void Init(void);
void INT_Init(void);
void Port_Init(void);
void __vector_1 (void) __attribute__((signal, used, externally_visible)); //0번 인터럽트에 대한 코드 pdf에 있는것 +1==>인터럽트 1번
void __vector_2 (void) __attribute__((signal, used, externally_visible)); //1번 인터럽트에 대한 코드 pdf에 있는것 +1==>인터럽트 2번
#endif //__MAIN_H__
|
위의 코드에 전역변수를 사용하기 위해
전역변수 만들기 연습
컴파일은 주소를 고정시키는 코드를 사용한다.
cl main.c /link /DYNAMICBASE:no
/*
작성 날짜 : 2016-03-15
작성 시간 : 10:48
전역변수 연습
*/
#include <stdio.h>
int D;
int E;
int F;
int G;
int H;
int main()
{
int A = 0;
int B;
int C = 100;
printf(" A의 주소 : %x \n",&A);
printf(" B의 주소 : %x \n",&B);
printf(" C의 주소 : %x \n",&C);
printf(" D의 주소 : %x \n",&D);
printf(" E의 주소 : %x \n",&E);
printf(" F의 주소 : %x \n",&F);
printf(" G의 주소 : %x \n",&G);
printf(" H의 주소 : %x \n",&H);
return 0;
}
|
|
|
|
#include <stdio.h>
int D;
int E = 99;
int F;
int G = 98;
int H;
int main()
{
int A = 0;
int B;
int C = 100;
printf(" A의 주소 : %p \n",&A);
printf(" B의 주소 : %p \n",&B);
printf(" C의 주소 : %p \n",&C);
printf(" D의 주소 : %p \n",&D);
printf(" E의 주소 : %p \n",&E);
printf(" F의 주소 : %p \n",&F);
printf(" G의 주소 : %p \n",&G);
printf(" H의 주소 : %p \n",&H);
printf(" printf()의 주소 : %p\n",&printf);
printf(" main()의 주소 : %p\n",&main);
return 0;
}
|
|
/*
2016-03-15
10:48
전역변수 연습
*/
#include <stdio.h>
int D;
int E = 99;
int F;
int G = 98;
int H;
int main()
{
int A = 0;
int B;
int C = 100;
printf("------Stack 영역-------\n");
printf(" A의 주소 : %p \n",&A);
printf(" B의 주소 : %p \n",&B);
printf(" C의 주소 : %p \n",&C);
printf("-------BSS 영역--------\n");
printf(" H의 주소 : %p \n",&H);
printf(" F의 주소 : %p \n",&F);
printf(" D의 주소 : %p \n",&D);
printf("-------Data 영역-------\n");
printf(" G의 주소 : %p \n",&G);
printf(" E의 주소 : %p \n",&E);
printf("-------Code 영역-------\n");
printf(" main()의 주소 : %p\n",&main);
printf(" printf()의 주소 : %p\n",&printf);
printf("------------------\n");
return 0;
}
|
|
전역변수의 특징을 알아보자
/*
특성1 : 전역변수를 초기화 하지 않으면 값은 binary 0으로 초기화 된다.
*/
#include <stdio.h>
int A;
int main()
{
printf("%d\n",A);
return 0;
} |
|
/*
특성2 : 전역변수보다 printf가 속해있는 공간을 우선적으로 찾는다.
*/
#include <stdio.h>
int A;
int main()
{
int A = 100;
printf("%d\n",A);
return 0;
} |
|
#include <stdio.h>
void smart();
int A;
int main()
{
//int A = 100;
printf("%d\n",A);
return 0;
}
void smart(void)
{
} |
|
/*
전역변수 사용시 단점
단점1 :변수 관리가 어렵다.
단점2 :전역변수는 프로그램이 종료될때까지 유지되므로 메모리를 차지하고 있다.
(전역변수는 왠만하면 많이 안쓰는게 좋다.
대부분의 변수는 지역변수로 만들어야한다.)
단점3 : 실행파일 자체의 용량을 키운다.
*/
#include <stdio.h>
void smart();
int A;
int main()
{
//int A = 100;
printf("%d\n",A);
smart();
printf("%d\n",A);
return 0;
}
void smart(void)
{
A=99;
} |
|
다시 인터럽트
/*
main.c만 이렇게 바꿔준다.
*/
#include "main.h"
volatile unsigned int uiState; //int는 bus의 크기에 맞춰져있다. 양수만 사용하는 unsigned int가 가장 빠른 변수이다.
int main(void)
{
volatile unsigned int uiCnt;
volatile unsigned int uiLoop;
uiCnt = 0;
Init();
uiState = 1;
while(1)
{
PORTA = ((uiCnt/10)<<4)|(uiCnt%10);
for(uiLoop = 0; uiLoop<60000; ++uiLoop);
if(uiState == 1)
{
++uiCnt;
}
if(uiCnt > 99)
{
uiCnt = 0;
}
sleep();
}
return 0;
}
void Init(void)
{
Port_Init();
INT_Init();
}
void Port_Init(void)
{
DDRA = 0xFF;
PORTA = 0x00; //전체 LED를 켠다.
}
void INT_Init(void) //인터럽트 초기화
{
EICRA = (3<<ISC1) | (3<<ISC0); //상승엣지 binary 11= decimal 3이므로
EIMSK = (1<<INT1) | (1<<INT0);
SREG = SREG | (1<<7);//sei(); 와 같은 말, 기존에 있던 값을 유지해야하기 때문에 SREG | 를 추가 해야한다.
//sei(); 어셈블리 명령어로 7번 비트만 1로 만드는 것
}
void __vector_1(void)//INT0
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
uiState = 1;
}
void __vector_2(void)//INT1
{
volatile unsigned int uiCnt;
for(uiCnt = 0; uiCnt<60000; ++uiCnt);
uiState = 0;
}
|
|
오후