AVR 마이크로컨트롤러 프로그래밍 절차. 초보 마이크로컨트롤러 프로그래머를 위한 조언. 필수 프로그램 세트

그래서 우리는 전환 및 주소 지정과 관련된 커널 작업을 정리했습니다. 이제 우리의 관심을 다른 영역, 즉 기억으로 돌릴 때입니다.

두 가지 유형이 있습니다(EEPROM은 일반적으로 주변 장치이므로 포함되지 않지만 나중에 자세히 설명합니다).

  • 램 - 램
  • ROM - ROM, 일명 플래시, 일명 프로그램 메모리

우리의 아키텍처는 Harvard이므로 요원에게는 자체 주소가 있고 플래시에는 자체 주소가 있습니다. 데이터시트에서 RAM 주소 지정 구조를 볼 수 있습니다.

바로 주소를 주목하세요! RON과 주변 레지스터, RAM은 동일한 주소 공간에 위치합니다. 저것들. 0000부터 001F까지의 주소가 레지스터를 차지하고, 주소 005F까지 I/O 셀(포트)이 있습니다. 포트를 통해 컨트롤러에 탑재된 모든 것이 구성됩니다. 그런 다음에만 주소 0060에서 의도한 목적으로 사용할 수 있는 RAM이 나옵니다.

또한 I/O 레지스터에도 고유한 주소 지정이 있습니다. I/O 레지스터의 주소 공간(00에서 3F까지)은 그림의 왼쪽에 표시되어 있습니다. IO/레지스터 블록 이 주소 지정은 OUT 및 IN 명령어에서만 작동하며 이는 흥미로운 기능으로 이어집니다.

주변 장치 레지스터는 두 가지 방법으로 액세스할 수 있습니다.

  • I/O 주소 공간의 짧은 주소에서 IN/OUT 명령을 통해
  • RAM 주소 공간의 전체 주소에서 LOAD/STORE 명령 그룹을 통해

예. 비동기 트랜시버 UDR의 입력 레지스터를 살펴보겠습니다. 주소는 0x0C(0x2C)이며 일반 주소 공간의 주소는 괄호 안에 표시됩니다.

LDI R18.10; 숫자 10을 R18 레지스터에 로드했습니다. OUT UDR,R18 ; 첫 번째 방법으로 추론하면 컴파일러 자체입니다. UDR STS 0x2C,R18 대신 0x0C 값을 대체합니다. 그들은 나를 두 번째 방법으로 데리고 나갔습니다. Store 명령을 통해; 주소를 직접 입력하면 됩니다.

두 방법 모두 동일한 결과를 제공합니다. 하지만! 입/출력 공간(OUT/IN)에서 주소 지정을 통해 작동하는 것들은 2바이트 더 짧습니다. 이것은 이해할 수 있습니다. 임의의 메모리 셀의 더블 바이트 주소를 저장할 필요가 없으며 입출력 공간의 짧은 주소가 더블 바이트 명령어 코드에 맞습니다.

사실, 여기에 또 다른 농담이 있습니다. 사실 매년 AVR의 돌이 점점 더 많이 나타나고 그 안에 고기가 점점 더 많이 들어 있습니다. 그리고 각각의 크래킹에는 자체 주변 I/O 레지스터가 필요합니다. 그리고 이제 우리는 ATMega88(Mega8을 대체함)에 이미 주변 장치가 너무 많아서 I/O 레지스터가 더 이상 3F 주소 공간 제한에 맞지 않는다는 결론에 도달했습니다.

이런, 도착했어요. 그리고 이것은 오래된 돌에서 새 돌로 바꾸는 사람들이 당황한 표정을 표현하기 시작하는 곳입니다. 왜 OUT/IN 명령이 일부 주변 레지스터에서는 작동하지만 다른 레지스터에서는 작동하지 않습니까?

그리고 간단합니다. 비트 용량이 충분하지 않았습니다.

하지만 핵심은 하나이므로 더 이상 다시 만들 수 없습니다. 그리고 여기서 ATMEL 사람들은 교활하게 행동했습니다. 그들은 소위 메모리 매핑 레지스터를 도입했습니다. 저것들. 3F 제한에 맞지 않는 모든 레지스터는 이제 로드/저장을 통해 한 가지 방법으로만 사용할 수 있습니다.

좋은 농담 이었어. m88def.inc를 열면 어떤 I/O 레지스터가 "올바른"지, 어떤 것이 메모리 매핑되어 있는지 확인할 수 있습니다.

다음과 같은 것이 있을 것입니다:

; ***** I/O 레지스터 정의 **************************************** ******** * ; 메모: ; "MEMORY MAPPED"라고 표시된 정의는 확장된 I/O 포트입니다. IN/OUT 명령어와 함께 사용할 수 없습니다. .equ UDR0 = 0xc6 ; 메모리 매핑 .equ UBRR0L = 0xc4 ; 메모리 매핑 .equ UBRR0H = 0xc5 ; 메모리 매핑 .equ UCSR0C = 0xc2 ; 메모리 매핑 .equ UCSR0B = 0xc1 ; 메모리 매핑 .equ UCSR0A = 0xc0 ; 메모리 매핑 어쩌고 저쩌고 등등.equ OSCCAL = 0x66 ; 메모리 매핑 .equ PRR = 0x64 ; 메모리 매핑 .equ CLKPR = 0x61 ; 메모리 매핑 .equ WDTCSR = 0x60 ; 메모리 매핑 .equ SREG = 0x3f ;<------ А тут пошли обычные.equ SPL = 0x3d .equ SPH = 0x3e .equ SPMCSR = 0x37 .equ MCUCR = 0x35 .equ MCUSR = 0x34 .equ SMCR = 0x33 .equ ACSR = 0x30

이것들은 파이입니다.

그리고 이 분야에서는 대형 모피 오르간이 그것을 단단히 덮는다는 목표를 가지고 어셈블리 코드의 모델 간 호환성을 향해 날아가고 있다는 것을 이해합니다. 결국 모든 종류의 매크로 정의와 레지스터를 설명하는 정의를 수정하는 것과 신데렐라처럼 올바른 포트와 잘못된 포트를 분리하는 것이 또 다른 것입니다.

그러나 해결책이 있습니다. 매크로 언어! 명령 시스템이 마음에 들지 않습니까? 블랙잭과 창녀들로 나만의 것을 만들어보세요!
만능 OUT처럼 우리만의 팀 UOUT을 만들어보자

IN 명령의 경우에도 마찬가지입니다. 일반적으로 이러한 매크로를 사용하면 어셈블러를 매우 다양화하여 모든 종류의 C 및 Pascal을 걸레처럼 찢을 수 있는 강력한 프로그래밍 언어로 바꿀 수 있습니다.

글쎄요, 제가 무슨 말을 하고 있는 걸까요... RAM에 대해서요.

그래서 우리는 주소 지정을 정리했습니다. 이제 데이터시트의 메모리 맵 섹션에서 사용자 RAM 셀이 시작되는 메모리 주소를 찾을 수 있는 위치를 알았습니다. 하지만 참고할 만한 내용이 있습니다.

그리고 우리 코드에서 RAM은 지시문으로 시작합니다. DSEG 템플릿을 기억하시나요?

"m16def.inc"를 포함합니다. 우리는 ATMega16을 사용합니다 ;= Macro.inc 시작 ============================== ; 매크로는 여기에 있습니다;= 매크로 종료 ================================= ; 램 ================================================ ============ .DSEG; RAM 세그먼트; 플래시 ================================================ ========== .CSEG ; 코드 세그먼트; EEPROM ================================================ ======== .ESEG ; EEPROM 세그먼트

.DSEG 이후에 변수를 설정할 수 있습니다. 그리고 여기에 우리는 단순히 세포의 폭발을 가지고 있습니다. 어느 하나를 차지하십시오. 주소를 입력하고 행복하세요. 그런데 왜 주소를 수동으로 계산합니까? 컴파일러가 여기서 생각하게 하세요.

따라서 우리는 라벨을 가져와 설정하겠습니다.

0x0060 ## ;변수 0x0061 ## 0x0062 ## 0x0063 ## ;변수2 0x0064 ## 0x0065 ## ;변수4는 여기에서 시작할 수 있습니다.

## 임의의 바이트로. 기본적으로 FF입니다. 물론 변수 입력, 초기 초기화, 오버플로 제어 및 기타 부르주아적 즐거움에 대해 이야기할 필요가 없습니다. 여기는 스파르타! 내 말은, 어셈블러. 모두 손으로.
C로 비유하자면, void 포인터만을 통해서 메모리로 작업하는 것과 같습니다. Sishniks는 이해할 것입니다. 그들은 이해하고 겁에 질릴 것입니다. 왜냐하면 이 세상은 잔인하고 배신적입니다. 지수를 조금 잘못 계산해서 다른 데이터를 잃어버렸어요. 그리고 이 오류가 바로 나타나지 않으면 이 오류를 발견하게 될 것입니다.

그래서 관심, 관심, 또 관심. 우리는 추적을 통해 모든 메모리 작업을 실행하며 실패하거나 오버플로되는 일은 없습니다.

.ORG 지시문은 데이터 세그먼트에서도 작동하며 정확히 동일한 방식으로 작동합니다. 즉, 여기에서 메모리 끝까지 주소(이 경우 표시)를 전송합니다. 단 하나의 미묘한 점 - ORG 0000은 RAM의 시작 부분을 제공하며 이는 R0 및 기타 레지스터입니다. 예를 들어 Mega16을 사용하는 0km의 RAM은 ORG 0x0060을 제공합니다. 그리고 다른 컨트롤러에는 다른 값이 있습니다. 매번 데이터 시트를 검토하는 것은 게으른 일이므로 특정 MK의 RAM 시작을 나타내는 SRAM_START와 같은 매크로 정의가 있습니다.

따라서 RAM의 시작 부분(예: 100바이트)을 일종의 가비지 버퍼 아래에 남겨두려면 이 트릭을 수행합니다.

1 2 3 4 .DSEG .ORG SRAM_START+100 변수: .byte 3

DSEG .ORG SRAM_START+100 변수: .byte 3

완료되었습니다. 버퍼 영역을 처음부터 100까지 지웠습니다.

좋아요, 주소를 정리했습니다. 메모리 셀을 사용하는 방법은 무엇입니까? 그리고 이러한 목적을 위해 두 가지 명령 그룹이 있습니다. LOAD 및 STORE는 가장 큰 명령 그룹입니다.

사실 RAM 셀에서는 RON에서 바이트를 로드하거나 RAM 셀에서 RON으로 바이트를 언로드하는 것 외에는 아무것도 수행할 수 없습니다.

Store(ST**) 명령은 RAM에 기록되고 Load(LD**) 명령은 읽혀집니다.

읽기는 레지스터 R16…R31로 이동하며 셀 주소는 명령에 직접 지정됩니다. 다음은 간단한 예입니다. 3바이트의 Variables 변수가 있으므로 1씩 증가해야 합니다. 즉, Variables++ 작업 수행

