BASIC4MCU | 질문게시판 | atmega128 질문이요
페이지 정보
작성자 dwe1312 작성일2020-11-05 02:24 조회6,036회 댓글2건본문
SEI(); 이나 SREG레지스터를 사용하면 LCD가 깜빡거리고 저둘을 지우면 글쓰는 나오는데 인터럽트가 실행이 않되는데
어떻게 해결해야하나요?
#include <iom128v.h>
#include <avrdef.h>
void delay_ms(unsigned int m);
void delay_us(unsigned int u);
void write_data(char d);
void write_instruction(char i);
void init_lcd(void);
void LCD_STR(char* str);
unsigned ampm =0;
unsigned char cnt =0, sec=0, min=0,hour=0;
void LCD_CHAR(char c) {
write_data(c);
delay_ms(1);
}
void Init_Timer0(void)
{
TCCR0 =0x02;
OCR0 = 100;
TIMSK = 0x01;
}
#pragma interrupt_handler timer0_comp_isr: iv_TIMER0_COMP
void timer0_comp_isr(void)
{
TCCR0 =6;
cnt++ ;
if(cnt == 20000)
{
cnt = 0;
sec++;
if(sec >= 60)
{
min++; sec = 0;
}
if(min >= 60) {
hour++; min = 0;
}
if(hour>12){
hour = 0;
if(ampm == 0) ampm =1;
else if(ampm ==1) ampm=0;
cnt =0;
}
}
}
void main(void)
{
DDRC=0xff;
DDRB=0xe0;
init_lcd();
char str[] = "Curren time";
char AM[] = "AM";
char PM[] = "PM";
Init_Timer0();
TCCR0 =6;
SREG = 0x80;
SEI();
char temp[16];
while(1){
write_instruction(0x80);
LCD_STR(str);
sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");
write_instruction(0xc0);
LCD_STR(temp);
}
}
void init_lcd(void) //초기화 함수
{
delay_ms(50);
write_instruction(0x30); //데이터 길이=8비트, lcd 1열로 사용
delay_ms(25);
write_instruction(0x30); //데이터 길이=8비트, lcd 1열로 사용
delay_ms(5);
write_instruction(0x30); //데이터 길이=8비트, lcd 1열로 사용
delay_ms(5);
write_instruction(0x3c); //데이터 길이=8비트, 5x7도트, lcd 2열로 사용
delay_ms(5);
write_instruction(0x08); //화면 off 커서 off, 점멸하지 않음
delay_ms(5);
write_instruction(0x01); //화면 지움 명령
delay_ms(5);
write_instruction(0x06); //주소를 +1시키고, 커서 또는 블링크 위치가 우측으로 이동 명령
delay_ms(5);
write_instruction(0x0c); //화면 on 명령
delay_ms(15);
}
void write_instruction(char i)
{
PORTB=0x80;
delay_us(10);
PORTC=i;
delay_us(10);
PORTB=0x00;
delay_us(100);
}
void write_data(char d)
{
PORTB=0xa0;
delay_us(10);
PORTC=d;
delay_us(10);
PORTB=0x20;
delay_us(100);
}
void delay_ms(unsigned int m)
{
unsigned int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<2117;j++);
}
}
void delay_us(unsigned int u)
{
unsigned int i,j;
for(i=0;i<u;i++)
{
for(j=0;j<2;j++);
}
}
void LCD_STR(char*str) // 문자열출력
{
while(*str!= 0)
{
write_data(*str);
str++;
}
}
댓글 2
조회수 6,036master님의 댓글
master 작성일
while(1){
write_instruction(0x80); LCD_STR(str);
sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");
write_instruction(0xc0); LCD_STR(temp);
delay_ms(500);
}
딜레이 없이 연속으로 출력하는 것보다 딜레이를 넣으면 더 매끄러워집니다.
초당 1회 또는 2회면 충분하겠죠
master님의 댓글
master 작성일
인터럽트와 메인함수의 동기를 맞추는 방법을 알려드리죠
unsigned char flag=0; //전역변수 추가
타이머 인터럽트 안에서 초 증가하는 부분에 코드를 한 줄 추가합니다.
if(cnt == 20000){ cnt = 0;
flag=1; //추가
sec++;
메인은 아래처럼 수정합니다.
while(1){
if(flag){ flag=0; //추가
write_instruction(0x80); LCD_STR(str);
sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");
write_instruction(0xc0); LCD_STR(temp);
} //추가
}
딜레이는 제거했습니다.
sec가 증가한 후에 LCD 표시를 합니다.