작업:
LCD를 통한 문자열 출력
개요:
Atmega의 입출력을 외부인터럽트를 사용해서 LCD에 출력
LCD Pin
lcd.h
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 | #ifndef __LCD_H__ #define __LCD_H__ #include "main.h" #define RS 4 #define RW 5 #define EN 6 #define BUS PORTA #define CTL PORTC // 케릭터lcd명령어 pdf 파일참고 #define LCD_CLR 0x01 //화면지우기 #define LCD_HOME 0x02 // 03가능// 홈 #define LCD_ENT 0x06 //S:0Shift OFF, I/D:1 Increase Mode // 엔트리모드셋 2진수 0110 #define LCD_DSP 0x0F //D:1 Display On C:1 Cursor on B:1 Blink On 1 // 2진수 1111 #define LCD_CUR 0x14 //S/C:0 Shift Cursor OFF R/L:1 // 2진수 0001 0100 #define LCD_FUNC 0x38 //DL:1 Data length 8bit N:1 2Line F:0 Font 5X8 // 2진수 0011 1000 void LCD_Init(void); void LCD_Inst(unsigned char ucInst); void LCD_Data(unsigned char ucData); void LCD_Str(char const *cString); #endif //__LCD_H_ | cs |
6~8번 : 각각 pin 번호 부여 LCD 모듈 컨트롤하기위한 RS,RW,E
10번 : PORTA를 BUS로 지정
11번 : PORTC를 제어로 지정
14번 : C영역 0000 0001 clear displayer 명령 실행
15번 : C영역 0000 0010 Return Home 명령 실행
16번 : C영역 0000 0110 Entry Mode 1 커서방향은 오른쪽으로 이동 SHIFT가 0이므로 쉬프트 X
17번 : C영역 0000 1111 디스플레이 제어 - Display ON ,화면 ON,커서 ON,커서 깜박임 ON
18번 : C영역 0001 0100 Cursor or Display Shift 명령 실행 - 오른쪽으로 커서 이동
19번 : C영역 0011 1000 Function Set 명령어 실행 ,Bus Size 8Bit, 2Line,5*10 font dots
21~24번 : 각각의 함수원형
lcd.c
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #include "lcd.h" void LCD_Init(void) { DDRC = ( 1 << RS )|( 1 << RW )|( 1 << EN ); //rs,rw,en 열기 DDRA = 0xFF; CTL = ( 0 << RS )|( 0 << RW )|( 0 << EN ); //Low 상태CTL == PORTC BUS = 0x00; LCD_Inst(LCD_FUNC); LCD_Inst(LCD_DSP); LCD_Inst(LCD_ENT); LCD_Inst(LCD_CUR); LCD_Inst(LCD_CLR); LCD_Inst(LCD_HOME); return; } void LCD_Inst(unsigned char ucInst) { //unsigned char int ucInst = 0x41; // ucInst volatile unsigned int uiCnt; //A 구간 CTL = CTL & (~ (1 << RS)); // CTL == PORTC CTL = CTL & (~ (1 << RW)); CTL = CTL & (~ (1 << EN)); BUS = ucInst; for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //B 구간 //CTL = CTL & (~ (1 << RS)); // CTL == PORTC //***** RS/RW/DB 는유지되므로****// //CTL = CTL & (~ (1 << RW)); //CTL = CTL & (~ (1 << EN)); //**** 중복제거 *****// //BUS = ucInst; for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //c 구간 //CTL = CTL & (~ (1 << RS)); // CTL == PORTC //CTL = CTL & (~ (1 << RW)); CTL = CTL | (1 << EN); // high 값을 가지므로 //BUS = ucInst; for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //D 구간 //CTL = CTL & (~ (1 << RS)); // CTL == PORTC //CTL = CTL & (~ (1 << RW)); CTL = CTL & (~ (1 << EN)); //BUS = ucInst; for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //E 구간 //CTL = CTL & (~ (1 << RS)); // CTL == PORTC //CTL = CTL & (~ (1 << RW)); //CTL = CTL & (~ (1 << EN)); //BUS = ucInst; for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); return; } void LCD_Data(unsigned char ucData) { volatile unsigned int uiCnt; //A 구간 CTL = CTL | (1 << RS); CTL = CTL & (~ (1 << RW)); CTL = CTL & (~ (1 << EN)); BUS = ucData; for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); // BUS를 통해 DATA와 Instruction 구간적 시간벌이 //B 구간 for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //c 구간 CTL = CTL | (1 << EN); // high 값을 가지므로 for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //D 구간 CTL = CTL & (~ (1 << EN)); for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); //E 구간 for(uiCnt = 0 ; uiCnt < 30000; uiCnt++); return; } void LCD_Str(char const *cString) { while(0 != *cString) { LCD_Data(*cString); ++cString; } return; } | cs |
3번 : lcd_Init 함수 - LCD 초기화
5번 : PortC의 4,5,6핀에 각각 RS, RW, E 출력 설정
6번 : PortA 모두 출력
7번 : 제어 모두 Low로 설정
8번 : Bus도 0로 초기화
9~14번 : 각각의 기능들을 초기화
19번 : LCD_Inst 함수
24번~26번 : A구간 비트&연산에 의해 RS,RW,E는 모두 0
27번 : 문자를 버스에 넣음
28번 : 딜레이
35번 : B구간은 A가 유지되므로 딜레이만 시킴
40번 : C구간에서 E는 High 값을 가짐 LCD Enable
47번 : D구간에서 E는 Low 값을 가짐 LCD disable
56번 : E 구간 현상유지 딜레이만 함
61번 : LCD_Data 함수
65번 : A구간 RS 에 high값을 줘서 DATA전달 RW,E는 0
68번 : Bus에 문자넣음
72번 : B구간 현상유지하며 딜레이
75번 : C구간에서 E는 High 값을 가짐 LCD Enable
79번 : D구간에서 E는 Low 값을 가짐 LCD disable
83번 : E구간 현상유지 딜레이만 함
88번 : LCD_Str 함수
cString에 값이 있는지 판단후 있으면 cString문자열을 LCD_Data함수에 문자열을 하나씩 담아서 보냄
main.h
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #ifndef __MAIN_H__ #define __MAIN_H__ #define PINA (*((volatile unsigned char *)0x20)) #define DDRA (*((volatile unsigned char *)0x21)) #define PORTA (*((volatile unsigned char *)0x22)) #define PINC (*((volatile unsigned char *)0x26)) #define DDRC (*((volatile unsigned char *)0x27)) #define PORTC (*((volatile unsigned char *)0x28)) #define EICRA (*((volatile unsigned char *)0x69)) #define EICRB (*((volatile unsigned char *)0x6A)) #define EIMSK (*((volatile unsigned char *)0x3D)) #define SREG (*((volatile unsigned char *)0x5F)) #define INT7 7 #define INT6 6 #define INT5 5 #define INT4 4 #define INT3 3 #define INT2 2 #define INT1 1 #define INT0 0 #define ISC7 6 #define ISC6 4 #define ISC5 2 #define ISC4 0 #define ISC3 6 #define ISC2 4 #define ISC1 2 #define ISC0 0 #define sei() __asm__ __volatile__ ("sei" ::) #define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: ) //void Init (void); //void Port_Init(void); //void INT_Init(void); void __vector_1 (void) __attribute__((signal, used, externally_visible)); void __vector_2 (void) __attribute__((signal, used, externally_visible)); #endif //__MAIN_H_ | cs |
4~16번 : 각각 해당하는 PinA,C및 EICRA,EICRB,EIMSK ,SREG 주소 설정
18~34번 : 사용할 값들 정의
36~37번 : sei및 sleep 정의
45~46번 : 인터럽트 벡터(interrupt vector) 인터럽트가 발생했을 때, 그 인터럽트를 처리할 수 있는 서비스 루틴들의 주소를 가지고 있는 공간
vector1과 vector2로 할당
main.c
1 2 3 4 5 6 7 8 9 10 11 | #include "main.h" #include "lcd.h" int main(void) { LCD_Init(); //LCD_Data('A'); LCD_Str("AAAAAAAAA"); while(1); return 0; } | cs |
1~2번 : main.h 와 lcd.h 헤더 불러옴
6번 : LCD_Init() 함수 호출 - 초기화시킴
8번 : LCD_STR("") 문자열 출력
출력:
'코스웨어 > 16년 스마트컨트롤러' 카테고리의 다른 글
20160322_김가연_업무일지_USART Rx Tx 시리얼 통신 (0) | 2016.03.23 |
---|---|
20160322-업무일지-이보원 (UART 통신) (0) | 2016.03.23 |
20160322_박진한_업무일지_펌웨어 실습(입력값 LCD에 출력) (0) | 2016.03.23 |
20160317_김도관_업무일지_LCD_특정시간출력 (0) | 2016.03.23 |
디자인 사고(Design Thinking) (0) | 2016.03.22 |
20160322_장진웅_업무일지_펌웨어 실습(입력값 LCD에 출력) (0) | 2016.03.22 |
2016_03_22_노태경_업무일지_ (0) | 2016.03.22 |
2016_03_21_업무일지_노태경 (0) | 2016.03.22 |