ATmega128 포트가 범용 디지털 I/O로 사용될 경우, Read-Modify-Write 기능을 수행할 수 있음
: I/O포트 입출력 변경하지않고도 동시에 입력과 출력의 기능을 수행할 수 있다.
입출력 방향의 변경없이 포트의 동작 방향이 달라질 수 있음
DDRx 레지스터 : 입출력의 방향을 설정, 각 비트를 1로 설정하면 출력, 0으로 설정하면 입력으로 결정
0 : PORTxn = 입력 -> 입력된 데이터가 PINxn에 저장.
1 : PORTxn = 출력 -> PORTxn의 데이터가 출력됨.
PORTx 레지스터 : 데이터 출력
PINx 레지스터 : 포트 입력 핀, 읽기만 가능하고 쓰기 불가
ATmega128에서 PORTG는 5개의 비트만 사용 (다른 PORT는 0-7까지 8개의 비트 사용)
Atmel/avr tools/avr toolchain/avr/include/avr/iom128.h
/io.h
에서 SFR 등 비트 정의를 볼 수 있다.
PORT초기화 예)
DDRB = 0xFF; // 포트 B 출력 설정
PORTB = 0x00; // 출력 0 설정
DDRD = 0x00; // 포트 D 입력 설정
PORTD = 0x00; // 포트 D 내부 풀업 저항을 사용하기 위해 0으로 설정
SFIOR |= 1<<2; // PUD 비트 1로 설정(풀업 저항 사용안함)
SFIOR의 PUD(Pull-up Disable) 비트를 1로 설정하면 ATmega128 내부에 있는 풀업저항을 사용하지 않는것이고
PUD를 0으로 설정하면 내부 풀업저항을 사용하는 것이다.
SFIOR의 PUD 비트의 초기값은 0으로 되어 있기 때문에 이 레지스터를 설정하지 않으면 내부 풀업저항을 사용하도록 설정되는 것과 같다.
WIn32 API 수업
// 그림판
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("Text Out 124"); // Title 명
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
while (GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT pa;
static int x = 100;
static int y = 100;
static int a = 0;
static BOOL bNowDraw = FALSE;
switch (iMessage)
{
case WM_DESTROY:
PostQuitMessage(0); // 종료
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &pa);
TextOut(hdc, x, y, TEXT("A"), 1);
EndPaint(hWnd, &pa);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_LEFT:
x -= 8;
break;
case VK_RIGHT:
x += 8;
break;
case VK_UP:
y -= 8;
break;
case VK_DOWN:
y += 8;
break;
case VK_SPACE:
a++;
a %= 2;
break;
}
InvalidateRect(hWnd, NULL, FALSE);
return 0;
case WM_LBUTTONDOWN:
x = LOWORD(lParam);
y = HIWORD(lParam);
bNowDraw = true;
return 0;
case WM_MOUSEMOVE:
if (bNowDraw == TRUE)
{
hdc = GetDC(hWnd);
MoveToEx(hdc, x, y, NULL);
x = LOWORD(lParam);
y = HIWORD(lParam);
LineTo(hdc, x, y);
ReleaseDC(hWnd, hdc);
}
return 0;
case WM_LBUTTONUP:
bNowDraw = FALSE;
return 0;
case WM_LBUTTONDBLCLK:
MessageBox(hWnd, TEXT("더블클릭"), TEXT("메세지박스"), MB_YESNO);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
// 타이머
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("Timer"); // Title 명
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, 300, 400, 400, 300, NULL, (HMENU)NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
while (GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT pa;
SYSTEMTIME st;
static TCHAR sTime[128];
switch (iMessage)
{
case WM_CREATE:
SetTimer(hWnd, 1, 1000, NULL);
return 0;
case WM_TIMER:
GetLocalTime(&st);
wsprintf(sTime, TEXT("지금 시간은 %d:%d:%d입니다."), st.wHour, st.wMinute, st.wSecond);
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case WM_DESTROY:
PostQuitMessage(0); // 종료
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &pa);
TextOut(hdc, 100, 100, sTime, lstrlen(sTime));
EndPaint(hWnd, &pa);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
// 3초에 한번 덧셈문제 출제
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("Timer"); // Title 명
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, 300, 400, 400, 300, NULL, (HMENU)NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
while (GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT pa;
SYSTEMTIME st;
static TCHAR sTime[128];
int a = rand() % 30;
int b = rand() % 30;
switch (iMessage)
{
case WM_CREATE:
SetTimer(hWnd, 1, 3000, NULL);
return 0;
case WM_TIMER:
GetLocalTime(&st);
wsprintf(sTime, TEXT("%d+%d=?"), a, b);
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case WM_DESTROY:
KillTimer(hWnd, 1);
PostQuitMessage(0); // 종료
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &pa);
TextOut(hdc, 100, 100, sTime, lstrlen(sTime));
EndPaint(hWnd, &pa);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
'Study > Embedded' 카테고리의 다른 글
아두이노 기초 (0) | 2017.05.25 |
---|---|
ATMEGA USART-C# App 연동 (0) | 2016.12.12 |
7/8 LCD제어2 (0) | 2016.07.08 |
7/5 LCD 제어 (0) | 2016.07.05 |
5/26 업무일지 PC PWM을 이용한 LED 밝기 조절 (0) | 2016.05.26 |