728x90

OR : 논리합 








AND : 논리곱








HD74LS00P (NAND 게이트)



http://www.alldatasheet.co.kr/datasheet-pdf/pdf_kor/247357/RENESAS/HD74LS00P.html








NAND로 NOT 게이트 만들기




NAND로 NOT 게이트 만들기



Output :

A = Lo: Out = Hi

A = Hi: Out = Lo

A = Lo: Out = Hi

A = Hi: Out = Lo






NOR 게이트(74HC02)




입력들 중 `1`이 1개 이상이면 출력이 `0`이 됨 

입력이 모두 `0`인 경우에만 출력이 `1`이 됨


A = Lo, B = Lo: Out = Hi

A = Lo, B = Hi: Out = Lo

A = Hi, B = Lo: Out = Lo

A = Hi, B = Hi: Out = Lo




XOR 게이트
: 입력 값이 같으면 0을 출력하고, 입력 값이 다르면 1을 출력

A

B

XOR B

0
0
1
1

0
1
0
1

0
1
1
0










Carry와 Sum (Carry는 올림수, Sum은 합을 의미)
: 10진수 1+9는 논리합이 0이 되고 자리올림 1이 되는 것처럼, 2진수도 똑같이 생각하면 된다.

가산기(Adder)

반가산기

A + B = C / S
0    0    0    0
0    1    0    1
1    0    0    1
1    1    1    0

여기서 carry는 and,

sum은 xor 게이트와 같다.

A

B

XOR B

0
0
1
1

0
1
0
1

0
1
1
0


반가산기 논리회로







전가산기

2개의 비트 a,b와 자리올림 Ci를 더해 합 S와 자리올림 Co을 구한다.  (Carry input/ Carry output)


입력

출력

A

B

Ci

Co

S

0

0

0

0

0

0

0

1

0

1

0

1

0

0

1

0

1

1

1

0

1

0

0

0

1

1

0

1

1

0

1

1

0

1

0

1

1

1

1

1


전가산기 논리회로 예시



'Study > Embedded' 카테고리의 다른 글

5/2 디지털이란? / 저항, 인덕터, 캐패시터  (0) 2016.05.02
2016 04 28 디코더  (0) 2016.04.28
2016-04-25_디지털제어-회로 기초  (0) 2016.04.25
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160323_펌웨어(ADC)  (0) 2016.03.23
728x90

analog 연속 -> noise에 약함, 데이터량에 많음, 원래 신호에 가까움, 보안성 약함



digital 불연속 -> noise에 강함



ADC 

:표본화, 양자화, 부호화를 거쳐 digital화 함



충전을 위해선 20%이상의 전압을 걸어줘야 함




전류 Current    A

전압 Voltage    V

저항 Resistor    R   



DC 직류 - 주파수 0 Hz



AC 교류 - 주파수 60 Hz




SMPS(Switched-Mode Power Supply) 

AC Line 주파수(50㎐~60㎐)를 DC로 변환하여 높은 주파수로 변경 (수십 ㎑~수백 ㎑)하여 사용





AC 단상 3선식 (일명 돼지코)

Live(Hot), Neutral(Cold) // N, L이라고 쓰여있음

  아래위엔 접지(Earth)가 있음



회로 설계시

1. 전자부품의 스펙 확인

구동전압 확인


2. 회로 설계

3. Artwork

4. Debugging

5. Artwork


싱크/ 소스타입 조사하기





풀업&풀다운 저항


어정쩡한 요인을 제거하기 위해 풀업이나 풀다운 저항을 사용함. 확실한 high와 low로 만들어줌

풀업 풀다운을 위해하기전에 플로팅에 대해 알 필요가 있다.



 플로팅 (floating)


 칩에 입력을 5V 또는 0V를 가한다. 하지만 입력을 가하지 않는 경우는 칩 자체에서는 5V를 입력하였는지 1V를 입력하였는지 모른다. 이런 문제에 의하여 오작동이 발생할 수 있다. 이런 상태를 플로팅되었다라고 한다. 플로팅 상태는 잡음에 매우 취약해지므로 시스템이 불안정해진다. 이를 해결 하기 위해서 풀업 / 풀다운 저항을 사용하게 된다



