★ ADC 컨버터 를 이용하여 캐릭터 LCD에 값 출력
ㆍ광센서를 AD7에 연결하고 반대쪽은 그라운드에 연결하였다.
ㆍLED는 14핀에 그라운드를 연결하고 반대쪽은 3.3v 에 연결
ㆍ광센서의 최대값은 1023으로 설정
ㆍ캐릭터 LCD 는 실시간으로 광센서의 빛의 밝기를 출력한다.
ㆍ밝은 빛을 비추면 최대값인 1023을 출력한다.
ㆍLED는 광센서값이 700이하이면 꺼지도록 하였다. (어두우면 꺼짐)
Ex) main.c |
#include "arm.h" #include "led.h" #include "aic.h" #include "ultra.h" #include "lcd.h" #include "dbgu.h" #include "adc.h"
void Init(void);
int main() { volatile unsigned int dly; unsigned char buff[] = "[1023]"; unsigned int UI_val; Init();
while(1) { UI_val = ADC_Run(); buff[1] = '0' + (UI_val/1000); // 1023 의 1 추출 buff[2] = '0' + ((UI_val%1000)/100); // 1023 의 0 추출 buff[3] = '0' + ((UI_val%100)/10); // 1023 의 2 추출 buff[4] = '0' + (UI_val%10); // 1023 의 3 추출 LCD_Position(00); LCD_String(buff); EMB_delay(100000);
if(UI_val > 700) { PIO_CODR = 1 << LED_Pin; } else { PIO_SODR = 1 << LED_Pin; } }
while(1); return 0; }
void Init(void) { Init_LED(); init_LCD(); Init_ADC(); return ; } |
Ex) LED |
#define LED_Pin 14 // LED Pin Number void Init_LED(void) { PMC_PCER = 1 << PIOA; PIO_OWER = 1 << LED_Pin; PIO_PER = 1 << LED_Pin; PIO_OER = 1 << LED_Pin; PIO_SODR = 1 << LED_Pin; return ; } |
Ex) LCD |
#define LCD_RS (1<<29) #define LCD_RW (1<<30) #define LCD_EN (1<<31) #define LCD_BS 0x00FF0000 #define LCD_ALL (LCD_RS | LCD_RW | LCD_EN | LCD_BS) #define RETURN_Home 0x02 /* LCD 데이터 버스 메크로 */ #define LCD_DB(x) ((x)<<(16)) #define LCD_Delay1 510 #define LCD_Delay2 510 #define LCD_Delay3 510
#define Function_set 0x38 // Function set #define Entry_Mode 0x06 // Entry Mode #define Cursor_Dis 0x1C // Cursor or display shift #define Display_on_off 0x0C // Display on/off #define Clear_Dis 0x01 // Clear void init_LCD(void) { PMC_PCER = 1 << PIOA; PIO_OWER = LCD_ALL; // I/O 기능 선택 PIO_PER = LCD_ALL; // pin 활성화 PIO_OER = LCD_ALL; // IO 출력 기능 활성화 LCD_Init();
return ; }
void LCD_Init(void) { LCD_inst(Function_set); LCD_inst(Entry_Mode); LCD_inst(Cursor_Dis); LCD_inst(Display_on_off); LCD_inst(Clear_Dis); LCD_inst(RETURN_Home);
return; } void LCD_inst(unsigned char UC_inst) { volatile unsigned int dly; PIO_CODR = LCD_ALL; // LCD_ALL 을 Low 로 변환 한다. PIO_SODR = LCD_EN; // LCD_EN(E)만 Hight 엣지상태로 만든다. EMB_delay(LCD_Delay1); PIO_SODR = LCD_DB(UC_inst); EMB_delay(LCD_Delay2); // t_AS : 40 ns min 정도의 시간을 번다. PIO_CODR = LCD_EN; // LCD_ALL 을 Low 로 변환 한다. EMB_delay(LCD_Delay3);
return ; } |
Ex) ADC |
#define ADC_CR *((volatile unsigned int *)0xFFFD8000) #define ADC_MR *((volatile unsigned int *)0xFFFD8004) #define ADC_CHER *((volatile unsigned int *)0xFFFD8010) #define ADC_CHDR *((volatile unsigned int *)0xFFFD8014) #define ADC_CHSR *((volatile unsigned int *)0xFFFD8018) #define ADC_SR *((volatile unsigned int *)0xFFFD801C) #define ADC_LCDR *((volatile unsigned int *)0xFFFD8020) #define ADC_IER *((volatile unsigned int *)0xFFFD8024) #define ADC_IDR *((volatile unsigned int *)0xFFFD8028) #define ADC_IMR *((volatile unsigned int *)0xFFFD802C) #define ADC_CDR0 *((volatile unsigned int *)0xFFFD8030) #define ADC_CDR1 *((volatile unsigned int *)0xFFFD8034) #define ADC_CDR2 *((volatile unsigned int *)0xFFFD8038) #define ADC_CDR3 *((volatile unsigned int *)0xFFFD803C) #define ADC_CDR4 *((volatile unsigned int *)0xFFFD8040) #define ADC_CDR5 *((volatile unsigned int *)0xFFFD8044) #define ADC_CDR6 *((volatile unsigned int *)0xFFFD8048) #define ADC_CDR7 *((volatile unsigned int *)0xFFFD804C) //================================================================= #define ADC_ID 4 // ADC 활성 ID ( 기본적으로 켜져있다. ) #define SWRST 0 // Software Reset #define START 1 // Start Conversion( 변환 > #define CH7 7 // 7번 체널 //[ ADC Mode Register ]============================================ #define TRGEN 0 #define TRGSEL 0 #define LOWRES 4 #define SLEEP 5 #define PRESCAL 8 #define STARTUP 16 #define SHTIM 24 //[ ADC_SR ]======================================================= #define EOC7 7 #define DRDY 16 //[ ADC_LCDR ]===================================================== #define LDATA 0 void Init_ADC(void) { PMC_PCER = 1 << ADC_ID; // PIOA ON : by PMC ADC_CR = 0x01; ADC_CHER = 1 << CH7; // 7번 체널 Enable ADC_MR = (5 << PRESCAL)|(LOWRES); // 4MHz : 10bit reg return ; }
//< ADC_CR Start >================================================= unsigned int ADC_Run(void) { ADC_CR = 1 << START; while(0 == (ADC_SR & (1<<DRDY))); // DRDY 에 1을 추출 // while(0 == ADC_SR & (1<<EOC7)); // EOC7 에 1을 추출 return (ADC_LCDR&0x000003FF); // 10bit 이외의 미정값추출 // return (ADC_CDR7&0x000003FF); // 10bit 이외의 미정값추출 } |
< 실행 결과 동영상 참고 >
★ DOS 에서 하이퍼터미널 대체 프로그램 만들기
Ex) main.c |
#include "arm.h" #include "led.h" #include "aic.h" #include "ultra.h" #include "lcd.h" #include "dbgu.h" #include "adc.h"
void Init(void);
int main() { unsigned char UC_char;
Init(); while(1) { UC_char = DBGU_Rchar (); LCD_data(UC_char); } while(1); return 0; }
void Init(void) { init_LCD(); Init_DBGU(); return ; } |
Ex) Dos에서 만든 하이퍼 터미널 |
#include <windows.h> #include <stdio.h>
int main() { HANDLE hComm; char CA_string[] = "Hello"; DWORD DW_write; DCB sPS; // 씨리얼 포트 상태 저장 COMMTIMEOUTS cTime; volatile unsigned int dly = 0; volatile unsigned int cnt = 0;
// CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다. hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(INVALID_HANDLE_VALUE == hComm) { printf("Com port open Error !\n"); return 0; }
// 버퍼 설정 if( 0 == SetupComm(hComm, 4096, 4096)) { printf("Buffer setting Error !\n"); CloseHandle(hComm); return 0; }
/* * 포트 초기화 * DCB 구조체 사용 * 길이 * 속도 */ if( 0 == PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR)) { printf("Buffer initialization Error !\n"); CloseHandle(hComm); return 0; }
sPS.DCBlength = sizeof(sPS);
if( 0 == GetCommState(hComm, &sPS)) { printf("Port status read Error !\n"); CloseHandle(hComm); return 0; }
sPS.BaudRate = CBR_115200; // 비트,초 sPS.ByteSize = 8; // 데이터 비트 전송 sPS.Parity = EVENPARITY; // 짝수 sPS.StopBits = ONESTOPBIT; // 정지 비트
// 위 세팅값을 핸들에 넣어준다. if( 0 == SetCommState(hComm, &sPS)) { printf("Port status write Error !\n"); CloseHandle(hComm); return 0; }
while(1) { for(dly =0; dly < 10000000 ; dly++); WriteFile(hComm, &CA_string[cnt], sizeof(CA_string[cnt]), &DW_write, 0); cnt++; if(cnt == 5) { break; } }
printf("Com port open Success !\n"); CloseHandle(hComm); // 터미널은 닫아주어야한다.
return 0; } |
※ 딜레이를 꼭 해줘야함 !!!
★ Thread
ㆍThread 는 정보와 Stack 영역만 존재한다.
ㆍ시분할 시스템 :: P1(0.01) -> P2(0.01) -> T1(0.01) 다시 P1으로 돌아가서 계속 반복
ㆍThread 는 Procces 에 종속된다.
ㆍThread를 사용하면 멀티태스킹이 가능한 프로그램을 만들 수 있다.
ㆍThread 를 만들어주는 함수는 다음과 같다.
CreateThread( );
ㆍ하이퍼터미널은 COM2 포트를 사용하였고 프로그램에서는 COM5 포트를 사용하였다.
Ex) Thread 를 이용한 하이퍼 터미널 송/수신 |
#include <windows.h> #include <stdio.h>
DWORD WINAPI Thread_Read(LPVOID);
HANDLE hComm;
int main() { HANDLE hThread; char CA_string[] = "Hello"; DWORD DW_write; DWORD Thread_ID; DCB sPS; // 씨리얼 포트 상태 저장 COMMTIMEOUTS cTime; volatile unsigned int dly = 0;
// CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다. hComm = CreateFile("COM5", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(INVALID_HANDLE_VALUE == hComm) { printf("Com port open Error !\n"); return 0; }
// 버퍼 설정 if( 0 == SetupComm(hComm, 4096, 4096)) { printf("Buffer setting Error !\n"); CloseHandle(hComm); return 0; }
/* * 포트 초기화 * DCB 구조체 사용 * 길이 * 속도 */ if( 0 == PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR)) { printf("Buffer initialization Error !\n"); CloseHandle(hComm); return 0; }
sPS.DCBlength = sizeof(sPS);
if( 0 == GetCommState(hComm, &sPS)) { printf("Port status read Error !\n"); CloseHandle(hComm); return 0; }
sPS.BaudRate = CBR_115200; // 비트,초 sPS.ByteSize = 8; // 데이터 비트 전송 sPS.Parity = EVENPARITY; // 짝수 sPS.StopBits = ONESTOPBIT; // 정지 비트 memset(&cTime, 0x00, sizeof(cTime)); cTime.ReadIntervalTimeout = MAXDWORD; // 넌블럭킹 SetCommTimeouts(hComm, &cTime);
// 위 세팅값을 핸들에 넣어준다. if( 0 == SetCommState(hComm, &sPS)) { printf("Port status write Error !\n"); CloseHandle(hComm); return 0; } hThread = CreateThread(NULL, 0, Thread_Read, NULL, 0, &Thread_ID); // 쓰레드 생성
while(1) { CA_string[0] = getche(); WriteFile(hComm, CA_string, 1, &DW_write, 0); if( CA_string[0] == '*') { break; } } printf("Com port open Success !\n"); CloseHandle(hComm); // 터미널은 닫아주어야한다.
return 0; }
//< Thread 함수 호출 > DWORD WINAPI Thread_Read(LPVOID temp) { char cText; DWORD DW_read; volatile unsigned int cnt = 0; while(1) { Sleep(50); // CPU 점유율을 줄이기 위함 ReadFile(hComm, &cText, 1, &DW_read, 0); if(DW_read == 1) { putchar('['); putchar(cText); putchar(']'); } }
return 0;
} |
< 실행 결과 >
ㆍ입력(COM5)은 도스창에서 이루어지고 수신은 하이퍼터미널에서 이루어짐(COM2)
[ 송신 ]
[ 수신 ]
ㆍ위와 반대로 입력은 하이퍼터미널(COM2)에서 이루어지고 수신은
Thread 를 통해 DOS창에서 출력.
[ 송신 ]
[ 수신 ]