DSEG 변수: .byte 3 변수2: .byte 1 .CSEG ; 변수는 메모리에 있으므로 먼저 가져와야 합니다. LDS R16, 변수 ; R16 LDS R17, Variables+1 에서 첫 번째 변수 바이트를 읽습니다. R17 LDS R18, Variables+2 에서 두 번째 변수 바이트를 읽습니다. 음, R18의 세 번째 바이트입니다. 이제 여기에 1을 더해 보겠습니다. 왜냐하면 AVR은 상수로만 더할 수 없습니다. 빼려면 왜곡해야합니다. 그러나 특별한 문제는 발생하지 않습니다. SUBI R16,(-1) ; 일반적으로 SUBI는 뺄셈이지만 -(-는 + SBCI R17,(-1) 을 제공합니다. 여기서는 전송이 고려됩니다. 그러나 이에 대해서는 나중에 자세히 설명합니다. SBCI R18,(-1) ; 어셈블러의 수학은 다른 이야기 STS Variables, R16 ; 모두 그대로 저장합니다 STS Variables+1,R17 STS Variables+2,R18

아니면 다른 방법을 사용할 수도 있습니다. 인덱스 레지스터를 통한 간접 기록.

DSEG 변수: .byte 3 변수2: .byte 1 .CSEG ; 변수 LDI YL,low(Variables) LDI YH,High(Variables) 의 주소를 가져옵니다. 변수는 메모리에 있으므로 먼저 가져와야 합니다. LD R16, Y+ ; R16 LD R17, Y+에서 첫 번째 변수 바이트를 읽습니다. R17 LD R18, Y+에서 두 번째 변수 바이트를 읽습니다. 음, R18의 세 번째 바이트입니다. 이제 여기에 1을 더해 보겠습니다. 왜냐하면 AVR은 상수로만 더할 수 없습니다. 빼려면 왜곡해야합니다. 그러나 특별한 문제는 발생하지 않습니다. SUBI R16,(-1) ; 실제로 SUBI는 뺄셈이지만 -(-는 + SBCI R17,(-1)을 제공합니다. 그리고 여기에서는 전송이 고려됩니다. 하지만 이에 대해서는 나중에 자세히 설명합니다. SBCI R18,(-1) ; 어셈블러의 수학은 다른 이야기입니다. ST -Y,R18 ; 모든 것을 그대로 유지합니다. ST -Y,R17 ; 그러나 역순으로 ST -Y,R16

사후 증가 및 사전 감소가 포함된 연산은 여기에서 이미 사용되었습니다. 첫 번째는 먼저 읽어서 주소에 1을 더하고, 두 번째는 먼저 주소에서 1을 빼고 저장합니다.

이러한 증분 명령을 사용하여 메모리나 테이블의 배열을 반복하는 것이 편리합니다.
또한 세 가지 유형의 인덱스(X,Y,Z)에 대한 간접 상대 쓰기/읽기 LDD/STD 및 기타 옵션도 있습니다. 일반적으로 데이터 시트와 명령 시스템을 연기하십시오.

스택
아, 스택은 대단한 것입니다. 내가 좋아하는 점은 스택 중단이 작동 중인 프로그램을 완전히 엉망으로 만든다는 것입니다. 스택 작업에는 더 많은 주의가 필요하기 때문에, 스택이 어디선가 깨지고 바로 추적할 수 없으면 나중에 잡아내기 때문입니다... 일반적으로 기즈모가 아닌 아름다움입니다.

나는 왜 당신을 사랑합니까? 글쎄요, C가 빠르고 효과적인 멍청한 기술이라면 조립은 세공 예술입니다. Jim과 같은 미치광이는 자신의 즐거움을 위해 기성품 조립식 모델과 접착제를 구입할 수 있는 것처럼 보이지만 종이와 종이로만 걸작을 리벳합니다. 여기에서도 마찬가지입니다. 프로세스 자체가 압도적입니다. 디버깅의 번거로움을 포함하여 :))))

그래서 스택에 대해. 그것은 무엇입니까? 그리고 이곳은 메모리 영역입니다. 스택의 원리에 따라 작동합니다. 저것들. 그는 마지막 것을 내려놓고 첫 번째 것을 가져갔습니다.

스택에는 스택의 맨 위를 가리키는 포인터가 있습니다. 특수 레지스터 SP는 스택 포인터를 담당하거나 오히려 레지스터 쌍 SPL 및 SPH입니다. 그러나 Tini2313과 같이 RAM 용량이 적은 마이크로 컨트롤러에는 SPL만 있습니다.

컨트롤러가 시작되면 일반적으로 가장 먼저 하는 일은 스택을 초기화하고 SP에 스택이 성장할 맨 아래 주소를 쓰는 것입니다. 일반적으로 이것은 RAM의 끝이며 시작 부분으로 커집니다.

이 작업은 프로그램 시작 부분에서 다음과 같이 수행됩니다.

1 2 3 4 5 LDI R16, 낮음(RAMEND) 출력 SPL, R16 LDI R16, 높음(RAMEND) 출력 SPH, R16

LDI R16, 낮음(RAMEND) 출력 SPL, R16 LDI R16, 높음(RAMEND) 출력 SPH, R16

여기서 RAMEND는 현재 MK에서 RAM의 끝을 나타내는 매크로 정의입니다.

이제 스택을 사용할 준비가 되었습니다. 데이터는 PUSH Rn 명령을 사용하여 스택에 푸시되고 POP Rn을 통해 검색됩니다.
Rn은 RON 중 하나입니다.

CALL, RCALL, ICALL, RET, RETI 명령과 인터럽트 호출도 스택에서 작동하지만 이에 대한 자세한 내용은 나중에 설명합니다.

스택을 가지고 놀면서 그것이 어떻게 작동하는지 느끼고, 그것이 어떻게 그리고 어디로 움직이는지 이해해 봅시다.

스튜디오에 다음 코드를 입력하세요.

CSEG; LDI 코드 세그먼트 R16,Low(RAMEND) ; 스택 초기화 OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16 LDI R17,0 ; 로딩 값 LDI R18.1 LDI R19.2 LDI R20.3 LDI R21.4 LDI R22.5 LDI R23.6 LDI R24.7 LDI R25.8 LDI R26.9 PUSH R17 ; 스택에 값을 넣습니다. PUSH R18 PUSH R19 PUSH R20 PUSH R21 PUSH R22 PUSH R23 PUSH R24 PUSH R25 PUSH R26 POP R0 ; 스택의 팝 값 POP R1 POP R2 POP R3 POP R4 POP R5 POP R6 POP R7 POP R8 POP R9

이제 스튜디오를 단계별로 실행하면서 SP가 어떻게 변하는지 지켜보세요. 스택 포인터는 스튜디오의 프로그램 카운터와 같은 위치에서 볼 수 있습니다.

먼저 스택을 초기화하고 레지스터에 데이터를 로드합니다. 결과는 다음 그림과 같습니다.

다음으로 POP 명령을 사용하여 스택에서 데이터를 검색합니다. 스택의 데이터를 어디에 저장하고 어디에 로드하는지는 중요하지 않습니다. 가장 중요한 것은 설치 순서입니다! 우리는 그것을 더 높은 음역에서 입력하고, 더 낮은 음역에서 그것을 얻을 것입니다. 그러면 스택 포인터가 증가합니다.

푸시 R16 푸시 R17 팝 R16 팝 R17

예를 들어, 나는 이미 더 낮은 RON의 제한에 대해 이야기했습니다. 이는 자신에게 직접 숫자를 쓰는 것을 허용하지 않습니다. 시니어 그룹의 등록부를 통해서만 가능합니다. 하지만 이건 불편해요!

문제는 매크로를 사용하여 해결됩니다. 나는 그것을 LDIL - LDI 로우라고 불렀습니다.

매크로 LDIL 푸시 R17; 상위 레지스터 중 하나의 값을 스택에 저장해 보겠습니다. LDI R17,@1 ; 즉각적인 값인 MOV @0,R17을 여기에 로드해 보겠습니다. 하위 그룹의 레지스터에 값을 전달해 보겠습니다. POP R17; 스택에서 가장 높은 레지스터의 값을 복원해 보겠습니다. .ENDM

이제 직접 만든 명령을 쉽게 사용할 수 있습니다.

1 LDIL R0.18

시간이 지남에 따라 매크로가 포함된 파일은 이러한 직접 만든 명령을 획득하고 작업이 쉽고 즐거워집니다.

스택 오류
스택은 데이터 방향으로 증가하며 이제 메모리에 State 변수가 있고 주소(예: 0x0450)에 있다고 가정합니다. 위험할 정도로 스택 상단에 가깝습니다. 예를 들어 변수는 프로그램의 추가 논리가 의존하는 유한 상태 기계의 상태를 저장합니다. 3개가 있으면 한 가지 일을 하고, 4개가 있으면 다른 일을 하고, 5개가 있으면 다른 일을 하는 식으로 최대 255개의 상태를 수행합니다. 그리고 작업 논리에 따르면 3 이후에는 4re가 있어야 하지만 10은 없어야 합니다.

그리고 3이 나왔습니다. 그리고 어느 끔찍한 순간에 조건이 너무 일치하여 스택이 커지고 그 상단이 이 변수에 도달하여 거기에 20이라는 값을 입력한 다음 그레이하운드가 뒤로 떨어졌습니다. 쓰레기를 남겨두는 것은 스택 오버플로의 전형적인 예입니다. 그리고 이로 인해 프로그램의 논리가 완전히 무너졌습니다.

또는 반대의 예 - 스택이 변수에 푸시되었지만 그 순간 변수가 업데이트되어 스택 데이터를 덮어썼습니다. 결과적으로 스택에서 뭔가 잘못된 부분(보통 비뚤어진 반환 주소)이 제거되고 프로그램이 충돌했습니다. 그런데 이 옵션은 훨씬 더 무해합니다. 왜냐하면... 이 경우 잼은 즉시 표시되며 신이 얼마나 오래 걸리는지 알고 나면 갑자기 나타나지 않습니다.

또한 이 오류가 나타났다가 사라질 수도 있습니다. 프로그램이 작동하는 방식과 스택을 로드하는 깊이에 따라 다릅니다. 그러나 이러한 당황스러운 상황은 스택 작업이 얼마나 활발하게 진행되고 있는지 확인할 수 없는 C로 작성할 때 더 일반적입니다. ASMA에서는 모든 것이 훨씬 더 투명합니다. 그리고 이것은 솔직히 비뚤어진 알고리즘으로 인해 발생할 수 있습니다.

어셈블러에서는 종종 다른 스택 오류가 발생합니다. 우선, 건망증입니다. 뭔가를 넣었다가 빼는 걸 깜빡했어요. 문제가 서브루틴이나 인터럽트에 있는 경우 반환 주소가 왜곡되고(자세한 내용은 나중에 설명) 스택이 찢어지고 프로그램이 즉시 붕괴됩니다. 또는 부주의함 - 데이터를 한 순서로 저장하고 다른 순서로 검색했습니다. 이런, 레지스터의 내용이 교환되었습니다.

이러한 오류를 방지하려면 먼저 스택을 모니터링하고 두 번째로 메모리에서 변수 배치를 올바르게 계획해야 합니다. 가장 중요한 영역과 변수(예: 상태 머신 또는 프로그램 논리 플래그)를 스택 상단에서 멀리, 메모리 시작 부분에 더 가깝게 유지합니다.