풀업 저항 (Pullup resistor)


풀업 저항을 사용한다면 스위치가 열려 있을 때 칩에는 항상 5V의 전압이 가해진다. 
따라서 회로에 입력을 몰라도 항상 5V의 전압을가진 상태가 된다. 스위치를 닫는다면 그라운드 쪽으로 전류가 흐르게 되며 회로의 전압은 0V가 되며, 1을 입력한 것으로 인식하게 된다. 핀을 높은 저항에 매달아 둔다는 뜻에서 '풀 업 저항'이라 한다.


풀다운 저항 (Pulldown resistor)


회로는 5V의 전압을 받으면 1로 인식하고, 0V의 전압을 받으면 0으로 인식한다. 
스위치가 열려있는 상태에서 그라운드와 연결되어 있으므로 전류가 항상 그라운드로 흐르게 되어 0V가 된다. 스위치를 닫게되면 소량의 전류가 저항을 통해 그라운드로 흘러 나가지만 많은 양의 전류가 회로(핀)로 흘러 5V가 된다. 따라서 1이 입력된 것으로 인식한다. 항상 그라운드에 묶어둔다는 의미에서 '풀 다운 저항' 이라 한다.




http://air802.tistory.com/2


슈미트 트리거 회로

Schmitt Trigger는 미국의 과학자 Otto H. Schmitt에 의해 발명된 일종의 비교기로써, 하나의 입력 전압과 출력 전압, 두 개의 threshold를 가진다. positive feedback을 사용하는 비교기로, OP Amp의 구조를 가지며 대부분 inverter로 사용된다.


 

 

 즉, input 신호로 low threshold 보다 낮은 전압이 인가되면 출력은 high로, high threshold 보다 높은 전압이 인가되면 출력은 low가 되며, 두 개의 threshold 사이의 전압이 인가되면 그 값을 유지한다.


 threshold가 하나인 유사한 시스템의 경우, 입력 신호에 noise가 섞여 threshold에 비슷한 전압이 인가되면 스위치를 순식간에 on/off 시킬 수 있기 때문에 두 개의 threshold를 사용하는 Schmitt Trigger가 더 안정적이다. 그러므로 사람의 손 떨림으로 인해 값이 여러번 입력되는 등의 switch noise를 제거할 수 있다.




http://blog.naver.com/PostView.nhn?blogId=davidsbkim&logNo=150031720819




임베디드 레시피

http://recipes.egloos.com/


도쳬 : 금속, 흑연 ...

부도체: 전류가 흐르지 않음


반도체 - 다이오드 : 한쪽 방향으로만 전류 흐름.


순방향


순방향 전압


역방향


역방향 전압



트랜지스터

http://www.mully.net/lee/2015/transistor/



대부분의 트랜지스터는 3개의 다리를 가지고 있습니다. 각각 베이스(Base), 컬렉터(Collector), 이미터(Emitter)라고 부릅니다.

  • 베이스(B): 트랜지스터를 작동시키기 위해 약한 전기신호를 가하는 단자입니다.
  • 컬렉터(C): 베이스에(B) 약한 전기신호가 들어오면 막혀 있던 컬렉터(C)에 큰 전류가 흐르게 됩니다.
  • 이미터(E): 베이스(B)와 컬렉터(C)에서 흐르는 전류가 합쳐지는 단자입니다.



Trans-Resistor :  Resistor값을 변화 시킬 수 있다는 의미로 전류의 양을 조절하는 것.







 B에 넣어주는 전압(전류)량의 미묘한 변화에도 저항값이 휙휙 많이 바뀐며, 결국 EC간의 전류 값도 휙휙 변하게 된다.





주파수






디지털 샘플링  Digital Sampling

http://www.mully.net/lee/2015/digital_sampling/


