검색결과 리스트
부산IT학원/스마트컨트롤러에 해당되는 글 131건
- 2014.07.29 20140729 (Assembly imul, idiv, div, cbw, cwd, cdq, cwde, movsx, movzx)
- 2014.07.28 20140728 (add, sub, inc, dec, neg, mul)
- 2014.07.25 20140725 (Assembly Flags Register)
- 2014.07.24 20140724 (ASM mov, xchg)
- 2014.07.23 20140723 (Assembly 기초, windbg 사용법)
- 2014.07.22 20140722 (ARM ADC, Assembly 기초, Debug)
- 2014.07.21 20140721 (ARM adc 소스 작성중, asm)
- 2014.07.17 20140717 (ARM Ultrasonic 초음파 모듈)
- 2014.07.16 20140716 (ARM 초음파 모듈, Ultrasonic)
- 2014.07.15 20140715 (ARM Timer & Counter)
글
20140729 (Assembly imul, idiv, div, cbw, cwd, cdq, cwde, movsx, movzx)
112일차
--------------
Assembly
--------------
------- imul Instruction
부호 있는 곱셈
flags는 CF, OF만 사용하고 함께 set된다.
3가지가 있다.
--- 1. imul source
eax, ax, al의 값과 operand 값과 연산을 하고
연산된 값은 edx:eax, dx:ax, ax에 저장된다.
--- 2. imul Reg, source
위와 좀 다른데
operand1 과 operand2와 연산하여
operand1 에 저장한다.
넘는 값은 짤리고 CF, OF가 set 됨
--- 3. imul Reg, source, immediate
이것도 좀 다른데
source 와 immediate 를 연산하여
Destination에 저장한다.
넘는 값은 짤리고 CF, OF가 set 됨
몇 가지 예제)
------- div, idiv Instruction
나눗셈
나눗셈은 flags가 바뀌지 않는다.
연산을 할 때에 잿수는 두 배의 크기여야 한다.
위의 표와 같이
byte를 연산할 경우
AX의 값을 다 바꿔야하고
word를 연산할 경우
DX의 값도 바꿔야하고
double word를 연산할 경우
EDX의 값도 함께 바꿔줘야 한다.
예를 들면
div ebx 를 한다고 치면
mov edx , 0
mov eax , 2
mov ebx , 2
div ebx
mov edx , -1 (FF FF FF FF)
mov eax , -2
mov ebx , 2
div ebx
이런식으로 확장된 곳의 값도 함께 바꿔줘야 한다.
이런 불편함을 덜어주는 명령어가
cbw AL -> AX
cwd AX -> DX:AX
cdq EAX -> EDX:EAX
cwde AX -> EAX
이다.
cwd AX -> DX:AX
cdq EAX -> EDX:EAX
cbw AL -> AX
cwde AX -> EAX
------- movzx , movsx Instruction
8 bit를 16 bit로,
16 bit를 32 bit로
확장하여 값을 넣는다.
movzx , movsx 의 다른 점은
movzx 는 확장된 곳에 무조건 0 을 채워 넣고
movsx 는 확장된 곳에 부호에 맞게 채워 넣는다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140731 (Assembly loop, 배열, lea, pipe line) (0) | 2014.07.31 |
---|---|
20140730 (rounding factor, adc, sbb, clc, stc, cmc, jmp, cmp) (0) | 2014.07.30 |
20140728 (add, sub, inc, dec, neg, mul) (0) | 2014.07.28 |
20140725 (Assembly Flags Register) (0) | 2014.07.25 |
20140724 (ASM mov, xchg) (0) | 2014.07.24 |
글
20140728 (add, sub, inc, dec, neg, mul)
111일차
------------------
Assembly
------------------
------- add, sub Instruction
(덧셈, 뺄셈)
위의 표에서 메모리와 상수 간에 명령어의 속도를 보면 다른 것보다 상당히 느리다.
예제 코드로 설명을 덧붙이자면...
int A = 0;
A = 0;
while(A < 10)
{
A++;
}
A를 한번 더 초기화하면서 위의 표를 참고 하면 엄청나게 많은 시간이 소모되었다.
최적활를 위해서 소스를 짤 때에 이런 것을 유의하여 작성해야 한다.
------- inc, dec Instruction
(increase, decreace 1 증가, 감소)
386 속도 용량
add eax , 1 2 5
inc eax 2 1
똑같은 +1 을 하는 코드를 사용한다면
inc를 사용하는게 용량면에서 좋다.
그런데 MS 컴파일러는 최적화를 하지 않는다.
MS Visual Studio를 통해 확인해 본다면
아래와 같은 소스를 짜고 저 위치에 Break Point를 걸고
F5로 디버그 모드를 실행 후, 디스어셈블리를 확인 할 수 있다.
아래 Assembly 소스를 보면 add, sub을 사용하였다.
속도면에서는 add, sub과 inc, dec의 차이는 없지만,
용량면에서 차이가 나기 때문에 inc, dec를 써주면 더 최적화된 소스이나,
컴파일러마다(?) 이런 요소를 상관하지 않을 수 있으므로
사람의 손이 필요하다.
위에서
mov eax, dword ptr [a]
라는게 있는데 C로 치자면 포인터이다.
a 는 값 a
[a] 는 a에 저장된 주소를 따라간다는 뜻이다.
몇 가지 예제
------- neg Instruction
(negative : 부호를 반대로. 2의 보수법을 취함)
몇 가지 예제
1.
2. -(x + y - 2z + 1)
3. 2(-x + y -1) + z
------- mul, imul Instruction
곱셈
mul : 부호가 없을 때
imul : 부호가 있을 때
1. 1byte 연산
mul 0x77
=> AX = AL * 0x77
2. 2byte 연산
mul 0x1234
=> DX : AX = AX * 0x1234
3. 4byte 연산
mul 0x12345678
=> EDX : EAX = EAX * 0x12345678
예제)
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140730 (rounding factor, adc, sbb, clc, stc, cmc, jmp, cmp) (0) | 2014.07.30 |
---|---|
20140729 (Assembly imul, idiv, div, cbw, cwd, cdq, cwde, movsx, movzx) (0) | 2014.07.29 |
20140725 (Assembly Flags Register) (0) | 2014.07.25 |
20140724 (ASM mov, xchg) (0) | 2014.07.24 |
20140723 (Assembly 기초, windbg 사용법) (0) | 2014.07.23 |
글
20140725 (Assembly Flags Register)
110일차
-------------------------
Assembly mnemonics
-------------------------
------- 덧셈, 뺄셈, Flag Reg
위에 것 중에 한가지만 예로 든다면.
EFL 이 Flags Register이다.
하위 12bit 중에 OF, SF, ZF, CF Flag만 보자.
------- batch file
윈도우에는 실행파일이 3종류가 있다.
- bat (cmd)
- com
- exe
이 중 같은 이름이고 확장자만 다를 때 실행할 경우
bat 파일이 실행된다.
---- batch 파일을 만드는 방법
@echo ---------------- compile ----------------
ml /c /coff /Zi %1.asm
@echo ---------------- link ----------------
link /debug /subsystem:console /entry:start /out:%1.exe %1.obj kernel32.lib
@dir %1.*
@pause
@start windbg %1.exe
이런식으로 사용할 명령어를 적어주고
파일 이름의 확장자를 .bat로 해주기만 하면 끝.
%1은 첫 번째 인수를 말한다.
--------------
ARM PMC
--------------
------- 그냥 테스트
LCD에 1 만 찍힌다. datasheet를 참고하면 Processor Clock 만 켜져 있다.
PMC_SCDR(PMC System Clock Disable Register) 에 1을 넣으면
Processor Clock이 Disable 되는데 그대로 동작이 멈춘다.
그 밑에 어떤 코드도 실행하지 않는다.
그래서 인터럽트로 다시 동작을 시켜주면 동작할까 싶어
이 코드를 추가하고 나니
약 5초 정도 후에 다시 동작하기 시작했다.
PMC로 MCU를 끄더라도 다른 장치가 동작하고 있고
다시 MCU도 킬 수 있었다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140729 (Assembly imul, idiv, div, cbw, cwd, cdq, cwde, movsx, movzx) (0) | 2014.07.29 |
---|---|
20140728 (add, sub, inc, dec, neg, mul) (0) | 2014.07.28 |
20140724 (ASM mov, xchg) (0) | 2014.07.24 |
20140723 (Assembly 기초, windbg 사용법) (0) | 2014.07.23 |
20140722 (ARM ADC, Assembly 기초, Debug) (0) | 2014.07.22 |
글
20140724 (ASM mov, xchg)
109일차
--------------
Assembly
--------------
------- []의미
------- mov 명령어
mov 명령어의 operand에 오는 속성과 정보들이다.
--- 경우 1. operand에 Reg, 상수
prefix byte를 실제로 확인.
--- 경우 2. operand에 Mem, 상수
--- 경우 3. 추가적으로...
------- 문법
mov buf , number
C로 표현하면
=> buf = number;
그런데 위에 mov 옵션을 보면
메모리에서 메모리로 옴겨지는 경우는 없다.
그래서 mov buf , number
이 문법은 틀렸다.
맞는 어셈블리로 짜려면
mov eax , number
mov buf , eax
이렇게 짜야한다.
또,
또,
그래서 INVOKE를 넣어줘야 한다.
(다른 방법이 있다고 하는데 아직 초보 수준에서는 이 정도만...)
------- xchg
C로
buf = number1;
number1 = number2;
number2 = buf;
이런 swap 하는 명령인데
어셈블리로 바꾸면
mov eax , number1
mov ebx , number2
mov ecx , eax
mov eax , ebx
mov ebx , ecx
mov number1 , eax
mov number2 , ebx
이렇게 한다.
중간에 swap을 더 빨리 해 주는 명령어가 xchg 이다.
mov eax , number1
mov ebx , number2
xchg eax , ebx
mov number1 , eax
mov number2 , ebx
이러면 끝.
용량과 속도도 더 빠르다.
--- xchg operand 정보
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140728 (add, sub, inc, dec, neg, mul) (0) | 2014.07.28 |
---|---|
20140725 (Assembly Flags Register) (0) | 2014.07.25 |
20140723 (Assembly 기초, windbg 사용법) (0) | 2014.07.23 |
20140722 (ARM ADC, Assembly 기초, Debug) (0) | 2014.07.22 |
20140721 (ARM adc 소스 작성중, asm) (0) | 2014.07.21 |
글
20140723 (Assembly 기초, windbg 사용법)
108일차
--------------------
Assembly Windbg
--------------------
------- windbg 로 프로그램 관찰
- string 변수에 1234567890을 입력합니다.
- string 에 1234567890 이 아스키코드로 입력됐음을 확인할 수 있습니다.
- 1234567890 이라는 10진수를 16진수로 바꾸면 49 96 02 D2 입니다.
- 다음 코드로 진행하면 number1에 eax에 저장된 49 96 02 D2 를 저장합니다.
- Register는 Big Endian이고, Memory는 Little Endian이라서
Memory에 거꾸로 저장된 것을 볼 수 있습니다.
- 위와 같은 과정을 거쳐 number2 에 255 를 입력하면
메모리에 아래와 같이 16진수로 FF 가 입력된 것을 볼 수 있습니다.
- 다음으로 진행해서 add eax, number2 명령을 EIP Reg를 통해 주소를 찾아가
기계 코드로 쓰여진 것을 확인할 수 있습니다.
03 05 04 40 40 00 이라고 입력되어 있는데요.
- Appendix D 목록을 보면 add 명령의 정보를 볼 수 있습니다.
Opcode 가 03 으로, add 명령의 기계코드가 03 이란 것을 알 수 있습니다.
그런데 기계코드가 03 05 로 뒤에 05 가 더 붙었습니다.
16 bit와 32 bit 를 분별하기 위해서 더 붙는다고 합니다.
디버깅으로 이렇게 관찰할 수 있습니다.
계속해서 PDF 파일을 봅니다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140725 (Assembly Flags Register) (0) | 2014.07.25 |
---|---|
20140724 (ASM mov, xchg) (0) | 2014.07.24 |
20140722 (ARM ADC, Assembly 기초, Debug) (0) | 2014.07.22 |
20140721 (ARM adc 소스 작성중, asm) (0) | 2014.07.21 |
20140717 (ARM Ultrasonic 초음파 모듈) (0) | 2014.07.17 |
글
20140722 (ARM ADC, Assembly 기초, Debug)
107일차
------------------
ARM ADC
------------------
------- ADC 타이밍도
1. ADC_CR Reg에 START bit가 set 되면
변환을 시작한다.
2. 변환이 끝나면 ADC_SR Reg에 해당 채널 EOC bit가 set 되고
ADC_SR Reg에 DRDY bit도 set 된다. (DRDY는 가장 먼저 변환이 끝난 후 계속 H)
3. 해당 ADC_CDRx Reg로 값을 읽으면 ADC_SR Reg에 해당 채널 EOC bit가 clear 된다.
4. 다시 ADC_CR Reg에 START bit가 set 되면 변환을 시작하고
변환이 끝나면 또 해당 채널의 bit가 set 된다.
5. ADC_LCDR Reg에는 최근에 변환이 완료된 값을 가지고 있고
이 값을 읽을 시 모든 채널의 EOC bit가 clear 된다.
--- 소스
- adc.c
- main.c
---------------
ASSEMBLY
---------------
------- example source code
------- compile, link, run
------- debug 모드
------- windbg 로 디버깅
1. 요놈 실행.
2. 실행 파일 열기
3. 실행 파일 열기
4. 이 화면이 뜸.
5. 알림창이 한 번 뜨고 두 번정도 더 누르면
6. 아래 창이 뜸.
7. View -> Registers 실행
8. View -> Memory 실행
9. 감시할 함수 이름을 써주는데 _start 함수를 감시할 예정.
10. 한 번 더 실행 시켜서 감시할 변수의 주소값을 적어주는데
number1이 가장 먼저 시작하는 변수라 이것을 적으면 뒤에 있는 메모리의 다른 변수도
함께 볼 수 있다.
11. 그럼 여러 창들이 뜨고 아래와 같이 배치하였다.
12. F11 키를 눌러 몇 번 실행하였다. 그림 안에 설명 참고.
13. 이렇게 Memory와 Register의 값이 어떻게 변하는지 관찰할 수 있다.
14. 여기서 중요한것은 12번 그림에서 0x00401072 주소에 명령어를 보면
a3 00 40 40 00 이라는 숫자가 있는데
mov number1, eax 를 의미한다.
위의 그림을 참고하면 명령어가 각 장비마다 실행 속도를 확인할 수 있고,
만약 같은 동작을 하는 명령어인데 속도와, 크기가 더 효과적인 명령어가 있을 수도 있다.
C에서는 바꿀 수 없지만 Assembly를 통해 더 효과적인 명령으로 수정하여
더욱 최적화가 가능하다.
또한, 이 처럼 실행 파일을 Asm 파일로 바꾸는 과정을 Disassembly 라고 하는데,
Disassembly 를 하고 코드를 바꿔 실행의 흐름을 바꾸는 기술을 Reverse Engineering 이라고 부른다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140724 (ASM mov, xchg) (0) | 2014.07.24 |
---|---|
20140723 (Assembly 기초, windbg 사용법) (0) | 2014.07.23 |
20140721 (ARM adc 소스 작성중, asm) (0) | 2014.07.21 |
20140717 (ARM Ultrasonic 초음파 모듈) (0) | 2014.07.17 |
20140716 (ARM 초음파 모듈, Ultrasonic) (0) | 2014.07.16 |
글
20140721 (ARM adc 소스 작성중, asm)
106일차
--------------
ARM ADC
--------------
------- 소스
--- adc.h
--- adc.c
-----------
asm
-----------
------- Reg
registers 종류 : data reg , general reg
EAX - EBX - ECX - EDX = Data Reg Or General Reg 라 한다.
여기서 특히 사용 많이 하는 EAX 레지스터를 accumulator 라 한다.
그래서 특히 4개중에 속도가 최고로 빠르다.
각각의 레지스터들은 32 비트이다 .
여기서 EAX는 반을 나누어서 사용한다 . 오른쪽은 AX 라하며 왼쪽은 호칭은 없다
여기서 AX를 또 반을 이용해서 사용하는데 반을 나눈 두가지를 AH AL 이라한다.
Ex) 레지스터 사용되는 형식
int A = 100; short B = 100; char C = 100; 여기서 연산을 A= A+1 을 할 경우 1. mov EAX,A의 주소 2. add EAX,1 ; EAX=EAX + 1 3. mov A의 주소,EAX B = B+1 을하면 EAX 대신에 AX를 대입하고 A의 주소에 B의 주소를 넣으면 된다. C = c+1 을하면 EAX 대신에 AL를 대입하고 A의 주소에 C의 주소를 넣으면 된다. |
이렇게 앞의 type에 따라 용량에 맞춰 레지스터가 사용된다.
---- Index Reg
-- Index Reg - ESI , EDI
1. 주로 주소를 저장하는 레지스터이다.
2. 연산을 할 때도 사용할 수 있다.
3. 데이터를 복사할때 사용하면 편리하다.
-출발점 주소를 ESI 도착점 주소를 EDI로 지정하면
ESI가 가리키는 주소를 EDI가 가르키는 복사된다..
-- Index Reg - ESP , EBP
ESP = Stack Pointer EBP = Base Pointer 라 한다.
이 두개의 레지스터는 함수호출할때 사용되며 중요한 레지스터이므로 함부로 설정하지 않는다.
----- Segment Reg
CS |
코드 영역 |
DS |
데이터 영역 |
ES |
확장 영역 |
FS |
안 중요함 |
GS |
안 중요함 |
SS |
스택 영역 |
----- EIP (Reg Or instruction pointer)
- 명령어를 저장하는 주소
- 다른 CPU에서는 PROGRAM COUNT 라 하고 PC이다. PC 와 EIP는 같은 것이다.
EFLAGS Reg : 상태를 저장하는 레지스터
----- PC Hardware : Input / Output
Memory mapped i/o : ARM/AVR 방식 , C로 접근가능 I/O레지스터가 메모리에 있음
I/O mapped i/o : 인텔방식 C로 접근불가 I/O레지스터가 메모리에 없음 어셈블리로 접근가능
Integrated development environments (IDE)
- test compiler debugger 3개를 합쳐서 통합개발환경이라 한다.
--- 예제 소스
- 명령어
add eax, 158
- directive (라벨, 지시자)
. 으로 시작.
- macro
- mnemonic 니모닉이라고 읽음.
name mnemonic operand(s) ; comments
Zerocount: mov ecx, 0 ; ecx = 0;
(name은
생략 가능)
(라벨, 지시자)
name만 쓸 수도 있다.
- .386
.MODEL FLAT
이 두 명령어는 sam 작성시 가장 앞에 써줘야 한다.
- asm으로 작성할 때 .386을 안쓰면 그 하위 버전용으로만 동작한다.
.586등 높은 수를 사용하면 최신기능을 사용할 수 있으나
하위 cpu들은 그 기능을 사용할 수 없다.
- 함수 선언
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
(cpu, reg를 만지고 원래 상태로 되돌리는 기능)
- 헤더파일 포함
INCLUDE io.h
- cr EQU 0dh (h:hexa, 0d = 13)
이 코드는 C로
#define cr 0dh
EQU(이퀄, 같다)
정리하면 cr이란 단어가 나오면 16진수 0D로 변환하라는 뜻.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140723 (Assembly 기초, windbg 사용법) (0) | 2014.07.23 |
---|---|
20140722 (ARM ADC, Assembly 기초, Debug) (0) | 2014.07.22 |
20140717 (ARM Ultrasonic 초음파 모듈) (0) | 2014.07.17 |
20140716 (ARM 초음파 모듈, Ultrasonic) (0) | 2014.07.16 |
20140715 (ARM Timer & Counter) (0) | 2014.07.15 |
글
20140717 (ARM Ultrasonic 초음파 모듈)
104일차
-------------------------------
ARM Ultrasonic (초음파 모듈)
-------------------------------
------- 어제 소스에 이어 계속 거리를 측정하는 소스를 작성한다.
--- 원리는
트리거 신호를 발사하면
초음파 모듈에서 버스트 신호를 발사하고
Echo로 H를 내보내다가
버스트 신호가 들어오면
Echo가 L로 들온다.
이 때 걸린 시간을 계산하면 물체와의 거리가 된다.
------- 소스
--- usonic.c
#include "usonic.h"
static volatile unsigned int uiCm;
static volatile unsigned int uiDist;
void Ultra_Init(void)
{
Trg_Init();
Echo_Init();
Timer1_Init();
}
void Timer1_Init(void)
{
// PIOA에 전원공급
*AT91C_PMC_PCER = (1<<AT91C_ID_TC1);
// Clock disable
*AT91C_TC1_CCR = AT91C_TC_CLKDIS;
// TC1 인터럽트 비활성화
*AT91C_AIC_IDCR = (1<<AT91C_ID_TC1);
// TC1 인터럽트 비활성화
*AT91C_TC1_IDR = AT91C_TC_COVFS | AT91C_TC_LOVRS | AT91C_TC_CPAS
| AT91C_TC_CPBS | AT91C_TC_CPCS | AT91C_TC_LDRAS
| AT91C_TC_LDRBS | AT91C_TC_ETRGS;
// Status Reg를 한번 읽어야 한다.
// ATmel 사에서 해야한다고 함.
*AT91C_TC1_SR;
// TC1 Clock Select 128 , RC Compare Trigger Enable
*AT91C_TC1_CMR = AT91C_TC_CLKS_TIMER_DIV2_CLOCK
| AT91C_TC_CPCTRG;
// 분주비 128일 때 375마다 1ms.
*AT91C_TC1_RC = 353;
// 인터럽트시 실행할 함수
AT91C_AIC_SVR[AT91C_ID_TC1] = (volatile unsigned int)Ultra_Handler;
// 인터럽트 걸리는 조건 및 우선순위
AT91C_AIC_SMR[AT91C_ID_TC1] = AT91C_AIC_SRCTYPE_HIGH_LEVEL
| AT91C_AIC_PRIOR_LOWEST;
// 인터럽트 Edge detecter 끄기
*AT91C_AIC_ICCR = (1<<AT91C_ID_TC1);
// TC1 인터럽트 RC compare 활성화
*AT91C_TC1_IER = AT91C_TC_CPCS;
// TC1 인터럽트 활성화
*AT91C_AIC_IECR = (1<<AT91C_ID_TC1);
// Clock enable
*AT91C_TC1_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Clock start
// *AT91C_TC1_CCR = AT91C_TC_SWTRG;
}
void Ultra_Handler(void)
{
++uiCm;
// Status Reg를 한번 읽어야 다음 인터럽트가 걸린다.
// ATmel 사에서 해야한다고 함.
*AT91C_TC1_SR;
}
void Echo_Init(void)
{
// PIOA에 전원공급
*AT91C_PMC_PCER = (1<<AT91C_ID_PIOA);
// PIN_ECHO 출력 비활성화
*AT91C_PIOA_ODR = PIN_ECHO;
// PIN_ECHO 핀 활성화
*AT91C_PIOA_PER = PIN_ECHO;
// PIN_ECHO 인터럽트 비활성화
*AT91C_PIOA_IDR = PIN_ECHO;
// pull up 저항 OFF
*AT91C_PIOA_PPUDR = PIN_ECHO;
// 인터럽트시 실행할 함수
AT91C_AIC_SVR[AT91C_ID_PIOA] = (volatile unsigned int)Echo_Handler;
// 인터럽트 걸리는 조건 및 우선순위
AT91C_AIC_SMR[AT91C_ID_PIOA] = AT91C_AIC_SRCTYPE_POSITIVE_EDGE
| AT91C_AIC_PRIOR_LOWEST;
// 인터럽트 Edge detecter 끄기
*AT91C_AIC_ICCR = (1<<AT91C_ID_PIOA);
// PIOA 인터럽트 Edge detecter 켜기
*AT91C_AIC_ISCR = (1<<AT91C_ID_PIOA);
}
void Trg_Init(void)
{
*AT91C_PMC_PCER = (1<<AT91C_ID_PIOA);
*AT91C_PIOA_PER = PIN_TRG;
*AT91C_PIOA_OER = PIN_TRG;
}
void Echo_Handler(void)
{
static unsigned int uiState;
static volatile unsigned int uiMode = MODE_POSITIVE;
// ISR은 한 번 읽으면 바로 다 지워짐
// 따라서 따로 저장해 두고 사용.
uiState = *AT91C_PIOA_ISR;
// 해당 인터럽트가 오면
if(PIN_ECHO == (uiState & PIN_ECHO))
{
// 상승 edge
if(MODE_POSITIVE == uiMode)
{
uiCm = 0;
// 인터럽트 걸리는 조건 및 우선순위
AT91C_AIC_SMR[AT91C_ID_PIOA] =
AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE
| AT91C_AIC_PRIOR_LOWEST;
uiMode = MODE_NEGATIVE;
}
// 하강 edge
else
{
// PIN_ECHO 인터럽트 비활성화
*AT91C_PIOA_IDR = PIN_ECHO;
uiDist = uiCm;
uiMode = MODE_POSITIVE;
}
}
// 처리중 인터럽트 발생시 초기화.
uiState = *AT91C_PIOA_ISR;
// Atmel 사에서 무슨 의미인지 모르지만
// 인터럽트가 끝날 때 마지막에 꼭 넣으라 함.
*AT91C_AIC_EOICR = 0;
}
void Ultra_Trigger(void)
{
volatile unsigned int uiCnt;
// PIN_ECHO 인터럽트 활성화
*AT91C_PIOA_IER = PIN_ECHO;
// PIOA 인터럽트 활성화
*AT91C_AIC_IECR = (1<<AT91C_ID_PIOA);
// 시작 펄스 신호
*AT91C_PIOA_CODR = PIN_TRG;
DELAY(1000);
*AT91C_PIOA_SODR = PIN_TRG;
DELAY(5000);
*AT91C_PIOA_CODR = PIN_TRG;
}
unsigned int Ultra_Act(void)
{
uiDist = 0;
Ultra_Init();
Ultra_Trigger();
while(0 == uiDist);
return uiDist;
}
--- usonic.h
#ifndef _USONIC_H_
#define _USONIC_H_
#include "project.h"
#define PIN_TRG AT91C_PIO_PA15
#define PIN_ECHO AT91C_PIO_PA14
#define MODE_POSITIVE 1
#define MODE_NEGATIVE 0
void Ultra_Init(void);
void Timer1_Init(void);
void Ultra_Handler(void);
void Echo_Init(void);
void Trg_Init(void);
void Echo_Handler(void);
void Ultra_Trigger(void);
unsigned int Ultra_Act(void);
#endif //_USONIC_H_
--- main.c
#include "project.h"
#include "lcd.h"
#include "dbgu.h"
#include "irq.h"
#include "tc.h"
#include "usonic.h"
int main(void)
{
volatile unsigned int uiCnt;
unsigned int uiDist;
Lcd_Init();
// DBGU_Init();
// IRQ_Init();
// IRQ_LED_Init();
// TC0_Init();
Lcd_Str((const unsigned char *)"Ultrasonic");
while (1)
{
uiDist = Ultra_Act();
Lcd_Inst(INST_SET_DDRAM | 0x40);
Lcd_Num(uiDist);
DELAY(1000000);
}
while(1);
return 0;
}
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140722 (ARM ADC, Assembly 기초, Debug) (0) | 2014.07.22 |
---|---|
20140721 (ARM adc 소스 작성중, asm) (0) | 2014.07.21 |
20140716 (ARM 초음파 모듈, Ultrasonic) (0) | 2014.07.16 |
20140715 (ARM Timer & Counter) (0) | 2014.07.15 |
20140714 (ARM Interrupt로 LED 켜기) (0) | 2014.07.14 |
글
20140716 (ARM 초음파 모듈, Ultrasonic)
103일차
--------------------
ARM 초음파 모듈
--------------------
------- atmega 에서 사용하던 소스를 가져오는데
ARM에 맞게 변형하여 사용한다.
--- usonic.c
오늘은 여기까지....
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140721 (ARM adc 소스 작성중, asm) (0) | 2014.07.21 |
---|---|
20140717 (ARM Ultrasonic 초음파 모듈) (0) | 2014.07.17 |
20140715 (ARM Timer & Counter) (0) | 2014.07.15 |
20140714 (ARM Interrupt로 LED 켜기) (0) | 2014.07.14 |
20140708 (ARM DBGU UART 통신) (0) | 2014.07.08 |
글
20140715 (ARM Timer & Counter)
102일차
------------------------
ARM Timer & Counter
------------------------
------- Block Diagram
------- Product Dependencies
1. I/O Lines
우리는 I/O Lines를 사용하지 않을 것이라서 넘어감.
2. Power Management
TC 장치를 켜야 사용 가능하므로 PMC를 사용한다.
3. Interrupt
TC 는 인터럽트가 필수다.
------- 소스
--- tc.c
--- main.c
문제점.
지금은 고쳤지만 처음엔 아래와 같이 소스를 짰었다.
--- tc.c
이 소스로 하니 타이머가 똑바로 동작하지 않았다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140717 (ARM Ultrasonic 초음파 모듈) (0) | 2014.07.17 |
---|---|
20140716 (ARM 초음파 모듈, Ultrasonic) (0) | 2014.07.16 |
20140714 (ARM Interrupt로 LED 켜기) (0) | 2014.07.14 |
20140708 (ARM DBGU UART 통신) (0) | 2014.07.08 |
20140707 (ARM LCD) (0) | 2014.07.07 |