어떤 사람들은 스택을 RAM 맨 끝이 아닌 더 가까운 곳에 배치하여 중요한 데이터를 위한 포켓을 남겨둘 수 있다고 생각할 것입니다. 별로 좋은 생각이 아닙니다. 사실 스택은 PUSH 명령을 사용하여 아래쪽으로 밀거나 POP 명령을 사용하여 위쪽으로 푸시할 수 있습니다. 두 번째는 훨씬 덜 자주 발생하지만... 이것은 번거로운 알고리즘보다 비뚤어진 손의 죄에 더 가깝지만 이런 일도 발생합니다.
그러나 가장 중요한 것은 스택 자체가 매우 중요한 구조라는 것입니다. 서브루틴과 기능의 전체 메커니즘은 여기에 달려 있습니다. 따라서 스택 오류는 어떤 경우에도 긴급 상황입니다.

스택 변태
내가 가장 좋아하는 주제. =)))) 스택 포인터 자체가 PUSH 및 POP 명령 중에 계산된다는 사실에도 불구하고 아무도 우리가 SP에서 스택 포인터를 선택하고 해당 값을 사용하여 거짓말하는 데이터의 주소를 수동으로 계산하는 것을 막지 않습니다. 스택. 아니면 원하는 대로 스택 데이터를 수정하세요.
무엇을 위해? 글쎄요, 두뇌에 부담을 주고 고정관념에서 벗어나 생각하기 시작하면 많은 응용 프로그램을 찾을 수 있습니다 :)))))

또한 매개변수는 x86 아키텍처의 클래식 C 및 Pascal에서 스택을 통해 전달되며 로컬 변수가 작동합니다. 저것들. 함수를 호출하기 전에 먼저 모든 변수가 스택에 푸시되고, 함수를 호출한 후 향후 지역 변수의 바이트가 스택에 푸시됩니다.

그런 다음 SP를 참조점으로 사용하여 이러한 변수를 원하는 대로 처리할 수 있습니다. 그리고 POP 명령으로 스택이 해제되면 스택이 소멸되어 메모리가 해제됩니다.

AVR에서는 모든 것이 다소 다르지만(분명히 메모리 양이 적어 실제로 스택에 넣을 수는 없지만 RON이 많기 때문에) 이 메커니즘을 사용해 볼 수도 있습니다.

사실, 이것은 이미 신경외과와 유사합니다. 제가 약간의 실수를 해서 환자가 죽었습니다.

스택과 RAM 덕분에 레지스터가 부족하다는 스트레스 없이 2~3개의 레지스터만으로 충분합니다.

플래시 메모리

EEPROM 메모리는 불과 몇 바이트로 작으며 계산에 시간을 낭비하지 않기 위해 외계인에게 보내는 메시지나 사인 테이블과 같은 많은 데이터를 저장해야 하는 경우가 있습니다. 메모리에 무엇이 저장되어야 하는지 미리 알 수 없습니다. 따라서 데이터는 컨트롤러에 탑재된 것과 동일한 킬로바이트의 플래시로 프로그램 메모리에 저장될 수 있습니다.

적어 보겠습니다. 그런데 어떻게 얻을 수 있나요? 이렇게 하려면 먼저 거기에 뭔가를 넣어야 합니다.
따라서 프로그램 끝 부분(예: 데이터)의 .CSEG 세그먼트 내에 레이블을 추가하고 그 뒤에 .db 연산자를 사용하여 데이터를 입력하십시오.

DB 연산자는 각 상수에 대해 바이트를 사용한다는 의미입니다. 2바이트 상수 DW(DD 및 DQ도 포함)를 지정하는 연산자도 있습니다.

1 데이터: .db 12,34,45,23

데이터: .db 12,34,45,23

이제 데이터 레이블은 배열의 첫 번째 바이트 주소를 가리키고 나머지 바이트는 주소에 1을 추가하여 오프셋으로 위치를 지정합니다.

한 가지 미묘한 점은 컴파일러가 표시 주소를 대체하고 이를 프로그램 카운터의 점프 주소로 간주한다는 것입니다. 그리고 기억하신다면 그는 더블 바이트 단어를 언급합니다. 결국 명령의 길이는 2 또는 4 바이트가 될 수 있습니다.

그리고 우리의 데이터는 바이트 단위이며 이에 액세스할 때 컨트롤러도 바이트 단위로 주소를 지정합니다. 단어로 된 주소는 바이트로 된 주소보다 두 배 작으므로 주소에 2를 곱할 때 이 점을 고려해야 합니다.

프로그램 메모리에서 데이터를 로드하려면 프로그램 메모리 로드 그룹의 명령을 사용하십시오.

예: LPM Rn,Z

이는 레지스터 쌍 Z가 가리키는 셀의 번호를 레지스터 Rn에 입력합니다. Z는 두 개의 레지스터 R30(ZL) 및 R31(ZH)임을 상기시켜 드리겠습니다. 주소의 하위 바이트는 R30에 입력되고 상위 바이트는 R31에 입력됩니다.

코드에서는 다음과 같습니다.

LDI ZL,낮음(데이터*2) ; 주소의 하위 바이트를 레지스터 쌍 Z LDI ZH,high(data*2) 에 입력합니다. 주소의 상위 바이트를 레지스터 쌍 Z에 입력합니다. 2를 곱하는 것은 주소가 표시되어 있기 때문입니다. 2바이트 단어로 되어 있지만 바이트 단위로 필요합니다. ; 그러므로 우리는 2를 곱합니다. 주소를 로드한 후 메모리 LPM R16, Z에서 번호를 로드할 수 있습니다. 이 명령 이후의 레지스터 R16에는 숫자 12가 있을 것입니다. 프로그램 메모리에서 가져옵니다. ; 프로그램 끝 어딘가, .CSEG 데이터 세그먼트: .db 12,34,45,23

이제 우리는 마이크로 컨트롤러의 일부 성능과 기능에 대해 이미 잘 알고 있으므로 자연스럽게 논리적인 질문이 떠오릅니다. 마이크로 컨트롤러를 프로그래밍하려면 무엇이 필요한가요? 어떤 프로그램과 장치가 필요하며 어디서 구할 수 있나요?


마이크로컨트롤러가 문제를 해결하고 특정 기능을 수행하려면 프로그래밍해야 합니다. 즉, 프로그램이나 프로그램 코드를 마이크로컨트롤러에 작성해야 합니다.

프로그램 작성의 구조와 순서

우선, 프로그램 또는 프로그램 코드 작성을 시작하기 전에 마이크로 컨트롤러가 수행할 기능을 명확하게 이해해야 합니다. 그러므로 먼저 프로그램의 궁극적인 목표를 결정해야 합니다. 그것이 정의되고 완전히 이해되면 프로그램의 알고리즘이 작성됩니다. 알고리즘은 명령 실행의 순서입니다. 알고리즘을 사용하면 코드 작성 프로세스를 보다 명확하게 구성할 수 있으며, 복잡한 프로그램을 작성할 때 개발 및 디버깅에 소요되는 시간을 줄일 수 있는 경우가 많습니다.

알고리즘을 컴파일한 후 다음 단계는 프로그램 코드를 직접 작성하는 것입니다. 마이크로컨트롤러용 프로그램은 다음 언어로 작성됩니다. 또는 어셈블러 . 오직 어셈블리만이 프로그래밍 언어라기보다 명령어 세트에 가깝고 저수준 언어입니다.


고급 언어인 C로 프로그램을 작성하겠습니다. C 프로그램은 유사한 어셈블리 프로그램에 비해 훨씬 빠르게 작성됩니다. 또한 모든 복잡한 프로그램은 주로 C로 작성됩니다.

여기서는 Assembly와 C로 프로그램을 작성하는 것의 장점과 단점을 비교하지 않습니다. 시간이 지남에 따라 MK 프로그래밍에 대한 경험을 쌓으면 스스로 유용한 결론을 도출하게 될 것입니다.

프로그램 코드 자체는 메모장과 같은 표준 텍스트 편집기로 작성할 수 있습니다. 그러나 실제로는 더 편리한 편집기를 사용하며 이에 대해서는 아래에서 설명합니다.

프로그램 컴파일

MK는 0과 1의 집합인 이진수(또는 16진수) 시스템에서만 명령을 이해하기 때문에 우리가 작성한 C 코드는 아직 마이크로컨트롤러에서 이해할 수 없습니다. 따라서 C 코드를 0과 1로 변환해야 합니다. 이를 위해 특수 프로그램이 사용됩니다. 컴파일러및 프로세스 자체 코드 변환을 컴파일이라고 합니다..

MK 펌웨어를 플래시하려면 다음과 같은 장치가 필요합니다. 프로그램 제작자. 프로그래머 유형에 따라 입력은 COM 또는 USB 포트에 연결되고 출력은 마이크로 컨트롤러의 특정 핀에 연결됩니다.


다양한 프로그래머와 개발 보드가 있지만 우리는 가장 단순한 것에 매우 만족합니다. 프로그램 제작자, 중국에서는 가격이 3달러를 넘지 않습니다.


마이크로 컨트롤러가 플래시된 후 프로그램은 실제 장치 또는 하드웨어에서 디버깅 및 테스트됩니다.

이제 마이크로 컨트롤러 프로그래밍 단계를 요약해 보겠습니다.


간단한 프로그램을 작성할 때 두 번째 요점 없이도 할 수 있습니다. 즉, 종이에 알고리즘을 작성하지 않고도 머리 속에 간직하는 것으로 충분합니다.

MK 펌웨어를 플래시하기 전에 프로그램 디버깅 및 테스트도 수행된다는 점에 유의해야 합니다.

필수 프로그램 세트

MK 프로그래밍에는 유용하고 편리한 프로그램이 많이 있습니다. 그들은 유료이고 무료입니다. 그중에는 세 가지 주요 항목이 있습니다.

1) 아트멜 스튜디오

2) 코드비전AVR

3) WinAVR

이 모든 프로그램은 다음과 관련이 있습니다. IDE통합 개발 이자형 nvironment – ​​통합 개발 환경. 그 안에 코드를 작성하고 컴파일하고 디버그할 수 있습니다.

Code Vision AVR에 주목해야 합니다. 이 IDE를 사용하면 코드 작성이 더 쉽고 빨라집니다. 그러나 프로그램은 유료입니다.

프로그래밍 초기 단계에서는 단순화하지 않고 모든 프로그램을 수동으로 작성하는 것이 좋습니다. 이를 통해 필요한 기술을 빠르게 습득할 수 있으며, 앞으로는 다른 사람이 작성한 코드를 잘 이해하고 필요에 맞게 편집할 수 있습니다. 따라서 Atmel Studio를 사용하는 것이 좋습니다. 첫째, 완전 무료이며 지속적으로 업데이트되며, 둘째, 프로그래밍 방법을 배울 마이크로 컨트롤러를 제조하는 회사에서 개발했습니다.

펌웨어 및 프로그램 디버깅

추가 프로그램을 사용하여 마이크로 컨트롤러를 플래시합니다..

마이크로컨트롤러를 사용할 수 없는 경우 프로그램을 사용하여 해당 작동을 에뮬레이트할 수 있습니다. 마이크로 컨트롤러가 있더라도 프로그램 디버깅 프로세스가 크게 단순화되므로 자주 다시 플래시할 필요가 없습니다. 모든 마이크로 컨트롤러에는 유한한 재작성 횟수가 있지만 이 숫자는 상당히 많기 때문입니다.

