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
728x90

카운터와 LED TEST



VCC는 빨간선, GND는 검은색 선임을 잘 확인하고 기판에 연결



seven segment에 00 이 출력된다.






 3

 2

 1

 0

 3

 2

 1

 0

 J

 1

 9

 L

 L

 L

 L

 H

 L 

 L 

 H 


0 | 9

09를 출력하기 위해선 PORTA에서 J19에 연결되는 핀을 위와 같이 연결한다. 






프로그래밍을 통한 숫자 바꾸기


숫자 34 출력



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#define DDRA (*((volatile unsigned long *)0x21)) #define PORTA (*((volatile unsigned long *)0x22)) #define PINA (*((volatile unsigned long *)0x20)) int main(void) //void 안적으면 컴파일시 warning isn't a prototype { volatile unsigned long uiCnt; DDRA=0xFF; // 모두 출력으로 쓴다. PORTA=0x00; PORTA=((34/10)<<4)|34%10; while(1) { } return 0; }


십자리에 3을 출력

34/10=3

3=0011  

0011<<4=00110000  // 0011의 비트를 왼쪽으로 4칸 이동 (shift 연산자)


일자리에 4를 출력

34/10의 몫은 3이고 "나머지는 4"


0011 0000

0000 0100

------------------비트 or연산 (논리합)

0011 0100




카운터 


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


int main(void) //void 안적으면 컴파일시 warning isn't a prototype
{
	volatile unsigned int uiCnt;
	volatile unsigned int uiLoop;

	DDRA=0xFF; // 모두 출력으로 쓴다.	
 	PORTA=0x00;

	uiCnt=0;
	while(1)
	{	
		for(uiLoop=0;60000>uiLoop;++uiLoop);
                PORTA=((uiCnt/10)<<4)|(uiCnt%10);
		++uiCnt;
	}
	return 0;
}



위 소스 그대로 프로그래밍시 카운터 앞자리가 사라지는 문제가 생긴다.



해결을 위해 while문 사이에 소스를 추가  if(uiCnt>99) { uiCnt=0; }
#define DDRA	(*((volatile unsigned long *)0x21))
#define PORTA	(*((volatile unsigned long *)0x22))
#define PINA	(*((volatile unsigned long *)0x20))


int main(void) //void 안적으면 컴파일시 warning isn't a prototype
{
	volatile unsigned int uiCnt;
	volatile unsigned int uiLoop;

	DDRA=0xFF; // 모두 출력으로 쓴다.	
 	PORTA=0x00;

	uiCnt=0;
	while(1)
	{	
                if(uiCnt>99)
		{
			uiCnt=0;
		}

		for(uiLoop=0;60000>uiLoop;++uiLoop);
                PORTA=((uiCnt/10)<<4)|(uiCnt%10);
		++uiCnt;
	}
	return 0;
}

앞자리 문제 해결



if, else문 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main()
{
	int iNum;
	printf("숫자를 입력하시오: \n");
	scanf("%d", &iNum);
	
	if(100<iNum)
	{
		printf("100보다 큰수입니다\n");
	}
	else
	{
		printf("100보다 작은수입니다\n");
	}
	return 0;
}

if()에서 괄호안이 조건


조건이 참일때 if {}의 내용들 수행

거짓일때 else {}의 내용들 수행



Output:





LED 교차 점등 TEST


#define DDRA (*((volatile unsigned char *)0x21)) #define PORTA (*((volatile unsigned char *)0x22)) #define PINA (*((volatile unsigned char *)0x20)) int main(void) //void 안적으면 컴파일시 warning isn't a prototype { volatile unsigned int uiCnt; unsigned int uiPos; uiPos=0; int iDir=1; DDRA=0xFF; // 모두 출력으로 쓴다. PORTA=0x00; // LED를 끈다. while(1) { if(1==iDir)// iDir(direction)이 1일때 { PORTA=~(1<<uiPos); //순방향 } else { PORTA=~(0x0080>>uiPos); //역방향 0x0080=1000 0000 } for(uiCnt=0;60000>uiCnt;++uiCnt); uiPos=uiPos+1; if(7<uiPos) { iDir=iDir*-1; // iDir이 -1이 되고 else{} 수행 uiPos=0; } } return 0; }


19번째 줄 PORTA=~(1<<uiPos);

~( )은 NOT 연산자


