AT91SAM7S256을 이용한 UART 통신설정
PIOA.h (진한부분이 새로 추가한 부분입니다.)
#ifndef __PIOA_H__
#define __PIOA_H__
#define PIOA_PER (*(volatile unsigned int *)0xFFFFF400) // Pin enable
#define PIOA_OER (*(volatile unsigned int *)0xFFFFF410) // output enable
#define PIOA_PPUDR (*(volatile unsigned int *)0xFFFFF460) // pull-up resistance disable
#define PIOA_CODR (*(volatile unsigned int *)0xFFFFF434) // 대입하면 0 - clear ouput data
#define PIOA_SODR (*(volatile unsigned int *)0xFFFFF430) // 대입하면 1 - set output data
#define PIOA_ODR (*(volatile unsigned int *)0xFFFFF414) //PIO output Disable Register
#define PIOA_IFER (*(volatile unsigned int *)0xFFFFF420) //PIO Glitch Register
#define PIOA_IER (*(volatile unsigned int *)0xFFFFF440) //PIO Glitch Register
#define PIOA_ISR (*(volatile unsigned int *)0xFFFFF44C)//몇번에 인터럽트가 발생하恙눼쩝� 알수 揚獵�.
#define PIOA_ODSR (*(volatile unsigned int *)0xFFFFF438)//출력 데이터 상태 레지스터
#define PIOA_IDR (*(volatile unsigned int *)0xFFFFF444)//인터럽트 금지 레지스터
#define PIOA_ASR (*(volatile unsigned int *)0xFFFFF470)//주변장치 A 선택 레지스터
#define PIOA_BSR (*(volatile unsigned int *)0xFFFFF474)//주변장치 B 선택 레지스터
#define PIOA_PDR (*(volatile unsigned int *)0xFFFFF404)//병렬 입출력 금지 레지스터
#endif
main.c
#include "PIOA.h"
#define DBGU_CR (*(volatile unsigned int*)0xFFFFF200) //DBGU 제어 레지스터 (송/수신부)
#define DBGU_IDR (*(volatile unsigned int*)0xFFFFF20C) //DBGU 금지 레지스터 (관련 인터럽터 비활성화)
#define DBGU_BRGR (*(volatile unsigned int*)0xFFFFF220) //DBGU 보레이트 발생 레지스터 (포트속도 설정)
#define DBGU_MR (*(volatile unsigned int*)0xFFFFF204) //DBGU 모드 레지스터 (포트모드 설정)
#define DBGU_SR (*(volatile unsigned int*)0xFFFFF214) //DBGU 상태 레지스터
#define DBGU_THR (*(volatile unsigned int*)0xFFFFF21C) //DBGU 송신 홀딩 레지스터
#define DBGU_RHR (*(volatile unsigned int*)0xFFFFF218) //DBGU 수신 홀딩 레지스터
#define RSTRX 2
#define RSTTX 3
#define DRXD 9
#define DTXD 10
#define RXEN 4
#define TXEN 6
#define PAR 9
#define CHMODE 14
#define TXRDY 1
#define RXRDY 0
#define MCK 48000000
#define BORETE 115200
#define CD (MCK/(16*BORETE))
void Usart_init()
{
DBGU_CR = (1<<RSTRX| 1<<RSTTX); //송수신부를 리셋, 동작중지
DBGU_IDR = 0xFFFFFFFF; //모든 레지스터 1로 설정
PIOA_ASR = (1<<DRXD | 1<<DTXD); //PA9, PA10 핀 Peripheral A활성화
PIOA_BSR = 0x00000000; //모든 Peripheral B 비활성화
PIOA_PDR = (1<<DRXD | 1<<DTXD); //PA9, PA10 핀 Peripheral A비활성화
DBGU_BRGR = CD; //cd값 26, MKC = 48MHz
DBGU_MR = (0<<CHMODE | 4<<PAR); //포트모드설정(로컬루프백, 패리티 X)
DBGU_CR = (1<<RXEN | 1<< TXEN); //송수신 활성화
return;
}
void Send_Char(unsigned char usSData) //Data 송신용 함수
{
while (0 == ((DBGU_SR) & (1<<TXRDY))); //(TXRDY 실시간 1확인)
DBGU_THR = usSData;
return;
}
unsigned char Recv_Char() //Data 수신용 함수
{
unsigned char usSData = 0;
while (0 == ((DBGU_SR) & (1<<RXRDY)));
usSData = DBGU_RHR;
return usSData;
}
int main(void)
{
unsigned char buff;
Usart_init();
Send_Char('A');
Send_Char('K');
Send_Char('I');
Send_Char('H');
Send_Char('O');
while(1)
{
buff = Recv_Char();
Send_Char(buff);
}
while(1);
return 0;
}
1. 송/수신부를 리셋 시키고 동작을 중지시킴
DBGU_CR 레지스터의 AT91C_US_RSTRX, AT91C_US_RSTTX 비트를 1로 설정
BGU_CR = (1<<RSTRX| 1<<RSTTX);
2. 관련 인터럽터의 비활성화
DBGU_IDR 레지스터의 모든 비트를 1로 설정
DBGU_IDR = 0xFFFFFFFF;
3. DBGU의 외부 연결용 Pin 설정
아래 그림은 AT91SAM7S의 스펙의 36Page에서 발췌한 부분입니다. 자세히 보면
Peripheral A에 속해 있고 PA 9, 10번 핀에 대해서 설정해야 한다는 것을 알 수
있음.
정리해 보면 PA9, 10번 핀을 Peripheral A 모드 활성화, 그에따라 Peripheral B
는 당연히 비활성화, 그리고 LED를 점둥할 때 쓰이는 병렬 I/O 포트 비활성화 등
3가지 동작이 이루어 져야 함.
3-1. PA9, 10번 핀의 Peripheral A 모드 활성화
PIO_ASR 레지스터의 AT91C_PA9_DRXD, AT91C_PA10_DTXD 비트를
1로 설정
PIOA_ASR = (1<<DRXD | 1<<DTXD);
3-2. PA9, 10번 핀의 Peripheral B 모드 비활성화
PIO_BSR 레지스터의 모든 비트를 0로 설정
PIOA_BSR = 0x00000000;
3-4. PA9, 10번 핀의 병렬 I/O 포트 모드 비활성화
PIO_PDR 레지스터의 AT91C_PA9_DRXD, AT91C_PA10_DTXD
PIOA_PDR = (1<<DRXD | 1<<DTXD);
4. 포트 속도 설정
DBGU_BRGR 레지스터에 115200 bps로 설정
DBGU_BRGR = CD;
5. 포트 모드 설정(정상모드, 패리티 없음)
DBGU_MR 레지스터에
AT91C_US_CHMODE_LOCAL, AT91C_US_PAR_NONE 비트를 1로 설정
DBGU_MR = (0<<CHMODE | 4<<PAR);
6. 송/수신 모드 활성화
DBGU_CR 레지스터의 AT91C_US_TXEN, AT91C_US_RXEN 비트를 1로 설정
DBGU_CR = (1<<RXEN | 1<< TXEN);
7. Data 송신용 함수의 제작 : void Send_Char(unsigned char usSData)
7-1. 폴링 방식으로 제작
7-2. DBGU_SR 레지스터 폴링
AT91SAM7S의 스펙 253Page 참조.
실시간으로 TXRDY 비트가 1로 설정되었는지 확인.
이 비트는 디버그 유닛이 전송 준비가 되면 1로 설정되므로
확인 즉시 1byte를 전성하면 시리얼 통신 포트로 문자가 전송
되게 됨. 여기서 주의 해야 할 것은 ATMEL사가 DBGU_SR
레지스터를 제공한 헤더파일에서는 DBGU_CSR로 해 놓았다는
것. 이유는 모르겠으나 이점을 유의해서 프로그램을 작성해야 함.
7-3. DBGU 유닛에 문자 전송
AT91SAM7S의 스펙 255Page를 참조.
DBGU_THR 레지스터에 char Data를 직접 쓰면 1Byte 시리얼 전송이
이루어 지게 됨.
void Send_Char(unsigned char usSData) //Data 송신용 함수
{
while (0 == ((DBGU_SR) & (1<<TXRDY))); //(TXRDY 실시간 1확인)
DBGU_THR = usSData;
return;
}
8. Data 수신용 함수의 제작 : unsigned char Recv_Char()
8-1. 폴링 방식으로 제작
8-2. DBGU_SR 레지스터 포링
송신 함수 제작과 마찬가지로 AT91SAM7S의 스펙 253Page를
참조하면서 작성.
실시간으로 RXRDY 비트가 1로 설정되었으면 1byte를 수신하면
시리얼 통신 포트로 1Byte가 수신된 것 임.
8-3. DBGU 유닛으로부터의 Byte 수신
AT91SAM7S의 스펙 255Page를 참조.
DBGU_RHR 레지스터에서 읽어 들이면 쓰면 시리얼 통신을 통해
1Byte를 실질적으로 수신 되게 됨.
unsigned char Recv_Char() //Data 수신용 함수
{
unsigned char usSData = 0;
while (0 == ((DBGU_SR) & (1<<RXRDY)));
usSData = DBGU_RHR;
return usSData;
}
9. 하이퍼터미널로 값을 넣었을 때 반응
int main(void)
{
unsigned char buff; //임시저장 변수
Usart_init();
Send_Char('A'); //하이퍼터미널에 내가 원하는 문자를 전송
Send_Char('K');
Send_Char('I');
Send_Char('H');
Send_Char('O');
while(1)
{
buff = Recv_Char();
Send_Char(buff);
}
while(1);
return 0;
}
API 예제
//main.cpp
#include <windows.h>
#include "MsgProc.h" //add
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE f_hInst;
LPCTSTR lpszClass = TEXT("First");
//add
typedef struct MESSAGEMAP
{
UINT iMessage;
LRESULT (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
} MESSAGEMAP;
////////////////////////////////////
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message; //MSG 구조체 사용
WNDCLASS WndClass; //WNDCLASS 구조체 사용
g_hInst=hInstance; //이 윈도클래스를 등록하는 프로그램의 번호
/*WndClass 정의(윈도우의 기반이 되는 클래스를 정의한다. 즉, 만들고자 하는 윈도우의 속성을 정의)*/
WndClass.cbClsExtra = 0; //예약 영역, 사용하지 않을 경우 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; //윈도우 스타일 정의
/*윈도우 클래스 등록*/
RegisterClass(&WndClass);
/*메모리상에 윈도우 생성*/
hWnd=CreateWindow(lpszClass, /*타이틀바문자열*/TEXT("My First Program"), /*윈도우스타일*/WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
/*윈도창위치*/300, /*윈도창위치*/400, /*폭*/CW_USEDEFAULT, /*높이*/CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance,NULL);
//(윈도클래스이름,타이틀바에나타날문자열,윈도우스타일,CW사용하면 운영체제가 화면크기에 맞게 알아서 조절, ....)
ShowWindow(hWnd, nCmdShow); //CreateWindow함수가 리턴한 핸들을 이용하여 출력(윈도우를 화면에 표시)
/*사용자로부터의 메시지 처리(메시지 루프)*/
while(GetMessage(&Message, NULL, 0, 0)) //메시지 큐에서 읽어옴
{ //GetMessage가 WM_QUIT면 False리턴
TranslateMessage(&Message); //키보드 입력 처리
DispatchMessage(&Message); //큐에서 꺼낸 메시지를 WndProc함수의 iMessage로 전달
}
return(int)Message.wParam; //메시지 루프 종료후 이 프로그램을 실행시킨 OS로 리턴
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{ //운영체제가 호출하는 함수는 CALLBACK 표시, LRESULT = 4바이트 long
//add
int i;
static MESSAGEMAP MessageMaps[] = {
{WM_CREATE, OnCreate},
{WM_COMMAND, OnCommand},
{WM_LBUTTONDOWN, OnLButtonDown},
{WM_PAINT, OnPaint},
{WM_DESTORY, 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));
}
//MsgProc.cpp
#include "MsgProc.h"
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PostQuitMessage(0);
return 0;
}
//MsgProc.h
#ifndef __MSGPROC_H_
#define __MSGPROC_H_
#include <windows.h>
LRESULT OnCreate(HWND, WPARAM, LPARAM);
LRESULT OnCommand(HWND, WPARAM, LPARAM);
LRESULT OnLButtonDown(HWND, WPARAM, LPARAM);
LRESULT OnPaint(HWND, WPARAM, LPARAM);
LRESULT OnDestroy(HWND, WPARAM, LPARAM);
extern HINSTANCE g_hInst;
#endif
API는 일단 예제만.....
'코스웨어 > 11년 내장형하드웨어' 카테고리의 다른 글
[내장형]심재원_2011년09월08일 (10) | 2011.09.08 |
---|---|
[내장형]이수란_2011년9월7일 (9) | 2011.09.07 |
[내장형]김동화_2011년_9월6일_일일보고서 (17) | 2011.09.06 |
[내장형]최남식-2011년9월5일 일일보고서 (11) | 2011.09.06 |
AT91SAM7S의 USART(DBGU) (0) | 2011.09.02 |
[내장형]이성재 2011년 9월1일 일일보고서 (15) | 2011.09.01 |
[내장형]김수만_일일보고서 2011년 8월 31일 (14) | 2011.09.01 |
[내장형]이상만_2011년 8월 30일_일일보고서 (9) | 2011.08.30 |