MK를 플래싱하고 디버깅할 때는 브레드보드에 놓는 것이 편리하지만 꼭 필요한 것은 아닙니다. 따라서 편의성을 높이기 위해 브레드보드도 유용합니다. 브레드보드의 종류는 다양하지만, 구멍이 최대한 많은 것을 선택하는 것이 좋습니다. 7세그먼트 디스플레이를 연결하기 시작하면 더 큰 브레드보드의 이점을 이해하기 시작할 것입니다.

우리에게 유용할 또 다른 중요한 요소는 MK에 대한 기술 문서입니다. 데이터 시트. 일반적으로 다운로드가 필요합니다. ATmega8 마이크로컨트롤러용 데이터시트.

키젤레프 로만, 2007년 5월 기사 업데이트: 2014년 5월 26일

그렇다면 마이크로컨트롤러(이하 MK)란 무엇인가? 이는 상대적으로 단일 집적 회로에 내장된 소형 컴퓨터입니다. 여기에는 프로세서(산술 논리 장치 또는 ALU), 플래시 메모리, EEPROM 메모리, 많은 레지스터, I/O 포트는 물론 타이머, 카운터, 비교기, USART 등과 같은 추가 벨과 휘파람 기능이 있습니다. 전원 공급 후 , 마이크로 컨트롤러가 부팅되고 플래시 메모리에 저장된 프로그램 실행을 시작합니다. 동시에 I/O 포트를 통해 다양한 외부 장치를 제어할 수 있습니다.

이것은 무엇을 의미 하는가? 이는 MK에서 특정 기능을 수행하는 모든 논리 회로를 구현할 수 있음을 의미합니다. 이는 MK가 마이크로회로이며 내부 내용이 실제로 우리 스스로 생성된다는 것을 의미합니다. 이를 통해 완전히 동일한 MK를 여러 개 구입하면 완전히 다른 회로와 장치를 조립할 수 있습니다. 전자 장치의 작동을 변경하려면 납땜 인두를 사용할 필요가 없으며 MK를 다시 프로그래밍하기만 하면 됩니다. 이 경우 AVR을 사용하는 경우 MK가 회로 내 프로그래밍을 지원하므로 장치에서 이를 제거할 필요조차 없습니다. 따라서 마이크로컨트롤러는 프로그래밍과 전자 장치 간의 격차를 해소합니다.

AVR은 8비트 마이크로컨트롤러입니다. 즉 ALU는 한 클록 사이클에서 8비트 숫자만으로 간단한 작업을 수행할 수 있습니다. 이제 우리가 사용할 MK에 대해 이야기할 차례입니다. 저는 ATMega16 MK를 사용하고 있습니다. 매우 일반적이며 거의 모든 라디오 부품 상점에서 약 100 루블에 구입할 수 있습니다. 찾을 수 없으면 MEGA 시리즈의 다른 MK를 구입할 수 있지만 이 경우에는 서로 다른 MK의 동일한 "다리"가 서로 다른 기능을 수행할 수 있으므로 이에 대한 문서를 찾아야 합니다. 연결하면 모든 결론이 정확하다면 작동하는 장치를 얻을 수도 있고 냄새 나는 연기 구름을 얻을 수도 있습니다. ATMega16을 구매할 때 대형 40핀 DIP 패키지로 제공되는지 확인하고 삽입할 수 있는 소켓도 구매하세요. 이를 사용하려면 LED, 버튼, 커넥터 등 추가 장치도 필요합니다.

ATMega16은 매우 다양한 기능을 가지고 있습니다. 다음은 그 특징 중 일부입니다:

  • 최대 클록 주파수 - 16MHz(ATMega16L의 경우 8MHz)
  • 대부분의 명령은 하나의 클록 주기에 실행됩니다.
  • 32개의 8비트 작업 레지스터
  • 4개의 완전한 8비트 I/O 포트
  • 2개의 8비트 타이머/카운터 및 1개의 16비트
  • 10비트 아날로그-디지털 변환기(ADC)
  • 1MHz의 내부 클록 생성기
  • 아날로그 비교기
  • 인터페이스 SPI, I2C, TWI, RS-232, JTAG
  • 회로 내 프로그래밍 및 자체 프로그래밍
  • 펄스 폭 변조(PWM) 모듈

이 장치의 전체 특성과 사용 지침은 이 MK의 참고 서적(데이터시트)에서 확인할 수 있습니다. 사실, 영어로 되어 있습니다. 영어를 알고 계시다면 이 데이터시트를 다운로드하십시오. 여기에는 유용한 정보가 많이 포함되어 있습니다.

마침내 사업에 착수합시다. 납땜 인두 없이(또는 거의 납땜 없이) 마이크로 컨트롤러를 사용하여 모든 전기 회로를 조립할 수 있는 마이크로 컨트롤러용 특수 개발 및 디버깅 보드를 만드는 것이 좋습니다. 이러한 보드를 사용하면 MK 작업이 훨씬 쉬워지고 프로그래밍 학습 속도가 빨라집니다. 다음과 같습니다.

이를 위해 무엇이 필요합니까?

먼저 보드 자체가 필요합니다. 나는 라디오 부품 상점에서 115 루블에 기성품을 구입했습니다. 그런 다음 필요한 모든 부품을 납땜했습니다. 그 결과 케이블을 연결하고 미세 회로와 표시기를 설치하여 몇 분 만에 모든 전기 회로를 조립할 수 있어 매우 편리합니다.

회로 요소를 연결하려면 끝에 커넥터가 있는 케이블을 사용하는 것이 매우 편리합니다. 이 커넥터는 MK의 각 포트 옆에 튀어나온 "다리"에 배치됩니다. 마이크로컨트롤러는 보드에 납땜하지 말고 소켓에 설치해야 합니다. 그렇지 않으면 실수로 태울 경우 제거하기가 매우 어렵습니다. 아래는 ATMEGA16 MK의 핀 배치입니다.

이제 어떤 다리에 관심이 있는지 설명하겠습니다.

  • VCC - 안정화된 소스에서 여기(4.5 - 5.5V)의 전원이 공급됩니다.
  • GND – 접지
  • RESET - 재설정(낮은 전압 레벨에서)
  • XTAL1, XTAL2 - 석영 공진기가 여기에 연결됩니다.
  • PA, PB, PC, PD – 입력/출력 포트(각각 A, B, C 및 D).

7-11V DC를 생성하는 모든 것을 전원으로 사용할 수 있습니다. MK의 안정적인 동작을 위해서는 안정적인 전원 공급이 필요합니다. 안정기로 사용할 수 있는 7805 시리즈 마이크로 회로는 선형 통합 안정기로서 입력에 7-11V의 직접 불안정 전류가 공급되고 출력은 5V의 안정화 전류입니다. 7805 전후에는 필터 커패시터(저주파 간섭 필터링용 전해액, 고주파용 세라믹)를 설치해야 합니다. 안정 장치를 찾을 수 없으면 4.5V 배터리를 전원으로 사용할 수 있으며 MK는 이 배터리에서 직접 전원을 공급받아야 합니다.

다음은 MK 연결 다이어그램입니다.

이제 여기에 무엇이 있는지 알아 보겠습니다.

BQ1은 MK의 작동 주파수를 설정하는 석영 공진기입니다. 최대 16MHz까지 설정할 수 있지만 향후 COM 포트를 사용하여 작업할 계획이므로 14.7456MHz, 11.0592MHz, 7.3725MHz, 3.6864MHz 또는 1,8432MHz(나중에) 주파수에 대한 공진기를 사용하는 것이 좋습니다. 이유가 분명해질 것입니다). 저는 11.0592MHz를 사용했습니다. 주파수가 높을수록 장치의 속도가 빨라지는 것은 분명합니다.

R1은 RESET 입력에서 5V의 전압을 유지하는 풀업 저항입니다. 이 입력의 낮은 전압 레벨은 재설정을 나타냅니다. 재설정 후 MK가 부팅되고(10~15ms) 프로그램 실행이 다시 시작됩니다. 이것은 고임피던스 입력이기 때문에 "공중에 매달려 있는" 상태로 둘 수 없습니다. 이 입력에 작은 픽업이 있어도 MK가 예기치 않게 재설정될 수 있습니다. 이것이 바로 R1의 목적입니다. 신뢰성을 위해 커패시터 C6(20μF 이하)을 설치하는 것이 좋습니다.

SB1 – 재설정 버튼.

석영 공진기와 필터 커패시터 C3는 MK에 최대한 가깝게(5-7cm 이내) 위치해야 합니다. 그렇지 않으면 와이어에 간섭이 발생하여 MK가 오작동할 수 있기 때문입니다.

다이어그램의 파란색 직사각형은 프로그래머 자체의 개요를 나타냅니다. 한쪽 끝은 LPT 포트에 연결되고 다른 쪽 끝은 MK 옆의 특정 커넥터에 연결되는 와이어 형태로 만드는 것이 편리합니다. 와이어가 너무 길어서는 안됩니다. 이 케이블에 문제가 발생하는 경우(일반적으로 문제는 발생하지 않지만 어떤 일이든 발생할 수 있음) Altera ByteBlaster 어댑터를 납땜해야 합니다. 이를 수행하는 방법은 AVReal 프로그래머의 설명에 기록되어 있습니다.

이제 하드웨어를 다루었으니 소프트웨어로 넘어갈 차례입니다.

AVR 프로그래밍을 위한 여러 개발 환경이 있습니다. 먼저, Atmel의 공식 프로그래밍 시스템인 AVR Studio입니다. 이를 통해 어셈블러로 작성하고 어셈블리, C 및 C++로 작성된 프로그램을 디버그할 수 있습니다. IAR은 C, C++ 및 어셈블리 언어로 된 상용 프로그래밍 시스템입니다. WinAVR은 오픈 소스 컴파일러입니다. AtmanAVR은 Visual C++ 6과 거의 동일한 인터페이스를 갖춘 AVR용 프로그래밍 시스템입니다. 또한 AtmanAVR을 사용하면 프로그램을 디버그할 수 있으며 코드 작성을 더 쉽게 해주는 많은 도우미 기능이 포함되어 있습니다. 이 프로그래밍 시스템은 상업용이지만 라이센스에 따라 한 달 동안 무료로 사용할 수 있습니다.

가장 투명한 개발 환경인 IAR을 사용하여 작업을 시작하는 것이 좋습니다. IAR에서는 프로젝트가 전적으로 손으로 생성되므로 여러 프로젝트를 완료하면 각 코드 줄의 의미와 코드를 변경하면 어떤 일이 발생하는지 이미 명확하게 알 수 있습니다. AtmanAVR로 작업할 때에는 미리 만들어진 템플릿을 사용해야 하는데, 이는 매우 번거롭고 경험이 없는 사람이 이해하기 어렵거나, 프로젝트를 처음부터 조립할 때 헤더 파일에 많은 문제가 발생하게 됩니다. IAR을 다룬 후에는 다른 컴파일러를 살펴보겠습니다.

먼저 IAR을 얻으십시오. 이는 매우 일반적이며 이를 찾는 것은 문제가 되지 않습니다. IAR 3.20을 어딘가에서 다운로드한 후 컴파일러/작업 환경을 설치하고 실행합니다. 그 후에 작업을 시작할 수 있습니다.

IAR을 시작한 후 다음을 선택하세요. 파일/새로 만들기/작업공간, 프로젝트 경로를 선택하고 해당 폴더를 생성한 후 "Prog1"과 같은 이름을 지정합니다. 이제 프로젝트를 만들어 보겠습니다. 프로젝트/새 프로젝트 만들기…"Prog1"이라고도 부르겠습니다. 프로젝트 트리에서 프로젝트 제목을 마우스 오른쪽 버튼으로 클릭하고 "옵션"을 선택합니다.

