마이크로프로세서 응용 및 실습 (AVR Microprocessor) 정 원 근
1. 마이크로 프로세서 정의 미리 확립된 순서(프로그램)에 의해 체계적으로 연산하고 실행하며 각 제어장치들을 1개의 작은 실리콘 칩에 집적시킨 초대규모 집적회로 2. 마이크로 콘트롤러의 정의 마이크로프로세서는 단순이 연산장치인 반도체 소자인 것으로 입출력 장치, 메모리 등을 회로로 구성하여야 하지만, 마이크로콘트롤러는 ROM, RAM, I/O PORT, TIMER, COUNTER 등이 하나의 칩(반도체 소자)에 집적되어 있는 소자 (특징) 제품이 소형화 되고 경량화, 제품의 가격이 저렴, 융통성이 높아 기능 변경이나 확장이 용이, 신뢰성이 높음.
3. 마이크로 프로세서/마이크로 콘트롤러의 종류 8Bit ATTiny2313 C8051F 시리즈 Pic 시리즈 16/32Bit AT91시리즈, 16/32bit, ARM CPU PXA255, 16/32 Bit, ARM CPU MSP430시리즈 16Bit
4. AVR CPU의 특징 및 종류 (1) AVR Series의 특징 ․ 8-비트 RISC(Reduced Instruction Set Computer) 구조로 명령어가 간단하며 동작 속도가 빠름. ․ 1MHz당 약 1MIPS(Million Instruction Per Second)의 성능. ․ 저소비 전력. ․ 10 비트 ADC 내장하고 있다.(일부 패밀리) ․ 다른 마이크로 콘트롤러에 비해 큰 SRAM을 가지고 있음. 예) AT90S8515(512B), Mega103(4KB) ․ Flash memory의 내장으로 프로그래밍이 용이함. ․ EEPROM을 내장하고 있어서 데이터 백업이 가능. ․ C언어에 최적화된 설계. ․ UART, SPI(Serial Pheriperal Interface), PWM 내장. ․ 8비트 및 16비트 타이머 내장.
(2) AVR Series의 종류 (A) Tiny 시리즈 -> RAM이 없거나 적은 모델이 대부분이며 핀 수 또한 적어서 간단한 어플리케이션에 적합. (B) Atmega 시리즈 -> 플래쉬 메모리와 램의 용량이 크고 핀 수 또한 많아서 복잡한 어플리케 이션에 적합.
5. AVR CPU를 이용한 응용 기기 개발 과정 <개발과정> 어셈블러 또는 C 컴파일러 사용 시뮬레이터 또는 에뮬레이터 이용하여 디버깅 타겟 보드를 이용하여 테스트
① SDK(Starterup Development Kit) 6. AVR CPU의 개발 환경 ① SDK(Starterup Development Kit) ▶ ATMEL STK500시리즈, Kanda STK200/300. ▶ AVRMALL AVR Board. ▶ 타사 AVR Development Board. ② Assembler & Compiler ▶ AVR STUDIO, IAR Assembler 등. ▶ AVR-GCC의 기반의 AVR-EDIT(국내), WINAVR(외국) 등의 무료 컴파일러. ▶ IAR, CodevisionAVR, Imagecraft(ICC) 등의 상용컴파일러. ▶ BASCOM-AVR, FastAVR의 Basic 컴파일러. ③ Programmer ▶ Parallel – STK200+/300(Ponyprog2000용으로 많이 사용). ▶ Serial – STK500/AVRISP(AVR STUDIO), AVRprog, ATJTAGICE 외. ▶ USB – AVRISP mk2(AVR STUDIO), USBISP 외. ④ Emulator & Simulator ▶ Emulator – ATJTAGICE, ATJTAGICE mkII, ATICE10/200/30/40/50 외. ▶ Simulator – AVR STUDIO3, AVR STUDIO4, IAR C-SPY Debugger
* SDK(Starterup Development Kit) ▶ ATMEL STK500시리즈 ▶ Kanda STK200/300 ▶ AVRMALL AVR Board ▶ ATTiny2313/At90S2313 Board
* Programmer Programmer ▶ Parallel – STK200+/300 (Ponyprog2000용으로 많이 사용) ▶ Serial – STK500/AVRISP (AVR STUDIO), AVRprog, ATJTAGICE 외 ▶ USB – AVRISP (AVR STUDIO), USBISP 외 * ISP PORT
* Codevision 컴파일 AVR C-compliler Atmel-AVR에 대한 통합개발환경과 자동 프로그램생성 기능 보유. 시스템 환경은 Windows 95,98,NT 4,2000과 XP CodevisionAVR 에서 지원하는 C 코드는 ANSI-C에 가까운 C 사용. (4) 컴파일된 COFF 파일은 C 소스 디버거용 소스 파일이며, AVR Stdio에서 디버깅 툴을 이용하여 변수 모니터링 등을 할 수 있음. (5) 통합개발환경(IDE)는 Compile 후에 In-System program 을 이용하여 AVR chip에 자동적으로 파일을 전송. In-System programmer 는 STK500, Kanda SYSTEM STK200+/300 보드에 연결하여 사용. Codevision AVR은 Code wizard 기능을 이용하여 필요한 기능에 대한 소스코드를 자동적으로 생성.
* Codevision 컴파일 통합환경 실행 마우스로 더블 클릭 프로그램 작성/편집창 프로젝트관리창 [파일 또는프로젝트 열기] [컴파일 실행] [자동프로그램 생성 마법사] [새파일/새프로젝트] [컴파일 및 기계어코드 생성] CPU로 기계어코드 다운로드 및 메모리관리
* 새 프로젝트 만들기 실습 CodeVision의 환경설정과 컴파일 링크를 알아보고, B0 포트가 0.1초 간격으로 점등하는 프로그램을 만들고 이를 실행하는 과정을 예제로 실습. 1. CodeVison을 실행한다 2. 메뉴중에 [File->New] 를 선택하고 오른쪽 그림의 [Project]를 선택하여 Project 파일을 만든다.
3. 아래 그림과 같이 CPU와 클럭을 선택한다 4. [Ports]에서 B포트를 출력으로 선택한다.
5. 컴파일후 프로그램을 CPU로 다운로드 하도록 ISP와 프로젝트 환경 설정 선택 선택
6. [File]->[Generate,Save and Exit] 메뉴를 선택한다. 7. 이름은 모두 “led”로 하여 “led.c” “led.prj” “led.cwp”를 만들면 기본적인 프로그램이 만들어 진다.
7. 시간 지연 함수(delay_ms())를 사용하기 위해 . #include <delay.h> 문자을 추가. 8. Main()에 있는 While()안에 아래의 명령 추가 /********************************************* This program was produced by the CodeWizardAVR V1.23.5 Evaluation Automatic Program Generator ?Copyright 1998-2002 HP InfoTech s.r.l. http://www.hpinfotech.ro e-mail:office@hpinfotech.ro , hpinfotech@xnet.ro Project : Version : Date : 2003-06-24 Author : Company : Comments: Chip type : ATmega8515 Program type : Application Clock frequency : 16.000000 MHz Memory model : Small Internal SRAM size : 4096 External SRAM size : 0 Data Stack size : 1024 *********************************************/ #include <mega8515.h> #include <delay.h> // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off // Analog Comparator Output: Off ACSR=0x80; SFIOR=0x00; while (1) { PORTB=0xff; //각 포트에 1를 출력 delay_ms(100); PORTB=0x00; delay_ms(100); }; }
ISP 포트 9. C 프로그램을 컴파일하고 기계어를 생성 10. ISP 케이블을 연결하고, 프로그램 다운로드를 실행 (1) 컴파일 실행] (2) 컴파일 및 기계어코드 생성] 10. ISP 케이블을 연결하고, 프로그램 다운로드를 실행 ISP 포트
7. 시간 지연 함수(delay_ms())를 사용하기 위해 . #include <delay.h> 문자을 추가. 8. Main()에 있는 While()안에 아래의 명령 추가 /********************************************* This program was produced by the CodeWizardAVR V1.23.5 Evaluation Automatic Program Generator ?Copyright 1998-2002 HP InfoTech s.r.l. http://www.hpinfotech.ro e-mail:office@hpinfotech.ro , hpinfotech@xnet.ro Project : Version : Date : 2003-06-24 Author : Company : Comments: Chip type : ATmega8515 Program type : Application Clock frequency : 16.000000 MHz Memory model : Small Internal SRAM size : 4096 External SRAM size : 0 Data Stack size : 1024 *********************************************/ #include <mega8515.h> #include <delay.h> // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off // Analog Comparator Output: Off ACSR=0x80; SFIOR=0x00; while (1) { PORTB=0xff; //각 포트에 1를 출력 delay_ms(100); PORTB=0x00; delay_ms(100); }; }
6. AVR CPU의 구조와 기능 6.1 내부 구조 6.2 코어 6.3 외부 구조 및 기능 6.4 특징 6.5 메모리구조 6.6 클럭 6.7 리셋
6.1 AVR CPU의 내부 구조
6.2 코어(Core) 6.3 외부 구조 및 기능 <ATTiny2313>
6.4 특징 (1) ISP(In-system programming) 기능 : 롬라이터 없이 PC에서 바로 프로그램을 다운로딩 (2) 118개의 명령어 (3) 프로그램 메모리 : 2K Bytes (4) 데이터 메모리 : SRAM 128 Bytes, EEPROM 128 Bytes (5) One 8-bit Timer/Counter with Separate Prescaler (6) One 16-bit Timer/Counter with Separate Prescaler, Compare, Capture Modes and 8-, 9- or 10-bit PWM (7) On-chip Analog Comparator (8) Full Duplex UART - 15 Programmable I/O Line (9) 동작전압 : 4V ~ 6V (10) 명령어 속도 : 10MHz (10MIPS)
6.5 ATTiny2313 / AT90S2313의 메모리 구조 <Flash memory 공간> <사용자 memory(S-RAM) 공간>
6.6 ATTiny2313 / AT90S2313의 클럭
6.6 ATTiny2313 / AT90S2313의 리셋(Reset) * RESET 회로 : RESET 단자에 1ms이상 Low로 유지후 High로 유지
7. I/O 포트 및 I/O 제어 실습 * I/O 포트 * 각 포트의 CPU 내부 구조 출력 입력
< 실험용 키트 회로도>
* I/O 포트의 특징 ⊙ 8비트 양방향 병렬 I/O포트로 구성 ⊙ Read-Modify-Write 동작 가능 ⊙ H상태의 source drive 와 L상태의 sink drive 능력이 대칭적 ⊙ 최대 구동전류 (sinks up to 40 mA) ⊙ 풀업저항의 사용 여부를 설정(Pinwise Controlled Pull-Up Resistors) ⊙ 데이터 입출력방향을 설정(Pinwise Controlled Data Direction) ⊙ Three Control/Status Bits per Bit/Pin
* I/O 포트를 위한 레지스터 ⊙ DDRx (Data Direction Register) : 입출력의 방향을 설정 ⊙ PORTx (Data Register) : 데이터 출력에 해당하는 PORTx 레지스터 ⊙ PINx (Port Input Pins Address) : 포트 입력 핀에 해당하는 PINx 레지스터 ⊙ DDR, PORT 는 읽고 쓰는 것이 가능, PIN은 읽는 것만 가능한 레지스터 ⊙ 내부 풀업 저항을 사용하려면 PUD비트를 0로 설정 (DDRx = 0, PORTx = 1) * 포트와 해당 레지스터와 관계
* 디지털 출력 (LED 순차 점등) 예제 #include <90s2313.h> // 사용하는 AVR Chip은 AT90S2313임 #include <delay.h> // delay_ms()함수를 사용하므로 필요 unsigned char led_status = 0x80; // led_status에대한 외부 변수 사용, 초기값설정 void main(void) // 메인 함수 시작 { DDRB=0xff; // PORTB를 출력으로 사용. PORTB=0xff; // PORTB의 초기치값 설정 while (1) // 무한루프 led_status >>= 1; // 오른쪽으로 1비트 이동 delay_ms(1000); // 1초간 시간 지연 led_status |= 0x80; // PORTB의 7번 포트를 1로 셋 시킴 if (led_status == 0xff) led_status = 0x80; // led_status가 0x00이면 // led_status는 초기치값은 0x80 PORTB = led_status; // PORTB를 led_status로 정의 }; }
* 디지털 입력 및 출력 (7-segment 점등) 예제 #include <90s2313.h> #include <delay.h> // hex폰트값(0 ~ 9), 배열을 이용하여 출력하고자 하는 값을 설정 char seg1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; void main(void) { int i=0, sw=1; // i에 대한 변수 선언 DDRB=0xff; PORTB=0xff; // PORTB를 출력으로 사용, 초기치 값 DDRD=0x00; PORTD=0xff; while (1) { sw=1; while(sw){ if (PIND.2==0) sw=0; // Key 누름 검사 } sw=1; delay_ms(50); if (PIND.2==1) sw=0; i++; if (i>=10) j=0; PORTB = seg1[i]; // 폰트값을 출력한다 };
7. 외부 인터럽트 개념 및 실습 * 인터럽트의 개요 ⊙ embedded program은 interrupt-driven (event-driven)방식 ⊙ 외부의 하드웨어적인 요구에 의해서 정상적인 프로그램의 실행 중에 시급한 작업을 먼저 수행한 후에 다시 원래의 프로그램으로 복귀하는 실행. ⊙ Interrupt 와 polling 방식의 비교 ⊙ 주변장치의 서비스 요청에 CPU가 가장 빠르게 대응할 수 있는 방법 ⊙ 인터럽트 발생시 나중에 되돌아 올 복귀주소(return address)가 자동적으로 스택에 저장되었다가 인터럽트 서비스 루틴의 마지막에 복귀(return) 명령을 만나면, 자동적으로 이 복귀주소가 찾아져서 인터럽트 발생전의 위치로 정확하게 되돌아감.
* 인터럽트의 종류 ⊙ 인터럽트 발생 원인에 따른 분류 - 하드웨어 인터럽트 -> 내부 인터럽트 : 나눗셈 에러, 보호된 메모리 영역에의 접근 등의 원인 -> 외부 인터럽트 : 타이머, 직렬포트, A/D변환 완료, DMA 동작의 종료 - 소프트웨어 인터럽트 ⊙ 인터럽트 발생시 마이크로프로세서의 반응 방식에 따른 분류 - 차단 가능 인터럽트(INT; maskable interrupt) : EIMSK, SEI, CLI - 차단 불가능 인터럽트(NMI; non-maskable interrupt) ⊙ 인터럽트를 요구한 입출력 기기를 확인하는 방법에 따른 분류 - 벡터형 인터럽트(vectored interrupt) - 조사형 인터럽트(polled interrupt)
* 인터럽트 처리 과정 * 인터럽트의 종류
* 외부 인트럽트 및 제어 ⊙ 외부 인터럽트는 8개의 외부핀 INT0~1을 통해 입력되는 신호에 의하 여 발생되는 인터럽트 ⊙ 외부 인터럽트는 Low의 논리레벨, 하강 에지, 상승에지 등에 의하여 트리거 될 수 있음 ⊙ 외부 인터럽트 제어 레지스터에 의해 모드 설정 ⊙ 전체적인 Interrupt를 enable 시킴 - I (Global Interrupt Enable) - SREG (Status Register), bit 7 - 내용: global interrupt enable을 결정. ⊙ interupt service시 clear, RETI후 set 1 : global interrupt enable ( C 프로그램에서 -> #asm(“sei”) ) 0 : global interrupt disable ( C 프로그램에서 -> #asm(“cli”) )
* 외부 인트럽트 제어 레지스터
* 외부 인터럽트(INT0) 예제 새프로잭트 실행 (2) CPU 및 클럭 설정 외부 인터럽트 INT0에 신호가 high에서 low로 변화될 때 LED 가 순차적으로 이동하는 프로그램 작성. 여기서 외부 인트럽트는 key를 누를떄 발생함. 새프로잭트 실행 (2) CPU 및 클럭 설정
* 외부 인터럽트(INT0) 예제 (3) I/O 포트 입.출력 설정 (4) 인트럽트 설정
(5) 프로그램 생성 이름을 모두 “ex0.c” “ex0.prj” “ex0.cwp”로 각각 지정하여 프로그램이 생성.
* 외부 인터럽트 제어 프로그램 소스 #include <tiny2313.h> #include <delay.h> unsigned char led_status = 0x80; // led_status에대한 외부 변수 사용, 초기값설정 // External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { #asm(“cli”) led_status >>= 1; // 오른쪽으로 1비트 이동 led_status |= 0x80; // PORTB의 7번 포트를 1로 셋 시킴 if (led_status == 0xff) led_status = 0x80; PORTB = led_status; // PORTB를 led_status로 정의 #asm(“sei”) } void main(void) PORTB=0x00; DDRB=0xFF; //출력으로 설정 PORTD=0x00; DDRD=0x00; // 입력으로 설정 // INT0: On, INT0 Mode: Falling Edge, INT1: Off GIMSK=0x40; MCUCR=0x03; EIFR=0x40; #asm("sei") //Global enable interrupts while (1) ;
8. 타이머 /타이머 인트럽트 개념 및 실습 ⊙ ATTiny2313은 2개의 타이머/카운터를 구성 - 타이머/카운터0는 8비트 구조이며 타이머/카운터1은 16비트 구조 ⊙ 타이머/카운터는 내부클럭 혹은 외부클럭을 사용시 프리스케일러의 적용 ⊙ 모두 인터럽트 및 PWM 출력 기능을 가짐 - 오버플로우 인터럽트(overflow interrupt) : 카운터의 값이 오버플로우되는 경우 발생 - 출력비교 인터럽트(output compare match interrupt) : 카운터 값이 출력 비교 레지스터의 값과 같게 되는 순간에 발생 - 입력캡쳐 인터럽트(input capture interrupt) - PWM : 출력비교 기능을 이용하여 출력비교 신호에 주기와 듀티비를 가변할 수 있는 출력 신호를 발생(OC0A, OC1A/OC1B)
* Timer/Counter 0 ⊙ 0에서 255까지 셀 수 있는 8비트 타이머/카운터 ⊙ 타이머로 사용될 때는 내부 클럭을 분주하여 이용 ⊙ 8비트 PWM 신호를 만들어서 포트로 출력
⊙ 인터럽트 주기 공식 Interrupt Cycle = (Prescale Ratio/Clock) * (256-TCLK0) 인터럽트 주기 = (프리스케일러비/클럭)*(256-TCLK0레지스터값) 예)프리스케일러비 256, 클럭 16MHz, TCLK0는 56 (256/16*10^6)*(256-56) = 3.2ms
<Timer/Counter 0의 레지스터> * C-언어에서 사용되는 Timer/Counter 0에 대한 레지스터 <Timer/Counter 0의 레지스터> TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; < 타이머 인트럽트 레지스터> TIMSK=0x00;
* 타이머 인터럽트 프로그램 소스 void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0xFF; // Timer/Counter 0, Clock // source: System Clock, // Clock value: 10.800 kHz, // Mode: Normal top=FF, TCCR0A=0x00; TCCR0B=0x05; TCNT0=0x10; OCR0A=0x00; OCR0B=0x00; // Timer interrupt(s) TIMSK=0x02; #asm("sei") while (1); } #include <tiny2313.h> // Timer 0 overflow interrupt routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { #asm(“cli”) led_status >>= 1; led_status |= 0x80; if (led_status == 0xff) { led_status = 0x80; } PORTB = led_status; TCNT0=0x10; #asm(“sei”)
9. LCD 제어 <문자 LCD의 핀 구조> <문자 LCD> <Back Light 회로>
* 문자 LCD 제어 명령
* LCD 초기화 과정
< Codevision에서의 LCD 제어 명령> unsigned char lcd_init(unsigned char lcd_columns) : - initializes the LCD void lcd_clear(void) : - clears the LCD and sets the printing character position at row 0 and column 0. void lcd_gotoxy(unsigned char x, unsigned char y) - sets the current display position at column x and row y. The row and column numbering starts from 0. void lcd_putchar(char c) - displays the character c at the current display position. void lcd_puts(char *str) - displays at the current display position the string str, located in SRAM. void lcd_putsf(char flash *str) - displays at the current display position the string str, located in FLASH.
* LCD 제어 프로그램 소스 #include <tiny2313.h> #asm .equ __lcd_port=0x18 ;PORTB #endasm #include <lcd.h> void main(void) { char s[6]=“TEST!”; PORTB=0x00; DDRB=0x00; lcd_init(16); lcd_gotoxy(0,0); lcd_puts(s); while (1); }