-> 여기서 로컬 루프백은 잘못된 것이고 정상모드로 설정한다.
Net Card에도 루프백이 적용된다. 연결주소를 127.0.0.1로 하면
외부로 나가는 것이 아니라 자기한테 다시 돌아온다.
->CHMODE 14 - 00정상모드 ,PAR 9 - 1XX(패리티를 사용하지 않음)
6.
-> TXEN : 0 - 무효, 1 - 송신부의 동작을 허용한다.
RXEN: 0 - 무효, 1 - 수신부의 동작을 허용한다.
세련된 표현으로 (1<<4) | (1<<6) 좀 더 세련된 표현 (1<<TXEN) | (1<<RXEN) 으로 표현.
7.8
-> TRXDY
0 = 송신버퍼에 문자가 들어있거나 송신부가 금지되어 있다.
1 = 송신버퍼에 문자가 들어있지 않아 송신문자의 라이트가 가능하다.
RXRDY
0 = 수신버퍼에 문자가 들어있거나 송신부가 금지되어 있다.
1 = 수신버퍼에 문자가 들어있지 않아 송신문자의 라이트가 가능하다.
그러므로 여기서는 masking을 통해 알고 싶은것만 1로 셋팅한다.
while(0==DBGU_SR & 0x00000002) ; -> 세미콜론으로 아무것도 안하고 묶어두게 된다. 언제까지?
1이 될때까지 값이 0이 아닌 1이면되면 수행하게 해준다.
좀 더 세련된 표현 DBGU_SR & (1<<1); 좀더 고상하게 DBGU_SR & (1<<TXRDY);
예제) 시리얼 통신을 이용해 한 글자가 아닌 문자열을 출력시킨다.(단 새로운 변수는 생성하지 않는다)
while (0 =! (unsigned char *) upData)
에제2) PIOA에 0번 포트 LED를 키보드를 이용하여 1번을 누를때 마다 토글되게 한다.
-> 기본적인 방법에는 전역변수, static를 이용할 수 있지만 여기서는 PIOA계열 status register을 이용하여 토굴 시킨다.
-예제2) 소스보기 접기
#include "PIOA.h"
#include "lcd.h"
#define RX_PIN 9 //수신용 pin [ 송수신용으로 사용할 주변장치 pin ]
#define TX_PIN 10 //송신용 pin
#define LED_PIN 0 //LED pin
#define RSTRX 2 //Reset recever [디버그 유닛의 Control Registor 비트 ]
#define RSTTX 3 //Reset transmitter
#define RXEN 4 //recever Enable
#define TXEN 6 //transmitter Enable
// [디버그 유닛의 Status Registor 비트]
#define TXRDY 1 //transmitter Ready (송신 버퍼 = DBGU_THR 레지스터 문자 있는지)
#define RXRDY 0 //receiver Ready (수신 버퍼 = DBGU_RHR 레지스터 문자 있는지)
#define CHMODE 14 //채널 모드 설정 [디버그 유닛의 Mode Resigtor 비트]
#define PAR 9 // 패리티 모드 설정
#define DBG_PID 1 //디버그 유닛 PID = 1
#define PIO_PID 1 //디버그 유닛 PID = 1
#define MCK 48000000
#define B_RATE 115200
#define BR_CD (MCK/(B_RATE*16 )) // 보레이트 Clock Divisor 값 , (보페이트 = MCK/(16*CD))
/* ---------전원 레지스터 ----------------------------------*/
//#define PMC_MCKR (*(volatile unsigned int*)0xFFFFFC30) //MCK 공급????????????????필요한지??
//#define PMC_PCER (*(volatile unsigned int*)0xFFFFFC10) //peripheral 전원 공급
/* ---------USART 레지스터 ----------------------------------*/
#define DBGU_CR (*(volatile unsigned int *)0x FFFFF200) //control registor
#define DBGU_IDR (*(volatile unsigned int *)0x FFFFF20C) //interrupt disable
#define DBGU_BRGR (*(volatile unsigned int *)0x FFFFF220) //boud rate generator
#define DBGU_MR (*(volatile unsigned int *)0x FFFFF204) //mode
#define DBGU_SR (*(volatile unsigned int *)0x FFFFF214) //status
#define DBGU_THR (*(volatile unsigned int *)0x FFFFF21C) //tx holding = 송신 버퍼
#define DBGU_RHR (*(volatile unsigned int *)0x FFFFF218) //rx holding = 수신 버퍼
/*---------------------------------------------------------*/
void DBGU_INIT(void );
void Send_Char(unsigned char usSData);
unsigned char Recv_Char();
void Send_String(void *vpdata);
void LED_INIT(void );
void ONE(void )
{
if ( 0 != (PIOA_ODSR & (1 < < LED_PIN)) ) //PDSR ???
{
PIOA_CODR= 1 < < LED_PIN;
}
else
{
PIOA_SODR= 1 < < LED_PIN;
}
}
void ONE(void )
{
Send_String("hello" );
}
int main(void )
{
unsigned char usSData;
// LCD_INIT();
DBGU_INIT();
LED_INIT();
while (1 )
{
Send_String("...send!!!" );
usSData= Recv_Char();
switch ( usSData)
{
case 1 :
one();
break ;
case 2 ;
two();
break ;
}
}
/*
LCD_INST(CLCD_INST_FS); // Funsion set
LCD_INST(CLCD_INST_EM); // Entry mode
LCD_INST(CLCD_INST_CS); // cursor shitf
LCD_INST(CLCD_INST_DO); // display on
LCD_INST(CLCD_INST_CD); //clear display
LCD_INST(CLCD_INST_DD); //DDRAM address set
LCD_INST(CLCD_INST_RH); // return home
LCD_DATA('A'< < 16);
while(1)
{
for(usSData= 'a';'z'> usSData;usSData++)
{
Send_Char(usSData);
usSData= Recv_Char();
if(0 != usSData)
{
LCD_DATA(usSData< < 16);
//커서 세팅...??
}
}
}
*/
return 0 ;
}
void DBGU_INIT(void )
{
// PMC_PCER = 1< < PIO_PID; //PIO 전원 공급 -- ?????????????????
// PMC_MCKR = 1< < DBG_PID; //DBGU 전원 공급 -- ?????????????????
DBGU_CR = (1 < < RSTTX) | (1 < < RSTRX); //송수신부 리셋 & 비활성.
DBGU_IDR = 0x FFFFFFFF; //디버그 유닛 인러럽트 모두 끄기 (인터럽트 신호발생으로 소스함수 실행등 방해 받지 않게...)
PIOA_ASR = (1 < < RX_PIN) | (1 < < TX_PIN); // 9,10번 핀 송수신에 사용 (주변장시 신호 모드 중 A 사용)
PIOA_BSR = (0 < < RX_PIN) | (0 < < TX_PIN); //(주변장치 보드 중 B 비활성) 0입력 or생략 가능
PIOA_PDR = (1 < < RX_PIN) | (1 < < TX_PIN); // PIO mode 비활성 (= 주변장치 모드 사용)
DBGU_BRGR = BR_CD; //보레이트 설정 (115200 bps)
DBGU_MR = (0 < < CHMODE) | (4 < < PAR); //모드 설정 (채널-정상모드 ,패리티- 없음)
DBGU_CR = (1 < < TXEN) | (1 < < RXEN); //송수신부 활성.
return ;
}
void Send_Char(unsigned char usSData)
{
while ( 0 = = (DBGU_SR & (1 < < TXRDY)) ); // 수신준비 비트가 1이면 (수신버퍼 비어있으면..
//= while( 0= = (DBGU_SR & (0x00000002) );
DBGU_THR= usSData; // 문자 수신
return ;
}
unsigned char Recv_Char()
{
while (0 = = (DBGU_SR & (1 < < RXRDY))); //송신준비 비트가 1이면 (송신버퍼가 차있으면 )
return (unsigned char )(DBGU_RHR) ;
}
void Send_String(void *vpdata)
{
while ( 0 != *((unsigned char *)vpdata) ) //문자열의 마지막까지 한문자씩 전송.
{
Send_Char(*(unsigned char *)vpdata);
vpdata= ((unsigned char *)vpdata)+1 ;
}
return ;
}
void LED_INIT(void )
{
PIOA_OER= 1 < < LED_PIN;
PIOA_PER= 1 < < LED_PIN;
PIOA_PPUDR= 1 < < LED_PIN;
PIOA_CODR= 1 < < LED_PIN;
return ;
}
접기
리소스
일반적으로 프로그램은 코드와 데이터로 구성된다. 데이터는 프로그램의 처리 대상이며 코드는 데이터를 처리하는 수단이다. 데이터의 의미를 확장하여 코드가 아닌 모든 것을 데이터라고 할 때 비트맵, 아이콘, 메뉴, 문자열 등등 프로그램의 논리와 무관한 모든 것들이 데이터에 속한다. 도스 프로그래밍에서는 이런 데이터를 만들고 관리하는 작업이 하나의 과정에 통합되어 있지만 윈도우즈 프로그래밍에서는 별도의 작업 과정으로 분리되어 있다. 코드의 논리와 무관한 데이터들을 리소스(Resource)라고 하며 메뉴, 비트맵, 액셀러레이터, 문자열, 아이콘, 커서 등등이 여기에 속한다. 이런 리소스들은 별도의 편집기로 만들어져 컴파일시에 실행파일에 결합된다.
메뉴 리소스 만들기
1. 먼저 새로운 프로젝트를 생성한다.
2.생성된 프로젝트에 기존에 수업했던 파일을 다음과 같이 ADD시켜준다.
main.cpp 소스보기 접기
//main.cpp
#include < windows.h>
#include "Msgproc.h" //add
#include "resource.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("Menu" );
HDC hdc;
PAINTSTRUCT ps;
//add
typedef struct MWSSAGEMAP
{
UINT iMessage;
LRESULT(*lpfnMsgProc)(HWND,WPARAM,LPARAM);
}MESSAGEMAP;
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= MAKEINTRESOURCE(IDR_MENU1);
WndClass.style= CS_HREDRAW| CS_VREDRAW;
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,0 ,0 ,0 )) {
TranslateMessage(& Message);
DispatchMessage(& Message);
}
return (int )Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
//add
int i;
static MESSAGEMAP MessageMaps[]= {
{WM_CREATE,OnCreate},
{WM_COMMAND,OnCommand},
{WM_LBUTTONDOWN,OnLButtonDown},
{WM_PAINT,OnPaint},
{WM_DESTROY,OnDestroy}
};
for (i= 0 ;i< sizeof (MessageMaps)/sizeof(MessageMaps[0 ]);i++)
{
if (MessageMaps[i].iMessage= = iMessage)
return (*MessageMaps[i].lpfnMsgProc)(hWnd,wParam,lParam);
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
접기
MasProc.cpp소스보기 접기
//MsgProc.cpp
#include "MsgProc.h"
#include "resource.h"
LRESULT OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
return 0 ;
}
LRESULT OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
switch (LOWORD(wParam))
{
case ID_FILE_MENU1:
MessageBox(hWnd,TEXT("첫 번째 메뉴 선택" ),TEXT("Menu Demo" ),MB_OK);
break ;
case ID_FILE_MENU2:
MessageBox(hWnd,TEXT("두 번째 메뉴 선택" ),TEXT("Menu Demo" ),MB_OK);
break ;
case ID_FILE_EXIT:
DestroyWindow(hWnd);
break ;
}
return 0 ;
}
LRESULT OnLButtonDown(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
return 0 ;
}
LRESULT OnDestroy(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
PostQuitMessage(0 );
return 0 ;
}
LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd,& ps);
EndPaint(hWnd,& ps);
return 0 ;
}
접기
MsgProc.h 소스보기 접기
#ifndef __MSGPROC_H_
#define __MSGPROC_H_
#include < windows.h>
LRESULT OnLButtonDown(HWND,WPARAM,LPARAM);
LRESULT OnDestroy(HWND,WPARAM,LPARAM);
LRESULT OnCommand(HWND,WPARAM,LPARAM);
LRESULT OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam);
LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam);
extern HINSTANCE g_hInst;
extern HDC hdc;
extern PAINTSTRUCT ps;
#endif
접기
3.다음과 같이 menu.rc파일을 생성 시켜준다.
4.아래와 같이 menu폴더가 생성되게 되는데 거기서 오른쪽을 클릭하여 insert해준다.
5.MENU프로젝트로 가서 더블클릭하면 아래와 같은 창이 뜬다.
6.메뉴를 편집할 수있는 창으로 가장상위인 File을 만들어 준다.
7.하위메뉴도 똑같이 해서 Menu1,Menu2,Exit도 만둘어준다.(ID도 만들어 줘야되는 것을 잊지말자)
8.여기까지 끝나면 build를 한번해준다. 그러면 다음과 같이 resource.h파일이 디렉토리에 생성된 것을 볼 수 있다.
9. MsgProc.cpp에 다음 파일을 추가 시킨뒤 실행한다.
<실행결과>