자연의 모든 소리는 아날로그 신호입니다.

아날로그 정보는 연속적인 모든 시간에서의 정보를 가지고 있습니다. 모든 시간의 값을 전부 기록할 수는 없으므로 보통은 일정한 시간 간격마다 값만 기록을 할 수 밖에 없습니다. 즉, 값을 추출하는 적당한 시간 간격을 정해야 합니다.

아날로그 정보를 디지털 정보로 정확하게 기록하기 위해서는 기록을 하는 시간 간격도 충분히 작게 해야 합니다. 즉, 아날로그 정보가 변하는 특정 시간 보다 더 촘촘한 시간 간격으로 기록을 해야 합니다.




접지(Earthing, Grounding) : 각종 전기, 전자, 통신 설비들을 전기적으로 대지와 연결하여 전위를 대지와 같은 기준전위(0 v)로 만드는 것






74 HC 시리즈 각 칩의 기능과 구성


http://donghwada.tistory.com/entry/74HC-%EC%8B%9C%EB%A6%AC%EC%A6%88-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%ED%8A%B8-%EB%B3%B4%EB%8A%94-%EB%B2%95-%EB%B0%8F-%EC%A0%95%EB%A6%AC74HC00-74HC02-74HC04-74HC08-74HC32-74HC86




'Study > Embedded' 카테고리의 다른 글

2016 04 28 디코더  (0) 2016.04.28
2016 04 27 논리회로  (0) 2016.04.27
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160323_펌웨어(ADC)  (0) 2016.03.23
20160322_펌웨어(USART)  (0) 2016.03.22
728x90

 

써미스터 10k

저항 10k

 

V=IR

5V = I * (R1+R2)

    = I * 20000

 

I=20000/5A

 =0.00025A

 =0.25mA

 

V=iR1

 =0.25mA*10000

 =2.5V

 

 

 


열 감지 실습

 

5v~2.5   : 열에 의해 저항이 변함

 

 

1<<ADLAR : 뒤의 비트만 버리는 방식으로 변경  (뒤의 비트를 버리는 것이 숫자 차이가 적음)

 

 

 128

 64

 32

 16

 8

 4

 2

 1

 

 

3-24_ADC.zip

 

 

 

 

 

Pulse Width Modulator (PWM)

 

펄스폭을 조절

LED의 변화(밝기,RGB)

모터속도의 변화(세게,약하게)

 

시간을 빠르게 하면 빠르게 올라감-분주비와 숫자(200,150)가 영향을 미침

 

CTC 꼭대기에서만 반전이 일어남

PWM

 

 

Toggle : 0->1, 1->0

 

 

AVR PWM실습


AVR-PWM.7z




 

 

'Study > Embedded' 카테고리의 다른 글

2016 04 27 논리회로  (0) 2016.04.27
2016-04-25_디지털제어-회로 기초  (0) 2016.04.25
20160323_펌웨어(ADC)  (0) 2016.03.23
20160322_펌웨어(USART)  (0) 2016.03.22
20160321_펌웨어(UART)  (0) 2016.03.21
728x90

 0V(LOW)
 5V(HIGH)

10bit resolution = 2의 10승  / 1024(0~1023)

 

 

 

 

 

 

ADC MULTIPLEXER SELECT (ADMUX)

ADC CTRL & STATUS REGISTER  (ADCSR)

ADC DATA REGISTER (ADCH/ADCL)

mux decoder
여러개중에 하나를 선택(몇번 다리에서 입력받을건지)

ADC[15:0] -> 0번부터 15번 다리까지 있다.  16개

GAIN AMPLIFIER -> AMP(AMPLIFIER)
신호를 키움

CONVERSION LOGIC

PRESCALER 심박수(클럭)이 기준

 

'Study > Embedded' 카테고리의 다른 글

2016-04-25_디지털제어-회로 기초  (0) 2016.04.25
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160322_펌웨어(USART)  (0) 2016.03.22
20160321_펌웨어(UART)  (0) 2016.03.21
20160317-펌웨어(타이머 카운터)  (0) 2016.03.17
728x90

 


