BASIC4MCU | 질문게시판 | Atmega128a timer3 compare match 주기 오류
페이지 정보
작성자 junner 작성일2022-12-05 21:22 조회702회 댓글1건본문
External INT 5(rising edge)발생하면 16 bit timer3의 compare match(CTC)
15.84 msec로 주기를 만들고, timer3의 CTC interrupt가 발생시키고, 15.84주기 interrupt
발생하면 주기마다 ADC를 통해 온도(free running mode)측정하여 7-segment에 디스플레이를 할려고합니다.
15.84 주기를 잘못 입력했는지 작동을 안합니다.
#include <mega128.h>
#include <delay.h>
typedef unsigned char u_char;
flash u_char seg_pat[10]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
unsigned char led = 0xFE; // LED 출력 초기값
void main(void)
{
DDRC = 0xFF; // 포트 C 출력으로 설정
PORTC = led; // 포트 C에 초기값 출력
ETIMSK = 0b00010000; // TOIE3 = 1
TCCR3A = 0x00; // CTC MODE
TCCR3B = 0b00001101; // T3 상승 에지에서 카운팅
TCCR3C = 0x0;
TCNT3H = 0x00; // TCNT3 초기값 설정 : 외부에서 클럭 1개
TCNT3L = 0x00; // 입력되면서 0이 되면서 인터럽트 발생
//OCR3AH = 0x0
//OCR3AL = 0xFF
SREG |= 0x80; // 전역 인터럽트 인에이블 비트 I 셋
while(1);
}
interrupt [TIM3_OVF] void timer_int3(void)
{
TCNT3H = 0xFF; // 초기값 재설정
TCNT3L = 0xFF;
led = led << 1; // 1비트 쉬프트
led = led | 0x01; // 최하위 비트 셋
if(led == 0xFF) led = 0xFE; // 모두 off이면 초기값 재설정
PORTC = led; // 포트 출력
}
void AD_disp(int); // A/D 변환값 표시
void main(void)
{
int ad_val;
DDRB = 0xF0;
DDRD = 0xF0;
DDRG = 0x0F;
ADMUX = 0x07; // ADC6 단극성 입력 선택
ADCSRA = 0x87; // ADEN=1, 16MHz 256분주 -> 125kHz
delay_ms(5);
while(1){
ADCSRA = 0xC7; // ADEN=1, ADSC = 1 변환 시작
while((ADCSRA & 0x10) == 0); // ADIF=1이 될 때까지
ad_val = (int)ADCL + ((int)ADCH << 8); // A/D 변환값 읽기
AD_disp(ad_val); // A/D 변환값 표시
}
}
void AD_disp(int val) {
float fval;
int ival, buf;
u_char N100, N10, N1;
fval = (float)val * 5.0 / 1024.0; // 젂압 값으로 변환
ival = (int)(fval * 1.0 / 0.001); // 반올림 후 정수화, (소수 둘째자리까지)
N100 = ival / 100; // 정수부 추출
buf = ival % 100;
N10 = buf / 10; // 소수 첫째 자리 추출
N1 = buf % 10; // 소수 둘째 자리 추출
PORTG = 0b00001000; // PG3=1, 소수 둘째 자리
PORTD = ((seg_pat[N1] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[N1] & 0x70 ) | (PORTB & 0x0F);
delay_ms(1);
PORTG = 0b00000100; // PG2=1, 소수 첫째 자리
PORTD = ((seg_pat[N10] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[N10] & 0x70 ) | (PORTB & 0x0F);
PORTB = PORTB | 0x80; // DP on(소수점)
delay_ms(1);
PORTG = 0b00000010; // PG1=1, 정수부
PORTD = ((seg_pat[N100] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[N100] & 0x70 ) | (PORTB & 0x0F);
delay_ms(1);
}
댓글 1
조회수 702junner님의 댓글
junner 작성일감사합니다!