여기서는 특정 MK에 대한 컴파일러를 구성합니다. 먼저 대상 탭에서 ATMega16 프로세서 유형을 선택하고 라이브러리 구성 탭에서 I/O 포함 파일에서 비트 정의 활성화 확인란을 선택해야 합니다. 그러면 프로그램 코드에서 다양한 MK 레지스터의 비트 이름을 사용할 수 있습니다. ), 거기에서 C 라이브러리 유형 /EU++를 선택합니다. ICCAVR 카테고리의 언어 탭에서 멀티바이트 지원 활성화 확인란을 선택하고 최적화 탭에서 최적화를 꺼야 합니다(그렇지 않으면 첫 번째 프로그램이 망가집니다).

다음으로 XLINK 카테고리를 선택하세요. 여기서는 컴파일된 파일의 형식을 결정해야 합니다. 제목에 설명된 대로 이제 디버그 모드에 대한 옵션을 설정하고 있으므로 디버그 파일을 출력으로 가져와야 합니다. 나중에 AVR Studio에서 열어보겠습니다. 이렇게 하려면 확장자.cof를 선택해야 하며 파일 형식은 ubrof 7입니다.

이제 확인을 클릭한 다음 디버그를 릴리스로 변경합니다.

옵션으로 다시 이동하여 XLINK를 제외한 모든 매개변수가 동일하게 설정됩니다. XLINK에서 확장자를 .hex로 변경하고 파일 형식을 intel-standart로 변경합니다.

그게 다야. 이제 첫 번째 프로그램 작성을 시작할 수 있습니다. 새 소스/텍스트를 만들고 여기에 다음 코드를 입력하세요.

#포함하다"iom16.h" short unsigned int i; 무효의기본( 무효의) (DDRB = 255; PORTB = 0; ~하는 동안(1) { 만약에(포트B == 255) 포트B = 0; 또 다른포트B++; ~을 위한(나는=0;나는

"iom16.h" 파일은 폴더에 있습니다. (C:\Program Files)\IAR Systems\Embedded Workbench 3.2\avr\inc. 예를 들어 ATMega64와 같은 다른 MK를 사용하는 경우 "iom64.h" 파일을 선택합니다. 이러한 헤더 파일은 MK에 대한 정보(레지스터 이름, 레지스터 비트, 인터럽트 이름)를 저장합니다. 포트 A, B, C 또는 D의 각 개별 핀은 입력 또는 출력으로 작동할 수 있습니다. 이는 DDR(데이터 방향 레지스터)에 의해 결정됩니다. 1은 다리를 출력으로 만들고, 0은 입력으로 만듭니다. 따라서 예를 들어 DDRA = 13으로 설정하면 "다리" PB0, PB2, PB3 출력을 만들고 나머지는 입력으로 만듭니다. 이진수 13은 00001101입니다.

PORTB는 포트 핀의 상태를 결정하는 레지스터이다. 거기에 0을 쓴 후 모든 출력의 전압을 0V로 설정합니다. 그런 다음 무한 루프가 발생합니다. MK를 프로그래밍할 때 항상 MK가 재설정되거나 중단이 발생할 때까지 일부 작업을 수행하는 무한 루프를 만듭니다. 이 주기에서 그들은 MK가 마지막으로 실행하는 "백그라운드 코드"를 작성합니다. 예를 들어 디스플레이에 정보를 표시하는 것일 수 있습니다. 우리의 경우 PORTB 레지스터의 내용이 가득 찰 때까지 증가합니다. 그 후 모든 것이 다시 시작됩니다. 마지막으로 루프에 대한 만 사이클입니다. 포트 B의 상태를 전환할 때 가시적인 지연을 형성하는 것이 필요합니다.



이제 이 파일을 프로젝트 폴더에 Prog1.c로 저장하고 iom16.h 파일을 프로젝트 폴더에 복사한 다음 Project/Add Files를 선택하고 "iom16.h" 및 "Prog1.c"를 추가합니다. Release를 선택하고 F7을 누르면 프로그램이 컴파일되고 다음 메시지가 나타납니다.


총 오류 수: 0
총 경고 수: 0

내 프로그래머의 사진은 다음과 같습니다.

AVReal 프로그래머를 다운로드하세요. Prog1.hex 파일이 있어야 하는 Release/exe 폴더에 해당 파일(AVReal32.exe)을 복사합니다. MK에 전원을 공급하고 프로그래밍 케이블을 연결합니다. Far Manager를 열고(MK를 플래시하는 것이 가장 편리함) 이 폴더로 이동한 후 Ctrl+O를 누릅니다. 우리는 완전히 새로운 MK를 가지고 있기 때문에

avreal32.exe +MEGA16 -o11.0592MHZ -p1 -fblev=0,jtagen=1,cksel=F,sut=1 –w

11059200Hz를 사용하지 않는 경우 올바른 주파수를 입력하는 것을 잊지 마세요! 동시에, 소위 퓨즈 - 작동을 제어하는 ​​레지스터입니다(내부 생성기, Jtag 등 사용). 그러면 첫 번째 프로그램을 받을 준비가 된 것입니다. 프로그래머에게는 사용된 LPT 포트, 주파수, 파일 이름 등이 매개변수로 제공됩니다(모두 AVReal 설명에 나열되어 있음). 우리는 전화를 겁니다:

Avreal32.exe +Mega16 -o11.0592MHz -p1 -e -w -az -% Prog1.hex

연결이 정확하면 프로그래머는 성공적인 프로그래밍을 보고합니다. 이것이 처음(프로그램을 처음 호출할 때)에 작동한다는 보장은 없습니다. 나 자신도 때때로 두 번째로 프로그래밍을 받습니다. 아마도 LPT 포트에 결함이 있거나 케이블에 간섭이 있을 수 있습니다. 문제가 발생하면 케이블을 주의 깊게 확인하십시오. 내 경험에 따르면 오작동의 60%는 올바른 위치에 접촉이 부족한 것과 관련이 있고, 20%는 불필요한 것이 있고, 또 다른 15%는 잘못된 것을 잘못된 것에 납땜하는 것과 관련이 있다는 것을 알고 있습니다. 다른 모든 방법이 실패하면 프로그래머의 설명을 읽고 Byte Blaster를 구축해 보세요.

모든 것이 당신에게 효과가 있다고 가정해 봅시다. 이제 8개의 LED를 MK의 포트 B에 연결하고(MK가 꺼진 상태에서 이 작업을 수행하고 LED와 직렬로 300-400Ω 저항기를 포함하는 것이 좋습니다) 전원을 공급하면 작은 기적이 일어날 것입니다. 웨이브”가 그들을 통과할 것입니다!

© Kiselev 로마
2007년 5월

2015년 12월

1. 제안한 방법의 장점

마이크로 컨트롤러(MCU) 기반 장치 회로는 일반적으로 결합하기 어려운 두 가지 특성, 즉 최대 단순성과 높은 기능성의 조합으로 구별됩니다. 또한 향후 회로를 변경하지 않고도 프로그램 교체(플래싱)만으로 기능을 변경 및 확장할 수 있습니다. 이러한 기능은 최신 마이크로 컨트롤러 제작자가 전자 장치 개발자에게 필요한 모든 것을 최소한 가능한 한 하나의 칩에 배치하려고 시도했다는 사실로 설명됩니다. 그 결과, 회로와 설치에서 소프트웨어로 중점이 옮겨졌습니다. MK를 사용하면 이제 회로에 부품을 "로드"할 필요가 줄어들고 구성 요소 간의 연결도 줄어듭니다. 물론 이는 숙련된 전자 엔지니어와 초보 전자 엔지니어 모두가 반복할 수 있는 회로를 더욱 매력적으로 만듭니다. 하지만 평소처럼 모든 비용을 지불해야 합니다. 이 역시 어려움이 없지는 않았습니다. 새 MK를 구입하면 서비스 가능한 부품으로 올바르게 조립된 회로에 설치하고 전원을 공급하면 아무 것도 작동하지 않습니다. 장치가 작동하지 않습니다. 마이크로 컨트롤러에는 프로그램이 필요합니다.

이것으로도 모든 것이 간단한 것 같습니다. 인터넷에서 무료 펌웨어가 포함된 많은 구성표를 찾을 수 있습니다. 그러나 여기에는 한 가지 문제가 있습니다. 펌웨어는 어떻게든 마이크로컨트롤러에 "업로드"되어야 합니다. 이전에 이런 일을 해본 적이 없는 사람에게 이러한 작업은 종종 문제가 되고 주요 혐오 요인이 되며 종종 MK 사용의 즐거움을 포기하고 "느슨하고" 엄격한 논리에 기반한 계획을 찾도록 강요합니다. 그러나 언뜻보기에 모든 것이 복잡하지는 않습니다.

인터넷 출판물을 분석해 보면 이 문제는 기성 프로그래머를 구입하거나 집에서 만드는 두 가지 방법 중 하나로 해결되는 경우가 가장 많다는 것을 알 수 있습니다. 동시에, 집에서 만든 프로그래머가 공개한 회로는 매우 종종 비합리적으로 복잡합니다. 즉, 실제로 필요한 것보다 훨씬 더 복잡합니다. 물론 매일 MK를 플래싱할 계획이라면 "멋진" 프로그래머를 두는 것이 더 좋습니다. 그러나 그러한 절차의 필요성이 때때로 발생하는 경우가 드물다면 프로그래머 없이도 할 수 있습니다. 물론, 우리는 생각의 힘으로 이것을 하는 법을 배우는 것에 대해 말하는 것이 아닙니다. 이는 프로그래머가 프로그래밍 모드에서 정보를 쓰고 읽을 때 마이크로컨트롤러와 상호 작용하는 방식을 이해함으로써 더 넓은 목적을 위해 사용 가능한 도구를 사용할 수 있음을 의미합니다. 이러한 도구는 프로그래머의 소프트웨어와 하드웨어 부분을 모두 대체해야 합니다. 하드웨어는 MK 마이크로회로에 대한 물리적 연결, 입력에 논리 레벨을 적용하고 출력에서 ​​데이터를 읽는 기능을 제공해야 합니다. 소프트웨어 부분은 필요한 모든 프로세스를 제어하는 ​​알고리즘의 작동을 보장해야 합니다. 또한 MK에 기록되는 정보의 품질은 프로그래머가 얼마나 "멋진"지에 달려 있지 않습니다. "더 잘 녹음된 것"이나 "더 나빴던 것" 같은 것은 없습니다. "등록됨"과 "등록되지 않음"의 두 가지 옵션만 있습니다. 이는 크리스탈 내부의 기록 프로세스가 MK 자체에 의해 직접 제어된다는 사실로 설명됩니다. 고품질의 전원(간섭이나 리플 없음)을 제공하고 인터페이스를 적절하게 구성하면 됩니다. 테스트 판독 결과에 오류가 없으면 모든 것이 정상입니다. 컨트롤러를 의도한 목적에 맞게 사용할 수 있습니다.