115200 bps(bit per sec)가 16mhz인 atmega에 가장 최적 (UBRR = 8)


atmega는 2m bps가 최대

 

 

실수가 버려지고 결과값이 7이 되는 문제가 생김


소스 수정

((OSC/(16.0*BAUD))-0.5); //반올림



UBRR 공식을 define해주고 다음과 같이 코딩한다


#define OSC F_CPU

#define BAUD 115200 //bps

#define UBRR ((OSC/(16.0*BAUD))-0.5);


UBRR0H = UBRR >> 8

UBRR0L = UBRR;





실습


AVR_rx-tx.7z











 




소스컴페어 (두 소스파일을 비교할 수 있는 유용한 프로그램)





DAC(Digital-to-Analog Converter)

ADC(Analog-Digital Converter)

아날로그에서 디지털로.

파형의 곡선을 표로 만드는 것과 같다.






16 Bit / 44.1 KHz 인 CD

3분기준 30MB(스테레오)



RGB 빛은 섞을수록 밝아진다. 색은 섞을수록 어두워진다.


사진의 점 pixel

R 8bit = 0~255 (256단계)

R/G/B = 3byte


3x1024x768=2359296

2359296/1024/1024=2.25  (MB)



24bit_rgb.bmp (1024x768)

2.25 MB


인간은 아주 작은 점을 그림으로 인식





'Study > Embedded' 카테고리의 다른 글

20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160323_펌웨어(ADC)  (0) 2016.03.23
20160321_펌웨어(UART)  (0) 2016.03.21
20160317-펌웨어(타이머 카운터)  (0) 2016.03.17
20160316-LCD출력  (0) 2016.03.17
728x90

함수 호출

  • 프로그래밍(s/w) -> 함수                                 호출
  • 회로(h/w) -> 인터럽트 함수 ISR                        IRQ     INT(인터럽트)
  • 운영체제 os(s/w) -> 콜백 함수(call back)          windows에선 Message         

드라이버 - 각 하드웨어 제조사에서 만듬

운영체제 - 운영 및 조율하는 역할

 

atmega - 펌웨어만 짜놓고 return하면 os가 없기 때문에 안됨

 

 

플랫폼 : 안드로이드

 

리눅스(os) + 안드로이드

폰 제조사들이 알아서 한다.

 

에뮬레이터 (플랫폼)  //  Java - JVM

BSD (unix)

 

Java는 임베디드를 타겟으로 만듬, 어플리케이션에 활용

 

 

 

시리얼(직렬)

패러럴(병렬)  

LAN     Local Area Network

WAN    Wide Area Network

 

네트워크 시초는 군사용

 

 

시리얼(직렬) : AVR -> LCD 1bit씩 보냄            1/0/1/1/1/1/0/0

패러럴(병렬) : AVR -> LCD 멀티 bit 를 보냄     10111100         

 

직렬 : 단순, 비용저렴, 속도 느림

병렬 : 복잡, 비용증가, 속도 빠름

 

고속직렬

 Tx

 R

 Rx

 T

 C

 C

 GND

 GND

 VCC

 VCC

 

T (transmit)  R (receive)

C 클럭  

GND 기준전압을 갖게 해주기 위해 무조건 연결

VCC

 

시리얼 방식 대표적인 예 : USB

패러럴 방식 대표적인 예 : BUS

 

 

Atmega2560

 

 

odd(홀수), even(짝수) / parity(점검하다)

 1

 0

 1

 0

 1

 1

 1

 0

 1  (parity bit)

 

갯수를 체크해서 데이터의 손실을 점검

 

 

전이중 : 전화

반이중 : 무전기

 

T,R,G 비동기 (칩에 기본 내장)

 

 

 

 

 

C언어 컴파일 명령어

cl /DF_CPU=8000000 main.c

 

http://codepad.org/YjciuvST

 

결과 :

 

 

