일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 리니지2레볼루션
- 국립경주박물관
- 후기
- 한국대중음악박물관
- 쿠폰
- 창세기전
- 아가시온
- VDI
- 2차전직
- AT&T
- 스피릿위시
- 치루
- 반구대암각화
- 주식
- 샤오미
- axe
- 울산박물관
- 걷기앱
- 족저근막염
- 워리어
- v4
- 버그
- 도미네이션즈
- 후쿠오카
- 몬스터스트라이크
- 브이포
- 달빛조각사
- 피쉬아일랜드
- AIA Vitality
- 창세기전 모바일
- Today
- Total
일상다반사 로그
임베디드 리눅스 Push,LED,TextLCD 본문
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <asm/fcntl.h>
#include <stdio.h>
#include <time.h> //랜덤수를 구하기위한 헤더파일
#define ADDRESSOFLED 0x10600000
#define ADDRESSOFPUSHBUTTON 0x10500000
#define ADDRESSOFTEXTLCD 0x10700000
//TextLCD를 사용하기 위한 함수들 선언
void setcommand(unsigned short command);
void initialize_textlcd();
void setcommand(unsigned short command);
void writebyte(char ch);
void initialize_textlcd();
void write_string(char *str,int length);
int function_set(int rows, int nfonts);
int display_control(int display_enable, int cursor_enable, int nblink);
int cusrsor_shit(int set_screen, int set_rightshit);
int entry_mode_set(int increase, int nshift);
int return_home();
int clear_display();
int set_ddram_address(int pos);
unsigned int *pTextlcd;
//TextLCD를 사용하기위한 함수
print_lcd(char * buf1, char *buf2, int *fd)
{
int i, len1=strlen(buf1), len2=strlen(buf2);
/*mmap을 이용하여 TextLCD의 하드웨어 어드레스를 응용프로그램에서
사용할 가상주소를 얻기*/
pTextlcd = mmap(NULL, 4, PROT_WRITE, MAP_SHARED, *fd, ADDRESSOFTEXTLCD);
initialize_textlcd(); //TextLCD초기화
/*writebyte함수를 이용하여 첫 번째 줄에 buf1에 들어있는 문자열을 쓴다.
set_ddram_address 함수를 이용하여 TextLCD커서를 두번째 줄의 처음으로
바꾸고 다시 buf2에 있는 문자열을 쓴다. */
for(i=0;i<len1;i++) writebyte(buf1[i]);
for(i=0;i<20-len1;i++) cusrsor_shit(1,1);
clear_display();
set_ddram_address(0x40);
for(i=0;i<(19-len2);i++) cusrsor_shit(0,1);
for(i=0;i<len2;i++) writebyte(buf2[i]);
for(i=0;i<20-len2;i++) cusrsor_shit(1,0);
clear_display();
set_ddram_address(0x40);
//munmap을 사용하여 mmap을 이용하여 매핑한 메모리를 해제
munmap(pTextlcd,4);
}
int main(){
int fd; //파일기술자
//LED와 Push button을 사용하기위한 변수들
unsigned char *addr_led, *addr_button,led_status;
unsigned char rp; //버튼값을 받는 변수
//랜덤수를 사용할 변수들
int s = 0, i,j=0;
int a=0;
int ran[5];
for(i = 0; i< 5; i++) //배열초기화
ran[i] = 5;
if((fd =open("/dev/mem",O_RDWR|O_SYNC)) <0){
perror("mem open fail \n");
exit(1);
}
/*mmap을 이용하여 LED,Push Button 하드웨어 어드레스를 응용프로그램에서
사용할 가상주소를 얻기*/
addr_led = mmap(NULL,1,PROT_WRITE,MAP_SHARED,fd,ADDRESSOFLED);
addr_button = mmap(NULL,1,PROT_READ,MAP_SHARED,fd,ADDRESSOFPUSHBUTTON);
*addr_led=0xAA; //Led초기화
led_status=1;
*addr_led= led_status;
print_lcd("ON LED","Cheking Random num",&fd);
while(1){
while(1){
j = 0;
srand((unsigned) time(NULL));
s= rand()%5; //랜덤함수사용 0~4까지
/*랜덤수를 구할때 중복된 값을 배열에 저장못하게
ran배열에 어떤위치의 값이 현재구해진 랜덤수와
같다면 j변수에 1를 넣어준다 이후 조건문에서
j가 1일때 continue를 해줌으로써 중복된값을
저장못하게 한다. */
for(i = 0 ; i < 5; i++)
{
if(ran[i]==s){
j = 1;
break;
}
}
if(j == 1){
continue;
}
else{
break;
}
}
ran[a]=s;
printf("현재 숫자: %d \n",ran[a]);
//ran[]배열에 있는 숫자에 따른 LED 점등
switch(ran[a]){
case 0 : led_status=128; break;
case 1 : led_status=64; break;
case 2 : led_status=32; break;
case 3 : led_status=16; break;
case 4 : led_status=8; break;
default : printf("error\n");
}
a++;
*addr_led = led_status;
usleep(500000);
if(a == 5)
break;
}
led_status=0;
*addr_led = led_status;
printf("* 프로그램 시작 *\n");
print_lcd("Program Start !","You have to remember",&fd);
i =0; //이후에 랜덤수비교할때쓰기위해 미리초기화
//버튼을 누르면 LED가 점등된다.마지막버튼은 종료 버튼
while(1){
int cnt =0;
int tmp = 255 - *addr_button; //버튼주소값을 구하기
switch(tmp){
case 0x80 : led_status=128; break;
case 0x40 : led_status=64; break;
case 0x20 : led_status=32; break;
case 0x10 : led_status=16; break;
case 0x8 : led_status=8; break;
case 0x4 : led_status=4; break;// 현재 사용하지 않는 버튼
case 0x2 : led_status=2; break;// 차후 업그래이드 예정
case 0x1 : printf("* 프로그램 종료 *\n"); print_lcd("Game Over","Thank you",&fd); *addr_led = 0x00; munmap(addr_led,1); munmap(addr_button,1);close(fd); exit(1); break;
}
*addr_led = led_status; usleep(10000);
//다섯개 모두 맞췄을경우 알림표시
if(i==5)
{
printf("와우! 당신은 정말 천재이군요!\n");
print_lcd("Wow Good Choice!","You lucky guy!",&fd);
break;
}
//랜덤수와 현재 버튼눌렀을때와의 비교
while(1)
{
if(tmp != 0){
if(tmp == 128)
break;
else{
tmp <<= 1;
cnt++;
}
}
else
break;
}
if(tmp == 0)
continue;
//버튼을 눌러서 맞췄을경우 콘솔에 표시
if(ran[i]==cnt)
{
printf("%d번 맞음 Good Choice !\n", i+1);
i++;
usleep(500000);
continue;
}
//틀렸을경우 콘솔에 알려주고 TextLCD에 실패표시
else
{
printf("틀렸습니다 프로그램 종료...\n");
print_lcd("Fail....T.T","You unlucky guy",&fd);
break;
}
}
printf("* 프로그램 종료 *\n");
print_lcd("Game Over","Thank You",&fd);
*addr_led = 0x00; //LED꺼짐
//munmap을 사용하여 mmap을 이용하여 매핑한 메모리를 해제
munmap(addr_led,1); munmap(addr_button,1);
close(fd); //fd반환
return 0;
}
//명령어를 받아 TextLCD의 명령값을 전달
void setcommand(unsigned short command)
{
command &= 0x00FF;
*pTextlcd = command | 0x0000;
*pTextlcd = command | 0x0400;
*pTextlcd = command | 0x0000;
usleep(100000);
}
/*제어명령표의 DataWrite to GG RAM 혹은 DD RAM을 사용하기위한 함수
TextLCD 직접 글자를 쓰는 함수이다.*/
void writebyte(char ch)
{
unsigned short data;
data = ch & 0x00FF;
*pTextlcd = data|0x100;
*pTextlcd = data|0x500;
*pTextlcd = data|0x100;
usleep(5000);
}
/*제어 명령표의 Clear Display(0x1)을 설정한후 setcommand()함수로 명령어를 전달
TextLCD의 화면을 지우고 커서를home에 위치시킨다. */
int clear_display(){
unsigned short command = 0x01;
setcommand(command);
usleep(2000);
return 1;
}
/*제어 명령표의 Return Home(0x02)을 설정한후 setcommand()함수로 명령어를 전달
하여 커서를 home에 위치시킨다.*/
int return_home(){
unsigned short command = 0x02;
setcommand(command);
usleep(2000);
return 1;
}
/*제어 명령표의 Entry Mode Set(0x04)을 설정하고 인수로 받은increase를
데이터의 비트에 대응시키고 setcommand()를 사용하여 TextLCD모듈에 전달 */
int entry_mode_set(int increase, int nshift){
unsigned short command = 0x04;
command = increase ? (command | 0x2) : command;
command = nshift ? (command | 0x1) : command;
setcommand(command);
return 1;
}
//인수로 받은 값에 따라 화면을 On/Off 하거나 커서를 깜빡이는 함수
int display_control(int display_enable, int cursor_enable, int nblink){
unsigned short command = 0x08;
command = display_enable ? (command | 0x04) : command;
command = cursor_enable ? (command | 0x02) : command;
command = nblink ? (command | 0x01) : command;
setcommand(command);
return 1;
}
//인수로 받은 값에 따라 화면 또는 커서를 왼쪽 오른쪽으로 시프트 하는 함수
int cusrsor_shit(int set_screen, int set_rightshit){
unsigned short command = 0x10;
command = set_screen ? (command | 0x08) : command;
command = set_rightshit ? (command | 0x04) : command;
setcommand(command);
return 1;
}
//이후 나머지 함수들은 TextLCD 초기화를 구현하는 함수들이다.
int function_set(int rows, int nfonts){
unsigned short command = 0x30;
if(rows == 2) command |= 0x08;
else if(rows == 1) command &= 0xf7;
else return -1;
command = nfonts ? (command | 0x04) : command;
setcommand(command);
return 1;
}
int set_ddram_address(int pos){
unsigned short command = 0x80;
command += pos;
setcommand(command);
return 1;
}
void initialize_textlcd(){
function_set (2,0);
display_control(1,0,0);
clear_display();
return_home();
entry_mode_set(1,0);
usleep(200000);
}
'IT > 임베디드 리눅스' 카테고리의 다른 글
임베디드 리눅스 -TextLCD (0) | 2017.10.13 |
---|---|
임베디드 리눅스 - LED(2) (0) | 2017.10.12 |
임베디드 리눅스 - LED (0) | 2017.10.11 |
임베디드 리눅스 - 텍스트 LCD (0) | 2017.10.11 |
임베디드 리눅스 - 스톱워치 (0) | 2017.10.10 |