BASIC4MCU | 질문게시판 | atmega while문 도와주세요 ㅠㅠ
페이지 정보
작성자 용용용 작성일2022-12-02 15:44 조회173회 댓글0건본문
제가 밑에 3가지 조건을 동시에 돌리려 메인 함수 while문 안에 코딩을 해봤는데 1, 2번만 작동을 하고 거리센서는 작동을 안 해요 ㅠㅠ 주석 처리하고 3번만 돌렸을 땐 잘 작동하는데 한번에 작동 시키려니 거리센서만 작동을 안 하는데 수정할 부분이 있을까요 ㅠㅠ 고민 많이 해봤는데 어렵네요...
1. 실시간 온도 fnd로 나타내기
2. 조도센서 이용해서 LED on, off
3. 초음파 거리센서 이용해서 버저 울리기
#define F_CPU 16000000UL
#define F_SCK 40000UL
#include <avr/io.h>
#include <util/delay.h>
#define LM75A_ADDR 0x90
#define LM75A_TEMP_REG 0
//모터
#define MOTOR_ON 0x40 //PB6 = 1
#define MOTOR_STOP 0x00 //PB6 = 0
#define TEM1 0x1400 //20도
// 거리
#define TRIG 6 // HC-SR04 Trigger 신호 (출력 = PE6)
#define ECHO 7 // HC-SR04 Echo 신호 (입력 = PE7)
#define SOUND_VELOCITY 340UL // 소리 속도 (m/sec)
//조도
#define CDS_10 341
void init_adc();
unsigned short read_adc();
void show_adc_led(unsigned short data);
void init_twi_port();
int read_twi_2byte_nopreset(char reg);
void display_FND(int value);
int main()
{
unsigned int distance, i;
DDRB = 0x10; // 삐에조 버저 출력
DDRE = ((DDRE | (1<<TRIG)) & ~(1<<ECHO)); // TRIG = 출력, ECHO = 입력으로 셋팅
int temperature=0;
init_twi_port();
DDRB = 0x08;
unsigned short value_zodo;
DDRA = 0x07; //PA0~2까지 LED
DDRF = 0x00;
init_adc();
while (1){
for (i=0; i<30; i++)
{
if (i == 0){
temperature = read_twi_2byte_nopreset(LM75A_TEMP_REG);
}
if(temperature > TEM1)
{
PORTB = MOTOR_ON;
}
else{
PORTB = MOTOR_STOP;
}
}
display_FND(temperature);
value_zodo = read_adc();
show_adc_led(value_zodo);
TCCR1B = 0x03; // Counter/Timer 1 클록 4us
PORTE &= ~(1<<TRIG); // Trig = LOW 상태 유지
_delay_us(10); // 최소 10us 동안
PORTE |= (1<<TRIG); // Trig = HIGH -> 거리 측정 명령 시작
_delay_us(10); // 펄스폭을 최소 10us 유지
PORTE &= ~(1<<TRIG); // Trig = LOW -> 거리 측정 명령 끝
while(!(PINE & (1<<ECHO))); // Echo = HIGH가 될 때까지 대기
TCNT1 = 0x0000; // Counter/Timer 1 값 초기화(=0)
while (PINE & (1<<ECHO)); // Echo = LOW가 될 때까지 대기 -> 측정 완료
TCCR1B = 0x00; // Counter/Timer 1 클록 정지
distance = (unsigned int)(SOUND_VELOCITY * (TCNT1 * 4 / 2) / 1000); // 거리 = 속도 * 시간
if (distance < 300){ // 30cm 이내 접근?
for (i=0; i<5; i++){ // 연속하여 삐~ 울림
PORTB = 0x10; _delay_ms(1); // 1ms 동안 ON 상태 유지
PORTB = 0x00; _delay_ms(1); // 1ms 동안 OFF 상태 유지
}
}
else ; // 1m 이상 거리가 있는 경우, 버저 울리지 않음
}//while문 끝
}
// TEM
void init_twi_port(){
DDRC = 0xff;
DDRG = 0xff;
TWSR = TWSR & 0xfc;
TWBR = (F_CPU/F_SCK - 16) / 2;
}
int read_twi_2byte_nopreset(char reg){
char high_byte, low_byte;
TWCR = (1 << TWINT) | (1<<TWSTA) | (1<<TWEN);
while (((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x08) ;
TWDR = LM75A_ADDR | 0;
TWCR = (1 << TWINT) | (1 << TWEN);
while (((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x18) ;
TWDR = reg;
TWCR = (1 << TWINT) | (1 << TWEN);
while (((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x28) ;
TWCR = (1 << TWINT) | (1<<TWSTA) | (1<<TWEN);
while (((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x10) ;
TWDR = LM75A_ADDR | 1;
TWCR = (1 << TWINT) | (1 << TWEN);
while (((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x40) ;
TWCR = (1 << TWINT) | (1 << TWEN | 1 << TWEA);
while(((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x50) ;
high_byte = TWDR;
TWCR = (1 << TWINT) | (1 << TWEN);
while(((TWCR & (1 << TWINT)) == 0x00) || (TWSR & 0xf8) != 0x58) ;
low_byte = TWDR;
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
while ((TWCR & (1 << TWSTO))) ;
return((high_byte<<8) | low_byte);
}
void display_FND(int value){
char digit[12] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0x00, 0x40};
char fnd_sel[4] = {0x01, 0x02, 0x04, 0x08};
int value_int, value_deci, num[4], i;
if ((value & 0x8000) != 0x8000)
num[3] = 10;
else{
num[3] = 11;
value = (~value)+1;
}
value_int = (value & 0x7F00) >> 8;
value_deci = (value & 0x0080);
num[2] = (value_int / 10) % 10;
num[1] = value_int % 10;
num[0] = (value_deci == 0x80) ? 5 : 0;
for(i=0; i<4; i++){
PORTC = digit[num[i]]; PORTG = fnd_sel[i];
if (i==1) PORTC |= 0x80;
if (i%2) _delay_ms(2);
else _delay_ms(3);
}
}
/// 조도
void init_adc(){
ADMUX = 0x40;
ADCSRA = 0x87;
}
unsigned short read_adc(){
unsigned char adc_low, adc_high;
unsigned short value_zodo;
ADCSRA |= 0x40;
while ((ADCSRA & 0x10) != 0x10);
adc_low = ADCL;
adc_high = ADCH;
value_zodo = (adc_high << 8) | adc_low;
return value_zodo;
}
void show_adc_led(unsigned short value_zodo){
if (value_zodo <= CDS_10){
PORTA = 0xff;
}
else{
PORTA = 0x00;}
}
댓글 0
조회수 173등록된 댓글이 없습니다.