IT/임베디드 리눅스

임베디드 리눅스 -TextLCD

일상다반사로그 2017. 10. 13. 06:13
반응형

실습13 텍스트 LCD 제어 프로그램


* 실습목표

mmap 함수를 이용하여 텍스트 LCD 디바이스를 제어한다.

텍스트 LCD 응용 프로그램으로는 자신의 학번과 이름을 텍스트 LCD에 디스플레이 하고, 좌우로 시프트되는 프로그램을 작성한다.

* 기초지식

 텍스트LCD는 DR(Data Register)과 IR(Instruction Register)을 이용하여 LCD에 글자를 표시하고 있다. 그러나 타겟보드의 메인 CPU는 DR/IR 레지스터를 직접 액세스하지 못하고, 텍스트 LCD모듈에서 인터페이스 나온11개 비트(D0~D7,RS,R/W,E)를 이용하여 제어해야한다.

 텍스트LCD는 모듈의 물리번지는 0x1070 0000'이므로 mmap함수를 이용한 응용프로그램은 이 번지를 사용하여 TextLcd를 사용할 수 있다.



#include <stdlib.h>

#include <unistd.h>

#include <sys/mman.h>

#include <asm/fcntl.h>

#include <stdio.h>


#define ADDRESSOFTEXTLCD         0x10700000


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 cusror_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;

//텍스트 LCD 프로그램에서 사용하며 각종 헤더를 첨가 텍스트LCD 하드웨어 주소를 설정

//전역변수 및 사용자들이 사용해야할 함수들 선언


int main(int argc, char **argv)

{

//입력하는 매개 변수의 숫자를 이용하여 매개변수가 없을 때에는 텍스트LCD의 첫 번째줄과 두 번째 줄에

//쓸 문자열을 선언하고있다.

        int fd;

        int i, len1=7, len2=12;

        char buf1[ 100] = "Hello!";

        char buf2[ 100] = "EmbededWorld";

        if(argc == 2) {

                        len1= strlen(argv[1]);

                        len2= 0;

                        strcpy(buf1,argv[1]);

        }else if(argc >=3){

                        len1 = strlen(argv[1]);

                        len2 = strlen(argv[2]);

                        strcpy(buf1,argv[1]);

                        strcpy(buf2,argv[2]);

        }

        if((fd=open("/dev/mem", O_RDWR|O_SYNC)) < 0){

                perror("mem open fail\n");

                exit(1);

        }

        //mmap을 이용하여 텍스트 LCD의 하드웨어 어드레스를 응용 프로그램에서 사용할 가상주소를 얻기

        pTextlcd = mmap(NULL, 4, PROT_WRITE, MAP_SHARED, fd, ADDRESSOFTEXTLCD);


        if((int)pTextlcd < 0){

                pTextlcd = NULL;

                        close(fd);

                printf("mmap error\n");

                return -1;

        }

        initialize_textlcd(); //텍스트LCD 초기화하기


        //writebyte함수를 이용하여 첫 번째 줄에 buf1에 들어있는 문자열을 쓴다.

        //set_ddramm_address 함수를 이용하여 텍스트LCD커서를 두 번째 줄의 처음으로 바꾸고 다시 buf2        //에있는 문자열을 쓴다

        for(i= 0; i<len1; i++) writebyte(buf1[i]);

        for(i=0; i<20; i++) cursor_shit(1,1);

        clear_display();

        set_ddram_address(0x40);

        usleep(2000000);


        for(i=0; i<(19-len2); i++) cursor_shit(0,1);

        for(i=0; i<len2; i++) writebyte(buf2[i]);

        for(i=0; i<20; i++) cursor_shit(1,0);

        

        clear_display();

        return_home();


        munmap(pTextlcd, 4); //munmap을 사용하여 mmap을 이용하여 매핑한 메모리를 해제

        close(fd);         //close로 fd반환


        

}


void setcommand(unsigned short command)

{

//명령어를 받아 텍스트 LCD의 명령값을 전달한다. 전달하는 방법은 XScale의 데이터 라인 0dptj 10비트를 아래//의 텍스트 LCD의 write 타이밍도를 보고 조작하여 전달한다.

        command &= 0x00FF;

        

        *pTextlcd = command | 0x0000;

        *pTextlcd = command|0x0400;

        *pTextlcd = command | 0x0000;


        usleep(50);

}


void writebyte(char ch)

{

//제어 명령표의 'Data Write to GG RAM 혹은 DD RAM‘ 을 사용하기 위해 만들었다.

//이 함수는 텍스트 LCD에 직접 글자를 쓰는 함수이다.

        unsigned short data;

        data = ch & 0x00FF;


        *pTextlcd = data|0x100;

        *pTextlcd = data|0x500;

        *pTextlcd = data|0x100;

        

        usleep(50);

}


int clear_display(){

//제어명령표의 Clear Display(0x1)을 설정한 후 setcommand()함수로 명령어를 전달하여 텍스트 LCD의 화면을 //지우고 커서를 home에 위치시킨다.

        unsigned short command = 0x01;

        setcommand(command);

        usleep(2000);

        return 1;

}


int return_home(){

//제어 명령표의 Return Home(0x02)을 설정한 후 setcommand()함수로 명령어를 전달하여 커서를 home에위치

        unsigned short command = 0x02;

        setcommand(command);


        usleep(2000);

        return 1;

}


int entry_mode_set(int increase, int nshift){

//제어 명령표의 Entry Mode Set(0x04)을 설정하고 인수로 받은 increase를 데이터의 비트에 대응시키고 //setcommand 함수를 사용하여 텍스트LCD모듈에 전달한다.

        unsigned short command = 0x04;

        command = increase?(command | 0x2):command;

        command = nshift?(command | 0x1):command;

        setcommand(command);

        return 1;

}


int display_control(int display_enable, int cursor_enable, int nblink){


//인수로 받은 값에 따라 화면을 On/Off하거나 커서를 깜빡이는 함수    

        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 cursor_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;

}

// 텍스트 LCD를 초기화를 구현하는 함수들

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(2000);

}

반응형