728x90

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

+ Recent posts