이제 계속적으로 LCD를 사용하면서 다른 기능들을
연습 하기 위해 계속 LCD 소스를 넣어 보았다. ㅋ
이 실습을 하니깐.. 시간이 0.1초 정도 밖에 안되어..
눈으로 보기에는 오버플로우 인터럽트가 계속 걸려 있는 것처럼
보였다.
#include <avr/io.h>
#include <stdio.h>
#include <avr/signal.h>
/***** 포트가 바뀔 경우 여기에서 수정 ******/
//LCD의 4,5,6번의 포트
#define LCD_PORT_CONTROL PORTA
#define LCD_DDR_CONTROL DDRA
//LCD의 7~14번의 포트
#define LCD_PORT_DATA PORTB
#define LCD_DDR_DATA DDRB
/***** Delay 함수 ******/
//delay 함수로 #include<avr/delay.h> 보다 나은것 같음
//이 소스는 윤덕용 선생님의 책을 인용한 것임
void Delay_us(int time_us)
{
int volatile i;
for(i=0; i<time_us; i++){ // 4 cycle +
asm volatile("PUSH R0"); // 2 cycle +
asm volatile("POP R0"); // 2 cycle + = 8 cycle = 1us for 8Mhz
asm volatile("PUSH R0"); // 2 cycle +
asm volatile("POP R0"); // 2 cycle + = 12 cycle for 11.0592MHZ
asm volatile("PUSH R0"); // 2 cycle +
asm volatile("POP R0"); // 2 cycle = 16 cycle = 1us for 16MHz
}
}
void Delay_ms(int time_ms)
{
int volatile i;
for(i=0; i<time_ms; i++)
Delay_us(1000);
}
/***** LCD 명령어 레지스터에 쓰는 함수 *****/
void Command(unsigned char command)
{
LCD_PORT_CONTROL = 0x00; // E = 0, R/W=0, Rs = 0
LCD_PORT_DATA = command; // 명령어 출력
LCD_PORT_CONTROL = 0x04; // E = 1 , R/W=0, Rs = 0(LCD 동작)
Delay_us(1);
LCD_PORT_CONTROL = 0x00; // E = 0, R/W=0, Rs = 0
Delay_us(50);
}
/***** LCD 데이터 레지스터에 쓰는 함수 *****/
void Data(unsigned char data)
{
LCD_PORT_CONTROL = 0x01; // E = 0, R/W=0, Rs = 1
LCD_PORT_DATA = data; // 데이터 내용 출력
LCD_PORT_CONTROL = 0x05; // E = 1, R/W=0, Rs = 1(LCD 동작)
Delay_us(1);
LCD_PORT_CONTROL = 0x01; // E = 0, R/W=0, Rs = 1
Delay_us(50);
}
/***** AVR 초기화 및 LCD에 대한 초기화 *****/
void Init(void)
{
LCD_DDR_DATA=0xff;
LCD_DDR_CONTROL=0x07;
Delay_ms(50);
Command(0x38); // function set(데이터 선을 8 bit 다 사용, 2줄표시 , 5x7 dot 사용)
Command(0x0C); // display control(표시(display) 켬, 커서(cursor) 끔)
Command(0x06); // entry mode set(CGRAM이나 DDRAM을 써넣거나 읽을 때
// 어드레스를 1증가 시키고 커서를 우로 이동, 시프트는 안함
Command(0x01); // clear display
Delay_ms(2);
}
/***** LCD에 글자 출력 함수 *****/
void String( unsigned char *string)
{
while(*string != '\0')
{
Data(*string);
string++;
}
}
unsigned char cnt = 0, led = 0xFF;
SIGNAL(SIG_OVERFLOW0) // 타이머/카운터0 오버플로우 함수
{ // MAIN에서 인터럽트 발생 주기를 1/16us * 1024 분주 * (256-0) = 16,384us로
unsigned char i; // 하여 16,384us 때 오버플로우가 생겨 이 함수로 들어옴
TCNT0 = 0x00;
cnt++;
if(cnt >= 10)
{
cnt = 0;
led = (led << 2);
if(led == 0x00)
{
led = 0xFF;
}
PORTD = led;
for(i = 0; i < 3; i++)
{
Command(0x80); // 첫줄 사용
String(" OVERFLOW0 ");
Delay_ms(500);
Command(0xC0); // 두번째 줄 사용
String(" 2009/07/24 ");
Delay_ms(500);
}
}
}
int main(void)
{
TIMSK = 0x01; // 오버프로우 인터럽트 인에이블 비트
TCCR0 = 0x07; // 1024분주
TCNT0 = 0x00; // 타이머 카운터를 0으로 함
SREG |= 0x80; // 인터럽트 사용
DDRD = 0xFF;
PORTD = 0xFF;
Init();
while(1)
{
Command(0x80); // 첫줄 사용
String(" PURESTARMAN ");
Delay_ms(1000);
Command(0xC0); // 두번째 줄 사용
String(" 2009/07/15 ");
Delay_ms(2000);
}
}
'AVR' 카테고리의 다른 글
간단한 송신 프로그램 (0) | 2009.11.11 |
---|---|
스텝모터 구동 (0) | 2009.09.14 |
타이머 / 카운터 0 일반모드(이론) (0) | 2009.07.25 |
TEXT LCD 제어 실습(외부 인터럽트) (0) | 2009.07.21 |
TEXT LCD 제어 실습 (0) | 2009.07.17 |