프로그래머 없이 MK에 프로그램을 작성하려면 USB-RS232TTL 포트 변환기도 필요합니다. USB-RS232TTL 변환기를 사용하면 USB 포트를 사용하여 입력 및 출력이 TTL 논리 레벨, 즉 0~5V 범위의 전압을 사용한다는 점에서만 "실제" 포트와 다른 COM 포트를 생성할 수 있습니다( " "기사에서 자세한 내용을 읽을 수 있습니다.) 어쨌든 그러한 변환기는 "가정"에 있으면 유용하므로 아직 가지고 있지 않다면 구입할 가치가 있습니다. 논리 레벨의 경우 TTL은 일반 COM 포트보다 유리합니다. 이러한 포트의 입력 및 출력은 ATtiny 및 ATmega를 포함하여 5V로 구동되는 모든 마이크로컨트롤러에 직접 연결할 수 있기 때문입니다. 그러나 일반 COM 포트를 사용하려고 시도하지 마십시오. -12 ~ +12V(또는 -15...+15V) 범위의 전압을 사용합니다. 이 경우 마이크로컨트롤러에 직접 연결할 수 없습니다!!!

프로그래머의 기능을 구현하는 Perpetuum M 프로그램용 스크립트를 작성하려는 아이디어는 MK 펌웨어에 대한 특정 솔루션을 제공하는 인터넷의 여러 출판물을 읽은 후에 나타났습니다. 각각의 경우에 심각한 결함이나 과도한 어려움이 발견되었습니다. 종종 나는 마이크로 컨트롤러가 포함된 프로그래머 회로를 접했고 동시에 다음과 같은 매우 진지한 조언을 받았습니다. "... 그리고 이 프로그래머를 위해 마이크로 컨트롤러를 프로그래밍하려면... 맞습니다. 다른 프로그래머가 필요합니다!" 다음으로 친구에게 가서 유료 서비스를 찾는 등의 제안을 받았습니다. 이러한 목적으로 네트워크에 배포된 소프트웨어의 품질도 인상적이지 않았습니다. 기능과 사용자 인터페이스의 "흐림" 모두에서 많은 문제가 발견되었습니다. 프로그램 사용법을 이해하는 데는 많은 시간이 걸리는 경우가 많습니다. 가장 간단한 작업을 수행하는 경우에도 프로그램을 연구해야 합니다. 다른 프로그램은 오랫동안 부지런히 작업을 수행할 수 있지만 사용자는 전체 펌웨어가 완전히 완료되고 후속 테스트 판독이 완료된 후에야 MK에 아무 것도 기록되지 않는다는 것을 알게 됩니다. 다음 문제도 발생합니다. 사용자가 지원되는 크리스탈 목록에서 MK를 선택하려고 시도하지만 목록에 없습니다. 이 경우 프로그램을 사용할 수 없습니다. 일반적으로 누락된 MK 목록에 포함되지 않습니다. 또한 대부분의 경우 프로그래머가 MK 유형을 스스로 결정할 수 있다는 점을 고려하면 목록에서 컨트롤러를 수동으로 선택하는 것이 이상해 보입니다. 이 모든 것은 기존 제품에 진흙을 던지기 위한 것이 아니라 이 기사에 설명된 Perpetuum M 프로그램의 스크립트가 등장한 이유를 설명하기 위한 것입니다. 문제는 실제로 존재하며 마이크로 컨트롤러의 세계에 첫발을 내딛기 위해 항상 이 "벽"을 극복하지 못하는 초보자와 관련이 있습니다. 제안된 스크립트는 다른 프로그램에서 발견되는 단점을 고려합니다. 알고리즘 작동의 최대 "투명성"이 구현되었습니다. 이는 학습이 필요하지 않고 혼동되거나 "잘못된 것을 클릭"할 가능성이 없는 매우 간단한 사용자 인터페이스입니다. 필요한 MK가 지원되는 MK에 포함되지 않은 경우 MK 개발자 웹사이트에서 다운로드한 문서에서 필요한 데이터를 가져와 설명을 직접 추가할 수 있습니다. 그리고 가장 중요한 것은 스크립트가 연구 및 수정이 가능하다는 것입니다. 누구나 텍스트 편집기에서 열어서 자신의 재량에 따라 연구하고 편집할 수 있으며, 기존 기능을 자신의 취향에 맞게 변경하고 누락된 기능을 추가할 수 있습니다.

스크립트의 첫 번째 버전은 2015년 6월에 작성되었습니다. 이 버전은 플래시 메모리 쓰기/읽기, 구성 비트 설정, 컨트롤러 유형 자동 감지 기능을 갖춘 Atmel의 ATtiny 및 ATmega 시리즈 마이크로 컨트롤러만 지원하며 EEPROM 쓰기 및 읽기는 구현되지 않았습니다. 스크립트 기능을 보완할 계획이 있었습니다. : EEPROM 쓰기 및 읽기 추가, PIC 컨트롤러 지원 구현 등 이 때문에 스크립트는 아직 공개되지 않았지만 시간 부족으로 인해 계획 구현이 지연되어 최고가되지 못했습니다. 선의 적, 기존 버전을 게시하기로 결정했습니다. 이미 구현된 기능이 충분하지 않다면 당황하지 마십시오. 이 경우 원하는 기능을 직접 추가해 볼 수 있습니다. 숨기지 않겠습니다: 처음에 이 스크립트를 작성한다는 아이디어는 교육적인 의미도 있습니다. 알고리즘을 이해하고 여기에 자신만의 것을 추가하면 프로그래밍 모드에서 MK의 작동을 더 잘 이해할 수 있으므로 미래에는 고장난 자동차 앞에서 소녀의 입장에 서서 그 내부를 주의 깊게 살펴보고 그것이 왜 "작동하지 않는"지 이해하지 못하는 자신을 발견하지 못할 것입니다.

2. 프로그래밍 모드의 MK 인터페이스

컨트롤러를 프로그래밍 모드로 전환하고 이 모드에서 작업하는 방법에는 여러 가지가 있습니다. ATtiny 및 ATmega 시리즈 컨트롤러를 구현하기 가장 쉬운 방법은 아마도 SPI일 것입니다. 우리는 그것을 사용할 것입니다.

그러나 SPI를 생성하는 데 필요한 신호를 고려하기 전에 몇 가지 예약을 해야 합니다. 마이크로 컨트롤러에는 구성 비트가 있습니다. 이는 프로젝트의 필요에 따라 마이크로 회로의 일부 속성을 변경할 수 있는 전환 스위치와 같은 것입니다. 물리적으로 이는 프로그램이 기록되는 것과 같은 비휘발성 메모리 셀입니다. 차이점은 그 수가 매우 적고(ATmega의 경우 최대 3바이트) 메모리 주소 공간의 일부가 아니라는 점입니다. 구성 데이터 쓰기 및 읽기는 MK 프로그래밍 모드에서 별도의 명령으로 수행됩니다. 이제 일부 구성 비트가 SPI 사용 기능에 영향을 미친다는 점에 유의하는 것이 중요합니다. 일부 값에서는 SPI를 사용할 수 없는 것으로 나타날 수 있습니다. 이러한 마이크로 컨트롤러를 발견하면 이 기사에서 제안한 방법은 도움이 되지 않습니다. 이 경우, 다른 프로그래밍 모드를 지원하는 프로그래머의 구성 비트 설정을 변경하거나 다른 마이크로컨트롤러를 사용해야 합니다. 그러나이 문제는 중고 MK 또는 누군가가 이미 "사용"에 실패한 MK에만 적용됩니다. 사실 새로운 MCU에는 SPI 사용을 방해하지 않는 구성 비트 설정이 함께 제공됩니다. 이는 Perpetuum M 프로그램의 프로그래머 스크립트 테스트 결과로 확인되었으며, 그 동안 4개의 서로 다른 MK(ATmega8, ATmega128, ATtiny13, ATtiny44)가 성공적으로 플래시되었습니다. 그들은 모두 새로운 것이었습니다. 구성 비트의 초기 설정은 문서와 일치했으며 SPI 사용을 방해하지 않았습니다.

위 내용을 고려하여 다음 부분에 주의를 기울여야 합니다. SPIEN 비트는 SPI 사용을 명시적으로 허용하거나 거부하므로 우리의 경우 해당 값은 활성화되어야 합니다. RSTDISBL 비트는 마이크로 회로의 출력 중 하나(미리 결정됨)를 "리셋" 신호의 입력으로 전환하거나 전환하지 않을 수 있습니다(이 비트에 기록된 값에 따라 다름). 우리의 경우 "재설정" 입력이 필요합니다(입력이 없으면 SPI를 통해 MK를 프로그래밍 모드로 전환할 수 없습니다). 클럭 신호의 소스를 지정하는 CKSEL 그룹의 비트도 있습니다. SPI 사용을 막지는 못하지만, 클록 펄스가 전혀 없거나 해당 주파수가 주어진 SPI 속도에 허용되는 것보다 낮으면 좋은 일도 일어나지 않기 때문에 명심해야 합니다. 일반적으로 내부 RC 발진기가 있는 새 MCU에는 이를 사용하도록 구성된 CKSEL 그룹 비트가 있습니다. 이는 우리에게 매우 적합합니다. 우리 측의 추가 노력 없이도 클럭킹이 제공됩니다. 석영 공진기를 납땜하거나 외부 발전기를 연결할 필요가 없습니다. 지정된 비트에 다른 설정이 포함된 경우 해당 설정에 따라 클럭킹을 처리해야 합니다. 이 경우 수정 공진기나 외부 클록 생성기를 MCU에 연결해야 할 수도 있습니다. 그러나 이 기사에서는 이것이 어떻게 수행되는지 고려하지 않을 것입니다. 이 기사에 포함된 프로그래밍을 위해 MK를 연결하는 예는 가장 간단한 경우를 위해 설계되었습니다.

쌀. 1. 프로그래밍 모드에서 SPI를 통한 데이터 교환

이제 ATmega128A MK 문서에서 가져온 그림 1을 살펴보겠습니다. MK로 1바이트를 전송하고 동시에 MK로부터 1바이트를 수신하는 과정을 보여준다. 우리가 볼 수 있듯이 이 두 프로세스는 프로그래머가 SCK 입력에서 마이크로 컨트롤러에 공급하는 동일한 클록 펄스를 사용합니다. 이는 SPI 프로그래밍 모드에서 이러한 역할이 할당되는 마이크로 회로의 핀 중 하나입니다. 두 개의 추가 신호 라인은 클록 사이클당 1비트의 데이터 수신 및 전송을 제공합니다. MOSI 입력을 통해 데이터가 마이크로 컨트롤러에 입력되고 읽기 데이터는 MISO 출력에서 ​​가져옵니다. SCK에서 MISO 및 MOSI로 이어지는 두 개의 점선을 확인하세요. 이는 마이크로 컨트롤러가 MOSI 입력에 설정된 데이터 비트를 "삼키는" 순간과 자체 데이터 비트를 MISO 출력으로 설정하는 순간을 보여줍니다. 모든 것이 아주 간단합니다. 그러나 MK를 프로그래밍 모드로 들어가려면 여전히 RESET 신호가 필요합니다. 공통 GND 와이어와 VCC 전원 공급 장치도 잊지 마세요. SPI를 통해 펌웨어를 플래시하려면 총 6개의 와이어만 마이크로 컨트롤러에 연결하면 됩니다. 아래에서는 이에 대해 더 자세히 분석할 것이지만 지금은 프로그래밍 모드에서 SPI를 통한 MK와의 데이터 교환이 4바이트 패킷으로 수행된다는 점을 추가하겠습니다. 각 패킷의 첫 번째 바이트는 기본적으로 전적으로 명령어 인코딩 전용입니다. 두 번째 바이트는 첫 번째 바이트에 따라 명령 코드의 연속이거나 주소의 일부이거나 임의의 값을 가질 수 있습니다. 세 번째 바이트는 주로 주소 전송에 사용되지만 많은 명령어에서 임의의 값을 가질 수 있습니다. 네 번째 바이트는 일반적으로 데이터를 전송하거나 임의의 값을 갖습니다. 네 번째 바이트 전송과 동시에 일부 명령은 마이크로컨트롤러에서 오는 데이터를 수신합니다. 각 명령에 대한 세부 정보는 "SPI 직렬 프로그래밍 명령어 세트"라는 표의 컨트롤러 설명서에서 확인할 수 있습니다. 지금은 컨트롤러와의 전체 교환이 일련의 32비트 패킷으로 구성되어 있으며 각 패킷에는 1바이트 이하의 유용한 정보가 전송된다는 점만 참고하면 됩니다. 이것은 매우 최적은 아니지만 전반적으로 잘 작동합니다.