전압이 높을수록 0과 1을 구별하기 용이하다.

max3232 신호전압을 조정

 

UART

USART(Universal Synchronous and Asynchronous Receive and Transmitter)

 

max3232  120Kbos x 1024=122,880  (최대속도)

TRANSMIT,RECEIVE SHIFT REGISTER  - 1bit씩 밀어냄

BAUD - 폭이 늘어나면 느려지고, 좁아지면 빨라진다.
BAUD RATE GENERATOR

 

 

 

 

 

 

 

 

 

 

 

 

 

USB 직렬통신 실습

 

 

 

 

 

 

 

 

 

 

'Study > Embedded' 카테고리의 다른 글

20160323_펌웨어(ADC)  (0) 2016.03.23
20160322_펌웨어(USART)  (0) 2016.03.22
20160317-펌웨어(타이머 카운터)  (0) 2016.03.17
20160316-LCD출력  (0) 2016.03.17
20160315-펌웨어 분석 및 학습  (0) 2016.03.16
728x90

타이머/카운터


 

클럭 : 동작 주파수

 

클럭-시간

주파수-초당 진동수

 

 

Atmega2560의 클럭 16mhz

16,000,000hz - oscillator(16.000 mhz)

1:1

    

 

빠른 CPU는?

기본외부 주파수 16mhz일때, PLL이 48mhz로 뻥튀기

 

PLL (phase locked loop) ; 위상 동기 루프

 

10진법-인간-1Mhz->1000khz

2진법-컴-1Mbyte->1024kbyte   

 

 

분주비의 개념

 

 

 

No prescaling - 분주를 하지 않음
From prescaler 분주비   (x/n)

 

/1024가 세기에 가장 좋음

 

 

8bit 타이머 카운터를 만드는데는 8/64/256/1024 중에서

오차 없는 분주비 64가 최적

 

 

동작주파수

분주비

클럭당 소요시간

기준시간

카운터

16000000

1

0.00000006250000000000

0.001

16000.000

8

0.00000050000000000000

0.001

2000.000

64

0.00000400000000000000

0.001

250.000

256

0.00001600000000000000

0.001

62.500

1024

0.00006400000000000000

0.001

15.625

 

  

 

 

내부 인터럽트 - 두가지 방식

over flow방식, compare방식

 

over flow방식

CharA=256;   printf 했을 때 0

 

 

Interrupt Vectors in ATmega 2560

Table

 

 

 


 

 

 







 

타이머 카운터 실습


1초마다 A세기

 


타이머카운터(1초마다 a세기).7z








시간 출력(00:00:03)



00_00_03.7z





 

char caTime[]="00:00:00"; 

//0시 0분 0초, 2byte : 0~65535  최대 18시간 저장가능한 시계를 만들수 있다.


 '0'

 '0'

 :

 '0'

 '0'

 :

 '0'

 '0'

 null


[0] [1]  2  [3] [4]  5  [6] [7] 8   - 9개


시 : 0, 1    / 분 : 3, 4    / 초 : 6, 7 

 

'Study > Embedded' 카테고리의 다른 글

20160322_펌웨어(USART)  (0) 2016.03.22
20160321_펌웨어(UART)  (0) 2016.03.21
20160316-LCD출력  (0) 2016.03.17
20160315-펌웨어 분석 및 학습  (0) 2016.03.16
20160314-펌웨어 분석(외부 인터럽트)  (0) 2016.03.15
728x90

LCD에 글자 출력하기



MAKEFILE 소스 수정


# List C source files here. (C dependencies are automatically generated.)

SRC = $(TARGET).c lcd.c




LCD_A출력.7z


make하기전에 각 소스의 마지막 줄은 비워둘 것



LCD에 A 출력


lcd.h

#ifndef __LCD_H__
#define __LCD_H__

#include "main.h"

#define RS 4
#define RW 5
#define EN 6

#define BUS PORTA
#define CTL PORTC	//control line

