Open changheepark-dev opened 10 months ago
/* * 프로그램 이름 : EX3.c * 프로그램 내용 : LCD 스위치 버저 LED 인터럽트 타이머 UART 통신 * Created: 2023-11-06 오후 6:17:00 * Author : 1922288 박창희 * 마지막 수정일 : 2023-11-06 오후 11:17:00 * 마지막 수정내용 :타이머 내용 추가 */ #define F_CPU 16000000UL // 16MHz의 오실레이터를 사용 #include <avr/io.h> //입출력 포트 사용을 위한 헤더 include #include <avr/delay.h> //딜레이 사용을 위한 헤더 inlcude #include <avr/interrupt.h> //인터럽트 사용을 위한 헤더 include #include "lcd.h" //LCD 사용을 위한 헤더 include -> " "외부의 파일을 include #include "uart.h" /* 외부 인터럽트 */ volatile char value1=0; ISR(INT0_vect) { cli(); if(!(PIND & (1<<PD0))) { value1 = (PORTB >> 4); PORTB = 0x00; } } void INTR_Init() { EICRA = (0b10<<ISC00); //하강엣지 트리거 EIMSK = (1<<INT0); //인터럽트 0 허용 PORTD |= (1<<PD0); //스위치를 PORTD 0번에 연결 sei(); //전역인터럽트 활성화 } /* 외부 인터럽트 끝 */ /* 타이머 */ volatile int count = 0, count_m = 0; //오버플로우가 발생한 횟수 ISR(TIMER1_COMPA_vect) { count++; if (count > 30) { count_m++; LCDMove(1,12); LCD_nNum(count_m); if (count_m >= 999) { count_m = 0; } count = 0; } } void TIMER1_Init() { TCCR1A = (0<<WGM11) | (1<<WGM10); TCCR1B = (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10); TIMSK |= (1 << OCIE1A); OCR1A = 128; sei(); //전역인터럽트 활성화 } /* 타이머 끝 */ /*AD 변환*/ int readAnalog(unsigned char ch) // AD 채널 값을 받아서 AD를 값을 읽어오는 함수. { int res; ADCSRA = 1<<ADEN | 0b111<<ADPS0; // 128 분주율로 AD를 사용 인에이블 설정 ADMUX = 0b01<<REFS0 | ch<<MUX0; // AREF를 기준전압으로 사용, AREF와 GND사이에 콘덴서 접속 ADCSRA |= 1<<ADSC; // A/D 변환 시작 while((ADCSRA & (1<<ADIF))) {} // A/D 변환완료인터럽트플래그비트 ADC 완료 대기 res = ADC; // 결과값을 res 변수에 넣음 return res; } int LCD_nNum(unsigned int NUM) { unsigned char Buff[8] = " 0"; Buff[0] = '0'+((NUM %10000)/1000); Buff[1] = '0'+((NUM %1000)/100); Buff[2] = '0'+((NUM %100)/10); Buff[3] = '0'+(NUM %10); for (unsigned char i=0; i<=2; i++) { if (Buff[i] != '0') { break; } Buff[i]=' '; } Buff[4]= '\0'; LCDPuts(Buff); } int main(void) { DDRB |= 0xf0; //7~4 LED 3~0 스위치가 연결되어 있다. 상위 니블 7~4까지는 출력을로 설정 하위 니블 3~0 입력으로 설정 DDRG |= (1<<PG3); //PG3번에 buzzer 연결되어있음 static char LCD_Tittle[]="resistance"; static char string[]="buzzer"; MCU_Init(); //LCD 사용을 위한 MCU 설정 LCDInit(); //LCD 사용을 위한 초기화 설정 LCDMove(0,0); //표시할 문자의 위치를 선택->HOME 위치 LCDPuts(LCD_Tittle); LCDMove(1,0); //LCD의 두번쨰 줄 LCDPuts(string); INTR_Init(); // 인터럽트 사용을 위한 초기화 TIMER1_Init(); UART_INIT(); // UART 통신 초기화 int analog = 0; unsigned char data=0; while (1) { analog = readAnalog(6); //가변저항 ADC 6,7번에 연결 LCDMove(0,12); //home 위치 LCD_nNum(analog); UART_transmit('a'); LCDMove(1,6); //home 위치 LCD_nNum((PORTB >> 4)); if(0 == (PINB & (1<<PB0))) { _delay_ms(200); //디바운싱을 해결하기위해 PORTB = PORTB ^ 0x10; } if(0 == (PINB & (1<<PB1))) { _delay_ms(200); //디바운싱을 해결하기위해 PORTB = PORTB ^ 0x20; } if(0 == (PINB & (1<<PB2))) { _delay_ms(200); //디바운싱을 해결하기위해 PORTB = PORTB ^ 0x40; } if(0 == (PINB & (1<<PB3))) { _delay_ms(200); //디바운싱을 해결하기위해 PORTB = PORTB ^ 0x80; } if(value1 > 0) { for (int b = value1 ; b > 0 ; b--) { PORTG |= (1<<PG3); //buzzer ON _delay_ms(100); PORTG &= ~(1<<PG3); //buzzer OFF _delay_ms(100); } value1=0; } } }