1<<uiPos   0000 0001을 왼쪽으로 uiPos(0~7)의 bit만큼 옮김

끝의 LED는 1000 0000이며, NOT 연산자인 ~()가 붙어서 0111 1111이 됨


PORTA


 L

 H

 H

 H

 H

 H

 H

 L

 0

 1

 1

 1

 1

 1

 1

 0



if(7<uiPos) { iDir=iDir*-1; uiPos=0; }

uiPos가 7을 초과할 시, iDir은 -1이 되고 else{} 수행


LED TEST



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

20160316-LCD출력  (0) 2016.03.17
20160315-펌웨어 분석 및 학습  (0) 2016.03.16
20160314-펌웨어 분석(외부 인터럽트)  (0) 2016.03.15
20160310-CPU 모듈2  (0) 2016.03.10
20160309-CPU 모듈  (0) 2016.03.09
728x90

2016-03-10 <CPU 모듈>


Atmel ATmega 2560


Brown-out Detection 

특정 전압 이하로 떨어지는걸 방지, 자동으로 CPU를 리셋하는 회로.


Watchdog 

특정한 시간동안 시스템이 응답없으면 리셋시킴.


86 Programmable I/O Lines

86개의 제어가능한 입출력(Input/Output) 라인.



칩의 심박수가 곧 "Clock"


발진기(오실레이터)

발진회로 혹은 클럭발생기라고도 함


Crystal - XTAL  

수정발진자 혹은 수정진동자라고 함



16.000 MHz  

소수점 이하 0이 많이 붙을수록 정확한 진동자


1초에 16000000 개를 센다.


타이머 카운터(T/C) - 시간 측정회로, 기준이 되는 것은 동작 주파수




GPR(General Purpose Register)과 Data SRAM간의 Direct Addressing 

: Memory와 Register간 직접 주소 연결




AVR memories

256kb Flash Memory



0x7FFF(0~)-> 0x8000   -> 32768 /1024  -> 32

0xFFFF     -> 0X10000 -> 65536 /1024  -> 64

0x1FFFF    -> 0X20000 -> 131072/1024 -> 128


flash memory 한 Section에 2byte 공간을 가지기에 128 x 2 = 256kbyte를 가짐





인텔 CPU는 폰 노이만 구조. 폰 노이만은 컴퓨터 설계의 기본을 만든 천재 수학자.

하바드(Harvard) 구조는 양방향이라 효율적이고 빠르지만 단가가 비싸다. 



DDRA - Port A  Data Direction Register

데이터의 방향을 결정하는 레지스터


0-7번 비트까지 8bit Register를 가지며, 읽고 쓰기가 가능하다.

initial value(초기값)는 0이고 0과 1에 따라 Direction이 바뀐다. 


Port-출력과 방향

DDR-방향을 결정


Port에 값을 줄건지 말건지에 따라 5V 또는 0V 가 출력.




LED 두개, 교차 깜박임 실습


LED 두개의 한쪽 선을 각각 PORT A의 1번, 5번에 꼽음 (나머지 한쪽선은 각각 GND에 꼽음)




PORTA의 1번


 7

 6

 5

 4

 3

 2

 1

 0

 0

 0

 0

 0

 0

 0

 1

 0


0 | 2  


PORTA의 5번


 7

 6

 5

 4

 3

 2

 1

 0

 0

 0

 1

 0

 0

 0

 0

 0


| 0  




소스

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


int main(void) //void 안적으면 컴파일시 warning isn't a prototype
{
	volatile unsigned long uiCnt;
	DDRA=0xFF; // 출력으로 쓴다.	

	while(1)
	{
		for(uiCnt=0; 100000>uiCnt;++uiCnt);
		PORTA=0x02; //2번
		for(uiCnt=0; 100000>uiCnt;++uiCnt);
		PORTA=0x20; //5번		
	}
	return 0;
}



결과 - LED 두개가 번갈아 깜박거리는 것을 볼 수 있다.





전해 콘텐서는 순간적으로 전압이 떨어지는 걸 방지한다. (일종의 배터리)




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

20160316-LCD출력  (0) 2016.03.17
20160315-펌웨어 분석 및 학습  (0) 2016.03.16
20160314-펌웨어 분석(외부 인터럽트)  (0) 2016.03.15
20160311-펌웨어분석 (FND, LED Test)  (0) 2016.03.12
20160309-CPU 모듈  (0) 2016.03.09

+ Recent posts