3. 프로그래밍을 위해 MK 연결하기

SPI 인터페이스를 구성하고 MISO 출력에서 ​​데이터를 읽는 데 필요한 모든 신호가 마이크로 컨트롤러 입력에 공급되도록 하기 위해 프로그래머를 만들 필요가 없습니다. 이는 가장 일반적인 USB-RS232TTL 변환기를 사용하여 쉽게 수행할 수 있습니다.

인터넷에서는 그러한 변환기가 열등하고 심각한 작업을 수행할 수 없다는 정보를 종종 찾을 수 있습니다. 그러나 대부분의 컨버터 모델에 대해서는 이러한 의견이 잘못되었습니다. 예, 표준 COM 포트(예: TXD 및 RXD만)에 비해 사용 가능한 모든 입력 및 출력이 없지만 분리할 수 없는 설계(마이크로 회로는 플라스틱으로 채워져 있음)를 갖는 변환기가 판매되고 있습니다. 핀에 닿을 수 없음). 그러나 이것들은 구입할 가치가 없습니다. 어떤 경우에는 배선을 칩에 직접 납땜하여 누락된 포트 입력 및 출력을 얻을 수 있습니다. 이러한 "개선된" 변환기의 예가 그림 2(칩 PL-2303 - 기사 ""의 핀 목적에 대한 자세한 내용)에 나와 있습니다. 이것은 가장 저렴한 모델 중 하나이지만 직접 만든 디자인에 사용할 때 고유한 장점이 있습니다. COM 포트처럼 끝에 표준 9핀 커넥터가 있는 모든 기능을 갖춘 어댑터 코드도 널리 퍼져 있습니다. TTL 수준과 레거시 소프트웨어 및 일부 오래된 하드웨어와의 비호환성 측면에서만 일반 COM 포트와 다릅니다. 또한 CH34x 칩의 코드는 PL-2303의 컨버터에 비해 다양한 극한 테스트에서 훨씬 더 안정적이고 안정적이라는 것을 알 수 있습니다. 그러나 일반적인 사용 중에는 그 차이가 눈에 띄지 않습니다.

USB-RS232TTL 변환기를 선택할 때 사용 중인 운영 체제 버전과 해당 드라이버의 호환성에도 주의를 기울여야 합니다.

ATtiny13, ATtiny44, ATmega8 및 ATmega128의 네 가지 MK 모델의 예를 사용하여 마이크로 컨트롤러와 USB-RS232TTL 변환기를 연결하는 원리를 자세히 살펴 보겠습니다. 그림 3은 이러한 연결의 일반적인 다이어그램을 보여줍니다. RS232 신호(RTS, TXD, DTR 및 CTS)가 부적절하게 사용된다는 사실을 알면 놀랄 수도 있습니다. 그러나 걱정하지 마십시오. Perpetuum M 프로그램은 직접 작업할 수 있습니다. 출력 값을 설정하고 입력 상태를 읽을 수 있습니다. 어쨌든 CH34x 및 PL-2303 칩에서 널리 사용되는 USB-RS232TTL 변환기가 이 기능을 제공하며 이는 검증되었습니다. 표준 Windows 기능을 사용하여 포트에 액세스하므로 널리 사용되는 다른 변환기에도 문제가 없습니다.

일반 다이어그램에 표시된 저항은 원칙적으로 설치할 수 없지만 설치하는 것이 좋습니다. 그들의 목적은 무엇입니까? 변환기의 TTL 입력 및 출력과 마이크로 컨트롤러의 5V 전원 공급 장치를 사용하면 논리 레벨을 조정할 필요가 없어집니다. 모든 것이 이미 매우 정확합니다. 이는 연결이 직접적일 수 있음을 의미합니다. 그러나 실험 중에는 , 무슨 일이든 일어날 수 있습니다. 예를 들어, 비열한 법칙에 따르면 드라이버는 떨어질 수 없는 곳에 떨어질 수도 있고 어떤 경우에도 단락되어서는 안되는 것을 단락시킬 수 있습니다. 물론 무엇이든 가능합니다. "스크류드라이버"로 판명됩니다. 이 경우 저항기는 때때로 결과를 감소시킵니다. 그 목적 중 하나는 가능한 출력 충돌을 제거하는 것입니다. 사실 프로그래밍이 완료된 후 마이크로 컨트롤러는 정상 작동 모드로 들어가고 방금 MK에 기록된 프로그램에 따르면 변환기의 출력(RTS, TXD 또는 DTR)에 연결된 핀도 출력이 됩니다. 이 경우 직접 연결된 두 출력이 "싸움"하면 매우 나쁠 것입니다. - 다른 논리적 수준을 설정해 보십시오. 그러한 “투쟁”에서 누군가는 “패배”할 수 있지만 우리는 그것을 원하지 않습니다.

세 개의 저항 값은 4.3 KOhm 레벨에서 선택됩니다. 이는 컨버터 출력과 마이크로컨트롤러 입력 사이의 연결에 적용됩니다. 저항의 정확도는 중요하지 않습니다. 저항을 1 KOhm으로 줄이거 나 10 KOhm으로 늘릴 수 있습니다 (그러나 두 번째 경우에는 MK로가는 도중에 긴 전선을 사용할 때 간섭 위험이 증가합니다). 컨버터 입력(CTS)과 마이크로컨트롤러 출력(MISO) 사이의 연결에는 100Ω 저항이 사용됩니다. 이는 사용된 변환기 입력의 특성으로 설명됩니다. 테스트 중에 PL-2303 마이크로 회로에 변환기가 사용되었으며, 그 입력은 상대적으로 낮은 저항 (수백 Ohm 정도)으로 양극 전원 공급 장치에 연결되어 있습니다. "풀업을 차단"하려면 이렇게 작은 저항을 가진 저항을 설치해야 했습니다. 그러나 전혀 설치할 필요는 없습니다. 변환기에서는 이것이 항상 입력입니다. 이는 탈출구가 될 수 없습니다. 즉, 이벤트 전개에 출구 충돌이 없음을 의미합니다.

칩에 아날로그-디지털 변환기(예: ATmega8 또는 ATmega128)에 전원을 공급하기 위한 별도의 AVCC 핀이 있는 경우 공통 VCC 전원 핀에 연결해야 합니다. 일부 IC에는 두 개 이상의 VCC 전원 핀 또는 두 개 이상의 GND가 있습니다. 예를 들어 ATmega128에는 GND 핀 3개와 VCC 핀 2개가 있습니다. 영구 설계에서는 동일한 이름의 핀을 서로 연결하는 것이 좋습니다. 우리의 경우 프로그래밍하는 동안 VCC와 GND 핀을 각각 하나씩 사용할 수 있습니다.

ATtiny13 연결은 다음과 같습니다. 그림은 SPI를 통해 프로그래밍할 때 사용되는 핀 할당을 보여줍니다. 사진 옆에는 일시적인 연결이 실제로 어떻게 보이는지 나와 있습니다.


어떤 사람들은 이것이 심각하지 않다고 말할 수도 있습니다 - 배선 연결. 하지만 당신과 나는 현명한 사람들입니다. 우리의 목표는 마이크로 컨트롤러를 프로그래밍하고 최소한의 시간과 기타 리소스를 소비하며 누군가 앞에서 과시하는 것이 아닙니다. 품질이 저하되지 않습니다. 이 경우 "전선 연결" 방법은 매우 효과적이고 정당합니다. 컨트롤러 펌웨어 플래시는 일회성 절차이므로 모조 다이아몬드로 덮을 필요가 없습니다. 나중에 회로(완제품)에서 컨트롤러를 제거하지 않고 펌웨어를 변경하려는 경우 장치 제조 중 설치 중에 이 사항이 고려됩니다. 보통 이를 위해 커넥터(RESET, SCK, MOSI, MISO, GND)가 설치되는데, MK는 보드에 설치한 후에도 플래싱이 가능하다. 그러나 이것은 창의적인 즐거움입니다. 우리는 가장 간단한 경우를 고려하고 있습니다.

이제 ATtiny44 MK로 넘어가겠습니다. 여기에서는 모든 것이 거의 동일합니다. 그림과 사진을 바탕으로 초보자라도 연관성을 파악하는데 어려움이 없을 것입니다. ATtiny44와 마찬가지로 ATtiny24 및 ATtiny84 마이크로컨트롤러를 연결할 수 있습니다. 이 세 가지의 핀 할당은 동일합니다.


프로그래밍을 위해 컨트롤러를 임시로 연결하는 또 다른 예는 ATmega8입니다. 여기에는 더 많은 핀이 있지만 원리는 동일합니다. 전선 몇 개만 있으면 이제 컨트롤러가 정보를 "채울" 준비가 되었습니다. 핀 13에서 나오는 사진의 여분의 검정색 선은 프로그래밍에 참여하지 않습니다. MK가 프로그래밍 모드를 종료한 후 사운드 신호를 제거하도록 설계되었습니다. 이는 "Perpetuum M" 스크립트를 디버깅하는 동안 뮤직 박스 프로그램이 MK에 다운로드되었기 때문입니다.


종종 하나의 컨트롤러를 다양한 하우징에서 사용할 수 있습니다. 이 경우 케이스별로 핀 할당이 다르게 분배됩니다. 컨트롤러의 하우징이 그림에 표시된 것과 유사하지 않은 경우 MK 개발자 웹사이트에서 다운로드할 수 있는 기술 문서에서 핀의 목적을 확인하십시오.

그림을 완성하기 위해 MK 마이크로 회로를 많은 수의 "다리"와 연결하는 방법을 살펴보겠습니다. 핀 15에서 나오는 사진의 여분의 검정색 와이어의 목적은 ATmega8의 경우와 정확히 동일합니다.


당신은 아마도 모든 것이 아주 간단하다고 이미 확신했을 것입니다. 마이크로 회로의 핀 수를 세는 방법을 아는 사람은 (원 안의 표시에서 시계 반대 방향으로) 알아낼 것입니다. 그리고 정확성을 잊지 마세요. 마이크로회로는 깔끔한 사람을 좋아하며 부주의한 대우를 용서하지 않습니다.