void LCD_Init(void);
void LCD_Inst(unsigned char ucInst);
void LCD_Data(unsigned char ucData);
void LCD_STR(const char* cString);

#define	LCD_CLR		0x01
#define	LCD_HOME	0x02
#define	LCD_ENT		0x06	//S:0Shift OFF, I/D:1 Increase Mode
#define	LCD_DSP		0x0f	//D:1 Display On C:1 Cursor on B:1 Blink On
#define	LCD_CUR		0x14	//S/C:0 Shift Cursor OFF R/L:1 
#define	LCD_FUNC	0x38	//DL:1 Data length 8bit  N:1 2Line F:0 Font 5X8

#endif	//__LCD_H__


lcd.c

#include "lcd.h"

void LCD_Init(void)
{
	DDRC = (1<<RS)|(1<<RW)|(1<<EN);	
	DDRA = 0xff;	//C3개, A8개 연다. 
	CTL = (0<<RS)|(0<<RW)|(0<<EN);	
	BUS = 0x00;	

	LCD_Inst(LCD_FUNC);
	LCD_Inst(LCD_DSP);
	LCD_Inst(LCD_ENT);
	LCD_Inst(LCD_CUR);
	LCD_Inst(LCD_CLR);
	LCD_Inst(LCD_HOME);		
}

void LCD_Inst(unsigned char ucInst)
{
	volatile unsigned int uiCnt;

	CTL = CTL & ~(1<<RS);		
	CTL = CTL & ~(1<<RW);	
	CTL = CTL & ~(1<<EN);	
	BUS = ucInst;
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt); //A

	for(uiCnt = 0; 30000>uiCnt; ++uiCnt); //B

	CTL = CTL | (1<<EN);		
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//C

	CTL = CTL & ~(1<<EN);	
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt); //D

	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//E		
	
}

void LCD_Data(unsigned char ucData)
{
	volatile unsigned int uiCnt;

	CTL = CTL | (1<<RS);		
	CTL = CTL & ~(1<<RW);	
	CTL = CTL & ~(1<<EN);	
	BUS = ucData;
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//A

	//CTL = CTL | (1<<RS);
	//CTL = CTL & ~(1<<RW);
	//CTL = CTL & ~(1<<EN);
	//BUS = ucData;
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//B

	//CTL = CTL | (1<<RS);
	//CTL = CTL & ~(1<<RW);
	CTL = CTL | (1<<EN);		
	//BUS = ucData;
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//C

	//CTL = CTL | (1<<RS);
	//CTL = CTL & ~(1<<RW);
	CTL = CTL & ~(1<<EN);	
	//BUS = ucData;
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//D

	//CTL = CTL | (1<<RS);
	//CTL = CTL & ~(1<<RW);
	//CTL = CTL & ~(1<<EN);	
	//BUS = ucData;		
	for(uiCnt = 0; 30000>uiCnt; ++uiCnt);	//E
	
}

void LCD_STR(const char* cString)
{
	while(0!=*cString)
		{
			LCD_Data(*cString);	
			++cString;			 
		}
	
}


main.h

#ifndef __MAIN_H__	
#define __MAIN_H__	

void Init(void);
void Port_Init(void);
void INT_Init(void);

#define PINA	(*((volatile unsigned char *)0x20))
#define DDRA 	(*((volatile unsigned char *)0x21))
#define PORTA	(*((volatile unsigned char *)0x22))

#define PINC	(*((volatile unsigned char *)0x26))
#define DDRC 	(*((volatile unsigned char *)0x27))
#define PORTC 	(*((volatile unsigned char *)0x28))

#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 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

#define sei()   __asm__ __volatile__ ("sei" ::)	
#define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: )

void __vector_1(void) __attribute__((signal, used, externally_visible));	
void __vector_2(void) __attribute__((signal, used, externally_visible));	

#endif	//__MAIN_H__


main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "main.h"
#include "lcd.h"

int main(void)
{
	LCD_Init();
	LCD_STR("TEST");
		
	while(1)
	{
	}

	return 0;
}


