BASIC4MCU | 질문게시판 | atmega128 온습도센서 사용하여 자동문개방
페이지 정보
작성자 졸업준비메카 작성일2020-12-08 15:06 조회4,119회 댓글1건본문
atmega128 소자를 사용하고, 초음파 센서로 일정거리다가오면 am2302(dht12)소자가 작동하여 온습도를 측정하고 36.5도 이하이면 모터가 작동하는 코드를 작성하였습니다.
codevision AVR 프로그램 사용하고 있습니다.
코드를 짜고서 빌드 하였는데 오류가 없다고 나오길래 된건가 싶었는데 다른 코드 빌드가 되어서 오류가 없다고 나왔습니다.
참고한 코드는 오실로스코프를 이용한 온습도 센서를 참고하였고 코드를 짜봤는데 다시 하니 오류가 8개가 있었습니다.
Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(40): function doesn't match its previous declaration from file: 'C:\cvavreval\inc\alcd.h', line: 36
Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(59): undefined symbol 'data'
Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(61): the first argument of the '.' operator must be of 'struct' or 'union' type
Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(81): undefined symbol 'data'Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(85): undefined symbol 'data'
Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(88): undefined symbol 'data'
Error: C:\Users\김주현\Desktop\3학년2학기\마프실험\r12\r12.c(197): operand types 'unsigned char [40]' and 'int' are incompatible with the '>' operator
이렇게 에러가 발생하였습니다.
(c61)은 사이트를 찾다가 portf가 비트출력이 안된다고 하시는 댓글을 보고 PORTF|=1; DDRF&=~1; 로 변경하여 에러를 고치긴 하였습니다.
현재 저희가 포트A 부터 G까지 모두 사용하고 있는데 찾아보니까 비트 출력이 안되는 포트가 있다고 하시던데 어떤 말씀이신지 궁금합니다.
한번만 도와주시면 감사하겠습니다 ㅠㅠ
#include <mega128.h> //atmega128을 사용하기위한 헤더파일
#include <alcd.h> //케릭터 lcd를 사용하기위한 헤더파일
#include <Delay.h> //delay 함수 라이브러리를 불러오기 위한 헤더파일
#include <stdio.h> //범용 입출력 함수용 헤더 sprintf를 사용하기 위한 헤더파일#define AM2302 PINF.4 //F포트의 4번핀을 AM2302로 정의
#define Echo PINC.4 //C포트의 4번핀을 Echo로 정의unsigned int half_usec,Temp,Humi; //온도, 습도 정의
unsigned char lcd_data[40], Temp_sign; //40bit의 unsigned char형의 변수선언
//[lcd] [AVR PortC]
//RS (pin4) ----- bit 0
//RD (pin 5) ----- bit 1
//EN (pin 6) ----- bit 2
//사용안함 bit 3
//[lcd] [AVR PortA]
//DB4 (pin 11) --- bit 4
//DB5 (pin 12) --- bit 5
//DB6 (pin 13) --- bit 6
//DB7 (pin 14) --- bit 7
//
#define lcd_RS PORTA.0
#define lcd_E PORTA.2
#define lcd_Out PORTA // PORTA.4~7 4bitsvoid lcdData(char d){
lcd_RS=1;
lcd_Out=(d&0xF0)|1; lcd_E=1; delay_us(1); lcd_E=0; delay_us(1);
lcd_Out=(d<<4)|1; lcd_E=1; delay_us(1); lcd_E=0; delay_us(40);
}
//
void lcdCmd(char c){
lcd_RS=0;
lcd_Out=c&0xF0; lcd_E=1; delay_us(1); lcd_E=0; delay_us(1);
lcd_Out=c<<4; lcd_E=1; delay_us(1); lcd_E=0; delay_us(40);
}
//
void lcd_init(void){
delay_ms(50);
lcdCmd(0x28); lcdCmd(0x28); lcdCmd(0x28);
lcdCmd(0x0C); lcdCmd(0x06); lcdCmd(0x01); delay_ms(2);
}
//
void lcd_gotoxy(char x, char y){
if (y==0)lcdCmd(0x80+x);
else if(y==1)lcdCmd(0xC0+x);
else if(y==2)lcdCmd(0x94+x);
else if(y==3)lcdCmd(0xD4+x);
}void lcd_puts(char *str){ while(*str)lcdData(*str++); }
//
void lcd_putsf(char flash *str){ while(*str)lcdData(*str++); }void AM2302_rd(void){
unsigned char i,k;
for(i=0;i<8;i++)data[i]=0; // 변수 초기화
//host start signal
DDRF|=1; delay_ms(1); DDRF&=~1; // 데이터 요구
//released time
TCNT1=0; TCCR1B=2; while( AM2302); TCCR1B=0; half_usec=TCNT1; // high_time
if((half_usec<30)||(half_usec>410))goto AM2302_Error; // 30us high 측정, (min20~max200us),실측 20us
//response AM2302
TCNT1=0; TCCR1B=2; while(!AM2302); TCCR1B=0; half_usec=TCNT1; // low_time
if((half_usec<140)||(half_usec>180))goto AM2302_Error; // 80us low 측정, (min75~max85us),실측 80us
//
TCNT1=0; TCCR1B=2; while( AM2302); TCCR1B=0; half_usec=TCNT1; // high_time
if((half_usec<140)||(half_usec>180))goto AM2302_Error; // 80us high 측정, (min75~max85us),실측 80us
//
for(k=0;k<5;k++){
for(i=0;i<8;i++){
//pulse
TCNT1=0; TCCR1B=2; while(!AM2302); TCCR1B=0; half_usec=TCNT1; // low_time
if((half_usec<85)||(half_usec>150))goto AM2302_Error; // 50us low(min48~max55us),실측 56us,68us
//
TCNT1=0; TCCR1B=2; while( AM2302); TCCR1B=0; half_usec=TCNT1; // high_time
if((half_usec<34)||(half_usec>165))goto AM2302_Error; // 26us & 70us high(min22~max75us),실측 24us,72~76us
//
if(half_usec>96)data[k]|=0x80>>i; // high구간 48us이상이면 1
}
}
//Parity(check sum)check
i=data[0]+data[1]+data[2]+data[3];
if(i!=data[4])goto AM2302_Error; //Parity error
//data copy
Humi=(unsigned int)data[0]*256+data[1];
Temp=(unsigned int)data[2]*256+data[3];
//Temp 영하 체크
if(Temp&0x8000){ Temp_sign=1; Temp&=0x7FFF; } // 영하
else Temp_sign=0; // 영상
return;
AM2302_Error:;
Humi=Temp=0; Temp_sign=0;
}// Echo - 초음파 센서 (PORTB 사용)
unsigned int getEcho(void) //getEcho함수를 정의
{
unsigned int range=0; //range변수를 선언하고 0으로 초기화
PORTD = 0x70;
delay_us(10);
PORTD = 0x60;
while(!Echo); //D포트의 4번 핀이 0인동안 반복
{
TCNT1=0x00; //카운트 레지스터 초기화
TCCR1B=0x02; //분주비를 8로설정
}
while(Echo); //D포터의 4번 핀이 1인동안 반복
{
range=TCNT1/200; //range에 TNCT1을 200으로 스케일링
return (range); //range값을 반환
}
}void main(void)
{
unsigned int range =0; //range변수를 선언하고 0으로 초기화
unsigned char str[50];
//타이머 카운터 초기화
TCCR1A=0x00; //타이머 카운터를 제어하는 레지스터A에 전부 0을 넣음
TCCR1B=0x00; //타이머 카운터를 제어하는 레지스터A에 전부 0을 넣어 카운터 정지
TCCR3A=0x00; //타이머 카운터를 제어하는 레지스터A에 전부 0을 넣음
TCCR3B=0x00; //타이머 카운터를 제어하는 레지스터A에 전부 0을 넣어 카운터 정지
//lcd포트 초기화
DDRA = 0x00;
PORTA = 0x00;
//자동문 모터제어
DDRB=0x60;
PORTB=0x00;
TCCR1A=0x40;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x0A;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
//손소독제 모터 제어
DDRE=0x18;
PORTE=0x00;TCCR3A=0x40;
TCCR3B=0x0A;TCNT3H=0x00;
TCNT3L=0x00;ICR3H=0x00;
ICR3L=0x00;OCR3AH=0x0A;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;
//trigger신호를 내보내기위한 PORTB.4를 출력모드로 설정
DDRD = 0x10; //포트D의 4번 핀에 초음파를 세는 명령을 시킴
PORTD = 0x00;
//PORTC를 입력으로 설정 초기화 getEcho용
DDRC = 0x00;
PORTC = 0x00;
//led포트 초기화
DDRG=0xFF;
PORTG=0xFF;
// DDRF초기화 - 열 감지 센서
lcd_init(16); //lcd부팅용 초기화 함수#asm("sei") //모든 인터럽트 허용
while(1)
{
range = getEcho();
if(lcd_data>300)
{
PORTG = 0x00; //led 꺼짐
}
else
{
PORTG = 0xff; //led 켜짐
delay_ms(500); // AM2302 데이터 요구 주기
AM2302_rd();
lcd_clear();
lcd_gotoxy(0,0);
sprintf(str, "Temp=%d.%d\xdfC ", Temp/10, Temp%10);
lcd_puts(str);
delay_ms(1000);
if(Temp<37)
{
//세정제 모터 동작 코드
TCCR3A=0x40;
PORTE = 0b0000000;
delay_ms(3000);
TCCR3A=0x00;
delay_ms(3000);
TCCR3A=0x40;
PORTE = 0b0100000;
delay_ms(3000);
TCCR3A=0x00;
delay_ms(3000);
//자동문 모터동작 코드
TCCR1A=0x40;
PORTB = 0b00000000; //모터 문열림 방향
delay_ms(3000); //3초간 문열림
TCCR1A=0x00; //모터정지
delay_ms(6000); //6초간 유지
TCCR1A=0x40;
PORTB=0b01000000; //모터 문닫힘 방향
delay_ms(3000); //3초간 문닫힘
TCCR1A=0x00; //모터 정지
}
else
{
lcd_gotoxy(0,1);
sprintf(lcd_data, "can not come in");
delay_ms(1000);
}
}
}
}
댓글 1
조회수 4,119master님의 댓글
master 작성일
128 경우 (mcu 디바이스별로 다릅니다.)
포트F는 입트 입력이 가능하고, 비트 출력은 불가능합니다.
포트G는 비트입력 및 비트출력 모두 안됩니다.
128 mcu 개발 할 때에 그렇게 설계되어 있는 부분이며
코드비젼은 설계자 의도에 맞게 정확하게 구현되어 있습니다.
비트 입출력이 안되는 것은 비트마스크 방법을 사용해서 제어하세요