소프트웨어 부분으로 넘어가기 전에 USB-RS232TTL 변환기 드라이버가 올바르게 설치되었는지 확인하세요(Windows 장치 관리자 확인). 변환기를 연결할 때 나타나는 가상 COM 포트의 번호를 기억하거나 적어 두십시오. 이 숫자는 아래에서 읽을 수 있는 스크립트 텍스트에 입력되어야 합니다.

4. 스크립트 - "Perpetuum M"의 프로그래머

우리는 "프로그래머"의 하드웨어 부분을 알아냈습니다. 이것은 이미 전투의 절반입니다. 이제 소프트웨어 부분을 다루어야 합니다. 그 역할은 마이크로컨트롤러와 상호 작용하는 데 필요한 모든 기능을 구현하는 스크립트의 제어 하에 Perpetuum M 프로그램에 의해 수행됩니다.

스크립트가 포함된 아카이브는 perpetuum.exe 프로그램이 있는 동일한 폴더에 압축을 풀어야 합니다. 이 경우 perpetuum.exe 파일을 실행하면 설치된 스크립트 목록과 함께 메뉴가 화면에 표시되며 그 중에는 "AVR MK Programmer"줄이 있습니다(유일한 것일 수 있음). 이것이 우리에게 필요한 라인입니다.

스크립트는 "MK Programmer AVR.pms" 파일의 PMS 폴더에 있습니다. 필요한 경우 Windows 메모장과 같은 일반 텍스트 편집기에서 이 파일을 보고, 연구하고, 편집할 수 있습니다. 스크립트를 사용하기 전에 포트 설정과 관련된 텍스트를 변경해야 할 가능성이 높습니다. 이렇게 하려면 Windows 장치 관리자에서 사용되는 포트 이름을 확인하고 필요한 경우 "PortName="COM4";" 행을 적절하게 수정하십시오. - 숫자 4 대신 다른 숫자가 있을 수 있습니다. 또한 다른 USB-RS232TTL 변환기 모델을 사용하는 경우 신호 반전 설정("High"라는 단어로 시작하는 스크립트 라인)을 변경해야 할 수도 있습니다. Perpetuum M 프로그램 지침(포트 작업 기능 섹션)에 포함된 예제 중 하나를 사용하여 USB-RS232TTL 변환기에 의한 신호 반전을 확인할 수 있습니다.

MK_AVR 하위 폴더에는 지원되는 컨트롤러에 대한 설명이 포함된 파일이 포함되어 있습니다. 필요한 컨트롤러가 그중에 없으면 비유에 따라 필요한 컨트롤러를 직접 추가할 수 있습니다. 파일 중 하나를 샘플로 선택하고 텍스트 편집기를 사용하여 필요한 데이터를 입력하고 마이크로 컨트롤러 설명서에서 가져옵니다. 가장 중요한 것은 조심해서 오류 없이 데이터를 입력하는 것입니다. 그렇지 않으면 MK가 프로그래밍되지 않거나 잘못 프로그래밍됩니다. 원래 버전은 ATtiny13, ATtiny24, ATtiny44, ATtiny84, ATmega8 및 ATmega128의 6개 마이크로컨트롤러를 지원합니다. 스크립트는 연결된 컨트롤러의 자동 인식을 구현하므로 수동으로 지정할 필요가 없습니다. MK에서 읽은 식별자가 사용 가능한 설명에 없으면 컨트롤러를 인식할 수 없다는 메시지가 표시됩니다.

스크립트가 포함된 아카이브에는 추가 정보도 포함되어 있습니다. AVR 컨트롤러 포함 파일 폴더에는 매우 유용하고 광범위한 컨트롤러 정의 파일 모음이 포함되어 있습니다. 이 파일은 MK용 프로그램을 작성할 때 사용됩니다. 4개의 추가 폴더 "MusicBox_..."에는 ATtiny13, ATtiny44, ATmega8 및 ATmega128용으로 별도로 MK에 다운로드할 수 있는 어셈블리 언어 및 펌웨어의 프로그램이 포함된 파일이 포함되어 있습니다. 이 기사에서 제안한 대로 프로그래밍을 위해 이러한 MK 중 하나를 이미 연결했다면 지금 바로 플래시할 수 있습니다. 그러면 뮤직 박스가 제공됩니다. 이에 대한 자세한 내용은 아래에서 확인하세요.

스크립트 메뉴에서 "MK AVR Programmer" 행을 선택하면 스크립트가 실행되기 시작합니다. 동시에 포트를 열고, 프로그래밍 모드로 전환하라는 명령을 MK에 보내고, MK로부터 성공적인 전환에 대한 확인을 받고, MK 식별자를 요청하고, 사용 가능한 식별자 중에서 해당 식별자로 이 MK에 대한 설명을 검색합니다. 설명이 포함된 파일입니다. 필요한 설명을 찾지 못하면 해당 메시지가 표시됩니다. 설명이 발견되면 프로그래머의 기본 메뉴가 열립니다. 그림 8에서 스크린샷을 볼 수 있습니다. 더 자세히 이해하는 것은 어렵지 않습니다. 메뉴는 매우 간단합니다.

스크립트의 첫 번째 버전에서는 본격적인 프로그래머의 일부 기능이 구현되지 않았습니다. 예를 들어, EEPROM을 읽고 쓸 수 있는 방법이 없습니다. 그러나 텍스트 편집기에서 스크립트를 열면 주요 내용이 이미 구현되어 있음에도 불구하고 크기가 매우 작다는 것을 알 수 있습니다. 이는 누락된 기능을 추가하는 것이 그리 어렵지 않다는 것을 의미합니다. 언어는 매우 유연하며 작은 프로그램에서 풍부한 기능을 구현할 수 있습니다. 그러나 대부분의 경우 기존 기능으로도 충분합니다.

일부 기능 제한 사항은 스크립트 텍스트에 직접 설명되어 있습니다.
//0 주소에서만 기록을 구현했습니다. (확장 세그먼트 주소 레코드는 무시되고 LOAD OFFSET도 무시됩니다.)
//HEX 파일의 레코드 순서와 연속성을 확인하지 않습니다.
//체크섬이 확인되지 않음
이는 MK용 펌웨어 코드를 가져오는 HEX 파일 작업에 적용됩니다. 이 파일이 손상되지 않은 경우 체크섬을 확인해도 아무런 효과가 없습니다. 왜곡된 경우 스크립트를 사용하여 감지할 수 없습니다. 대부분의 경우 나머지 제한 사항은 문제가 되지 않지만 여전히 염두에 두어야 합니다.

5. 오르골 - 초보자를 위한 간단한 공예

ATtiny13, ATtiny44, ATmega8 또는 ATmega128과 같은 마이크로컨트롤러 중 하나가 있으면 이를 쉽게 뮤직 박스나 뮤직 카드로 바꿀 수 있습니다. 이렇게 하려면 스크립트와 동일한 아카이브의 "MusicBox_..." 폴더에 있는 4개 중 하나인 해당 펌웨어를 MK에 작성하는 것으로 충분합니다. 펌웨어 코드는 확장자가 ".hex"인 파일에 저장됩니다. 물론 이러한 기술에 ATmega128을 사용하는 것은 ATmega8과 마찬가지로 "지방"입니다. 그러나 이는 테스트나 실험, 즉 교육 목적으로 유용할 수 있습니다. Assembler에 있는 프로그램의 텍스트도 첨부되어 있습니다. 프로그램은 처음부터 만들어지지 않았습니다. A.V. Belov의 책 "AVR Microcontrollers in Amateur Radio Practice"의 뮤직 박스 프로그램이 기본으로 사용되었습니다. 원래 프로그램은 여러 가지 중요한 변경을 거쳤습니다.
1. 4개의 MK 각각에 적용: ATtiny13, ATtiny44, ATmega8 및 ATmega128
2. 버튼이 제거되었습니다. 전원과 사운드 이미터 외에는 컨트롤러에 연결할 필요가 없습니다. (멜로디는 무한 루프로 차례로 재생됩니다.)
3. 음악적 리듬의 방해를 제거하기 위해 각 음표의 지속 시간은 음표 사이의 일시 중지 지속 시간만큼 줄어듭니다.
4. 8번째 멜로디가 연결되어 있으며, 북버전에서는 사용되지 않습니다.
5. 주관적인 측면에서: 알고리즘을 최적화하고 이해하기 쉽게 만드는 일부 "개선 사항"

일부 멜로디에서는 특히 중간에 있는 "Smile"에서 거짓과 심각한 오류까지 들을 수 있습니다. 벨소리 코드는 책에서 가져온 것입니다(또는 원래 asm 파일과 함께 책의 저자 웹사이트에서 다운로드한 것). 수정되지 않았습니다. 분명히 멜로디 인코딩에 오류가 있습니다. 그러나 이것은 문제가 되지 않습니다. 음악에 "친절"한 사람이라면 누구나 쉽게 문제를 파악하고 모든 것을 고칠 수 있습니다.

ATtiny13에서는 16비트 카운터가 부족하여 8비트 카운터를 사용하여 음표를 재생해야 했으며 이로 인해 음표의 정확도가 약간 떨어졌습니다. 그러나 이것은 귀로 거의 눈에 띄지 않습니다.

구성 비트 정보. 해당 설정은 새 마이크로컨트롤러의 상태와 일치해야 합니다. 귀하의 MK가 이전에 어딘가에서 사용되었다면 구성 비트의 상태를 확인해야 하며, 필요한 경우 이를 새 마이크로컨트롤러의 설정과 일치시켜야 합니다. 이 MK 설명서("퓨즈 비트" 섹션)에서 새 마이크로컨트롤러의 구성 비트 상태를 확인할 수 있습니다. ATmega128은 예외입니다. 이 MCU에는 이전 ATmega103과의 호환성 모드를 활성화하는 M103C 비트가 있습니다. M103C 비트를 활성화하면 ATmega128의 성능이 크게 감소하며 이 비트는 새로운 MK에서 활성화됩니다. M103C를 비활성 상태로 재설정해야 합니다. 구성 비트를 조작하려면 프로그래머 스크립트 메뉴의 해당 섹션을 사용하십시오.

뮤직 박스의 다이어그램을 제공하는 것은 의미가 없습니다. 뮤직 박스에는 마이크로 컨트롤러, 전원 공급 장치 및 압전 음향 방출기만 포함되어 있습니다. MK를 프로그래밍할 때와 똑같은 방식으로 전원이 공급됩니다. 사운드 방출기는 공통 와이어(컨트롤러의 GND 핀)와 MK 핀 중 하나 사이에 연결되며, 핀 번호는 프로그램 어셈블리 코드(*.asm)가 있는 파일에서 찾을 수 있습니다. 주석의 각 MK에 대한 프로그램 텍스트 시작 부분에는 "사운드 신호가 핀 XX에서 생성됩니다."라는 줄이 있습니다. 프로그래머 스크립트가 완료되면 마이크로컨트롤러는 프로그래밍 모드를 종료하고 정상 작동으로 들어갑니다. 멜로디 재생이 즉시 시작됩니다. 사운드 이미터를 연결하면 이를 확인할 수 있습니다. SPI에 사용되지 않는 핀에서 사운드를 가져오는 경우에만 크리스털을 프로그래밍하는 동안 사운드 이미터를 연결된 상태로 둘 수 있습니다. 그렇지 않으면 핀의 추가 정전 용량이 프로그래밍을 방해할 수 있습니다.