LCD에 TEST 출력





728x90

변수


전역변수 : 함수밖 선언 - Data

지역변수 : 함수내 선언 - Stack




전역 변수 사용

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int A;

int main()
{
    printf("%d\n",A);
    return 0;
}



Output:

1
0


전역변수는 0으로 초기화(bss)

지역변수는 stack의 쓰레기 값이 표시됨






두번째 예제

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int A;

int main()
{
    int A = 100;
    printf("%d\n",A);
    return 0;
}

printf가 속한 곳이 우선, 없으면 전역변수의 값이 표시

Output:

1
100



전역변수 사용은 아래와 같은 이유 때문에 최소화하는 것이 좋다.

  • 실행파일 용량 증가

  • 변수 관리의 어려움 (값을 어떤걸 대입하게 될지 모르기에 헷갈릴 수가 있다)

  • 전역변수는 프로그램 종료시까지 메모리를 차지한다.


Code(text)

 .EXE


Compile

Time

Data

BSS

Heap

 실행시

Run

Time

Stack


unsigned int가 메모리에 최적화된 가장 빠른 변수이다.




전역, 지역변수의 주소를 출력하고 할당된 메모리 공간 나누기
#include <stdio.h>

int D;
int E=98;
int F;
int G;
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("---------data---------------------\n");
	printf("G의 주소	: %p\n", &G);
	printf("E의 주소	: %p\n", &E); 
	printf("---------bss-----------------------\n");
	printf("H의 주소	: %p\n", &H);
	printf("F의 주소	: %p\n", &F);
	printf("D의 주소	: %p\n", &D); 
	printf("---------code-----------------------\n");
	printf("printf의 주소   : %p\n", printf); 
	printf("main의 주소     : %p\n", main);

	return 0;
}



Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--------stack--------------------
A의 주소	: 0xfffcd00c
B의 주소	: 0xfffcd008
C의 주소	: 0xfffcd004
---------data---------------------
G의 주소	: 0x8049950
E의 주소	: 0x8049934
---------bss-----------------------
H의 주소	: 0x8049948
F의 주소	: 0x804994c
D의 주소	: 0x8049944
---------code-----------------------
printf의 주소   : 0x80483c0
main의 주소     : 0x80484a4




Atmega 카운터 인터럽트실습


14일에 배운 것을 응용하여 Switch를 통한 인터럽트를 추가해준다. 


main.h / main.c

#ifndef __MAIN_H__ 
#define __MAIN_H__

void Init(void);
void Port_Init(void);
void INT_Init(void);

#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 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

#define sei()   __asm__ __volatile__ ("sei" ::) //sei(); 어셈블리어로 7번비트만 1로 만듬
#define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: )

void __vector_1(void) __attribute__((signal, used, externally_visible)); //신호사용 외부호출 INT0.
void __vector_2(void) __attribute__((signal, used, externally_visible)); // INT1.

#endif //__MAIN_H__

#include "main.h" volatile unsigned int uiState; 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 < 45000; ++uiloop); for(uiloop = 0; uiloop < 50000; ++uiloop); if(1==uiState) { ++uiCnt; } if(uiCnt > 99) //세그먼트에서 앞자리가 9를 넘어가면 지워지는 이유는 uiCnt가 100을 넘어갔을 때이다. 그래서 if문으로 재정의. { uiCnt = 0; } } return 0; } void Init(void) { INT_Init(); Port_Init(); } void Port_Init(void) { DDRA = 0xff; PORTA = 0x00; } void INT_Init(void) { EICRA=(3<<ISC0)|(3<<ISC1); // INT0 0000 0011 3 (2진수 11 = rising edge) INT1도 마찬가지 EIMSK=(1<<INT0)|(1<<INT1); // INT0,1 Enable SREG=SREG|(1<<7); // sei(); 전역 인터럽트 활성화 } void __vector_1(void) { volatile unsigned int uiCnt; uiState = 1; } void __vector_2(void) { volatile unsigned int uiCnt; uiState = 0; }



결과.

두 스위치를 통해 카운터를 시작/정지할 수 있게 된다.


'Study > Embedded' 카테고리의 다른 글

20160317-펌웨어(타이머 카운터)  (0) 2016.03.17
20160316-LCD출력  (0) 2016.03.17
20160314-펌웨어 분석(외부 인터럽트)  (0) 2016.03.15
20160311-펌웨어분석 (FND, LED Test)  (0) 2016.03.12
20160310-CPU 모듈2  (0) 2016.03.10
728x90
스위치를 사용한 외부 인터럽트

상승엣지(rising edge) - 버튼을 누를 때       (L->H)
하강엣지(falling edge) - 버튼에서 손을 뗄 때 (H->L)
High 0V
Low 5V


EICRA,EICRB - 외부 인터럽트 트리거 방식 설정


EICRA (0x69)

 INT3 

 INT2 

 INT1

 INT0

 ISC31

 ISC30

 ISC21

 ISC20

 ISC11

 ISC10

 ISC01

 ISC00


0 0 : INTn의 low 레벨에서 인터럽트
0 1 : Any edge
1 0 : INTn의 falling edge에서 인터럽트
1 1 : INTn의 rising edge에서 인터럽트


EICRB (0x6A)

 INT7

 INT6

 INT5

 INT4

 ISC71

 ISC70

 ISC61

 ISC60

 ISC51

 ISC50

 ISC41

 ISC40

0 1 : 논리값 변화에 의한 인터럽트 



EIMSK (0X3D)
외부인터럽트 INT0~INT7를 개별적으로 허용하는 레지스터 
(여러문을 관할하는 관문이라고 할 수 있음)


EIMSK=(1<<INT0);  // INT 0 활성화


EIMSK=(1<<INT0) | (1<<INT3);   // INT 0, 3 활성화
 


SREG (0x5F)


인터럽트를 열기위한 마지막 관문이라고도 할 수 있음.
7번째 bit를 1로 바꾸면 전역 인터럽트 활성화


Interrupt Vector Table

address의 $는 16진수(0x)를 의미

vector number와 주소, 소스, 그리고 인터럽트 정의를 볼 수 있다.




실습







SW6 을 누를때 인터럽트, LED에 불이 들어오고 나가도록 실습한다.

채터링 현상은 하드웨어적으로 개선할 수 없다면 지연을 통해 소프트웨어적으로 해결한다. 




실습 예제

#define DDRA (*((volatile unsigned char *)0x21)) #define PORTA (*((volatile unsigned char *)0x22)) #define PINA (*((volatile unsigned char *)0x20)) #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 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 #define sei() __asm__ __volatile__ ("sei" ::) //sei(); 어셈블리어로 7번비트만 1로 만듬 #define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: ) void __vector_1 (void) __attribute__((signal, used, externally_visible)); //신호 사용,외부 호출


int main(void) { DDRA=0xFF; PORTA=0x00; EICRA=(3<<ISC0); // INT0 0000 0011 3 (2진수 11 = rising edge) EIMSK=(1<<INT0); // INT0 Enable SREG=SREG|(1<<7); // sei(); 와 같음 while(1) { sleep(); // cpu 부하를 줄임 } return 0; } void __vector_1 (void// $0002 INT0 외부 인터럽트 요청

{ volatile unsigned int uiCnt; for(uiCnt = 0; 30000>uiCnt ; ++uiCnt); // 채터링 현상을 s/w적으로 개선하기 위함 PORTA=~PORTA; // ~은 NOT 연산자, 비트반전

}


'Study > Embedded' 카테고리의 다른 글

20160316-LCD출력  (0) 2016.03.17
20160315-펌웨어 분석 및 학습  (0) 2016.03.16
20160311-펌웨어분석 (FND, LED Test)  (0) 2016.03.12
20160310-CPU 모듈2  (0) 2016.03.10
20160309-CPU 모듈  (0) 2016.03.09

+ Recent posts