질문게시판 > 질문있습니다.

인기검색어 > 아두이노 센서 ATMEGA128

최신글 질문게시판 동영상강좌 가입하기

▼ BASIC4MCU 후원업체 신제품 정보 ▼

▲ BASIC4MCU 후원업체 신제품 정보 ▲

BASIC4MCU > 질문게시판

질문있습니다.

페이지 정보

작성자 Busan 작성일19-12-27 01:28 조회95회 댓글1건

본문

​밑줄 친 부분은 제가 LCD 안정화 코드를 따온 것입니다. ​​신경 안쓰셔도 됩니다. 적

어둔 코드는 화재 감지기를 한 번 구현해본 것인데 가변 저항을 돌려 4.0V 이상 일 때 화재로 판단하여 LED 점등(PA7 단자) 및 스피커 알람, LCD에 fire 점등이며 평상시에는 전압만 출력합니다. 구동이 잘됩니다.

#include <mega128.h>       
#include <delay.h>

 

 

#define LINE2    0xC0    // 2nd Line Move
#define HOME    0x02    // Cursor Home
#define RSHIFT    0x1C    // Display Right Shift
#define LSHIFT    0x18    // Display Left Shift
#define DISPON    0x0c     // Display On                      
#define DISPOFF    0x08    // Display Off

void LCD_init(void);
void LCD_String(char flash *str);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);
void adc_display(void);

int adc_value = 0;
float Vref = 5.0, Vwarn = 4.0, Vdetect = 0;
int cnt_bell = 0;

void main(void)

    ADMUX = 0x00;
    ADCSRA = 0x87;
   
    ETIMSK = 0x04;
    TCCR3A = 0x00;
    TCCR3B = 0x04;
    TCNT3H = 0x85;
    TCNT3L = 0xED;
   
    DDRB = 0x30;
    DDRA = 0x80;
    PORTA = 0xff;
   
    SREG = 0x80;
   
    LCD_init();
    adc_display();
          
    while(1){ 
        ADCSRA = 0xc7;
        while((ADCSRA & 0x10) == 0);
        adc_value0 = (int)ADCL + ((int)ADCH << 8);
        Vdetect = (float)adc_value * Vref / 1024;  
    }             
}  
interrupt [TIM3_OVF] void timer_tin0 (void)
{
    TCNT3H = 0x85;
    TCNT3L = 0xED;
   
    if(Vdetect >= Vwarn){
        TCCR1A = 0x40;
        TCCR1B = 0x0a;
       
        if(cnt_bell == 0){
            PORTA = 0x00;
            OCR1A = 2082;
            Command(CLEAR);
            LCD_String("fire!!!");
            cnt_bell = 1;
            }
            else{
                PORTA = 0xff;
                OCR1A = 2777;
                Command(CLEAR);
                cnt_bell = 0;
            }
    }
    else{
        TCCR1A = 0x00;
        TCCR1B = 0x0a;
        PORTA = 0xff;
        adc_display();
    }
}  
void adc_display(void)
{
    int temp0 = 0, temp1 = 0, temp = 0;
   
    Command(CLEAR);
    LCD_String("Value:");

    temp = (int)(Vdetect * 10 + 0.5);
   
    temp1 = temp / 10;
    temp0 = temp % 10;
   
    Data(0x30 + temp1);
    LCD_String(".");
    Data(0x30 + temp0);
    LCD_String("V");
}   
// LCD 초기화 함수
void LCD_init(void)
{                         
    DDRC = 0xFF;    // 포트 C 출력 설정
    PORTC &= 0xFB;    //E = 0;
   
    // 충분한 지연시간을 통한 안정화 과정
     delay_ms(15);
    Command(0x20);    // D5=1
    delay_ms(5);
    Command(0x20);    // D5=1
    delay_us(100);
    Command(0x20);    // D5=1

    // 초기화 과정
    Command(0x28);    // function set
    Command(0x06);    // entry mode set
    Command(0x01);    // all clear
    Command(0x0c);    // display on
}

// 인스트럭션 쓰기 함수
void Command(unsigned char byte)
{
   Busy();

   // 인스트럭션 상위 바이트
   PORTC = (byte & 0xF0);   // 데이터  
   PORTC &= 0xFE;   // RS = 0;          
   PORTC &= 0xFD;   // RW = 0; 
   delay_us(1);    
   PORTC |= 0x04;   // E = 1;
   delay_us(1);
   PORTC &= 0xFB;   // E = 0;

   // 인스트럭션 하위 바이트
   PORTC = ((byte<<4) & 0xF0);   // 데이터
   PORTC &= 0xFE;   // RS = 0;
   PORTC &= 0xFD;   // RW = 0;
   delay_us(1);       
   PORTC |= 0x04;   // E = 1;
   delay_us(1);
   PORTC &= 0xFB;   // E = 0;
}

// 문자열 출력 함수
void LCD_String(char flash *str)
{                         
   char flash *pStr=0;

   pStr = str;  
   while(*pStr) Data(*pStr++);
}

// char flash : pointer declaration for program memory
// char eeprom : pointer declaration for EEPROM

//데이터 쓰기 함수
void Data(unsigned char byte)
{
   Busy();
       
   // 데이터 상위 바이트
   PORTC = (byte & 0xF0);   // 데이터
   PORTC |= 0x01;   //RS = 1;
   PORTC &= 0xFD;   //W = 0;
   delay_us(1);       
   PORTC |= 0x04;   //E = 1;
   delay_us(1);
   PORTC &= 0xFB;   //E = 0;

   // 데이터 하위 바이트
   PORTC = ((byte<<4) & 0xF0);     // 데이터
   PORTC |= 0x01;   //RS = 1;
   PORTC &= 0xFD;   //RW = 0;    
   delay_us(1);       
   PORTC |= 0x04;   //E = 1;
   delay_us(1);
   PORTC &= 0xFB;   //E = 0;
}

// Busy Flag Check -> 일반적인 BF를 체크하는 것이 아니라
// 일정한 시간 지연을 이용한다.
void Busy(void)
{
   delay_ms(2);
}


​위 코드와

 

#include <mega128.h>       
#include <delay.h>

#define LINE2    0xC0    // 2nd Line Move
#define HOME    0x02    // Cursor Home
#define RSHIFT    0x1C    // Display Right Shift
#define LSHIFT    0x18    // Display Left Shift
#define DISPON    0x0c     // Display On                      
#define DISPOFF    0x08    // Display Off

void LCD_init(void);
void LCD_String(char flash *str);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);
void degree_display(void);
void v_value(void);

int rot_base=375, rot_min=275, rot_max=475;
int rot_delta1=1, rot_delta2=4, rot_delta=0;
int rot_value=0, rot_dir=2;
int adc_value=0;
float Vref=5.0, f_val=0;
int temp10=0;

void main(void)
{
    DDRB=0xff;
    DDRF=0xff;
   
    ADMUX=0x00;   
    ADCSRA=0b10000111;
   
    ETIMSK=0b00000100;
    TCCR3A=0x00;
    TCCR3B=0b00000100;
    TCNT3H=0xE7;
    TCNT3L=0x96;
   
    TCCR1A=0b10000010;
    TCCR1B=0b00011011;
    ICR1H=0x09;
    ICR1L=0xc3;

    SREG=0b10000000;
   
    rot_value=rot_base;
    OCR1A=rot_value;

    LCD_init();
    degree_display();
   
      while(1)
    {
        v_value();
        
        if(temp10>0&&temp10<=15)
        {
            rot_dir=1;
            rot_delta=rot_delta2;
        }
        else if(temp10>15&&temp10<=20)
        {
            rot_dir=1;
            rot_delta=rot_delta1;
        }
        else if(temp10>30&&temp10<=35)
        {
            rot_dir=0;
            rot_delta=rot_delta1;
        }
        else if(temp10>35&&temp10<=50)
        {
            rot_dir=0;
            rot_delta=rot_delta2;
        }
        else
        {  
            rot_dir=2;
            OCR1A=rot_value;  
        }
       
    }
 
}

interrupt [TIM3_OVF] void timer_int3(void)
{
    TCNT3H=0xE7;
    TCNT3L=0x96;
       
    if(rot_dir==0)
    {
        if(rot_value<=rot_max)
        {
            rot_value+=rot_delta;
        }
        else
        {
            rot_value=rot_max;
        }
        OCR1A=rot_value;
    }
 
    else if(rot_dir==1)                                                                                                                   
    {
        if(rot_value>=rot_min)
        {
            rot_value-=rot_delta;
        }
        else
        {
            rot_value=rot_min;
        }
        OCR1A=rot_value;
    } 
       
    degree_display();       
}
void v_value(void)
{
    ADCSRA=0b11000111;
    while((ADCSRA&0x10)==0);
    adc_value=(int)ADCL+((int)ADCH<<8);
   
    f_val=(float)adc_value*Vref/1024;
    temp10=(int)(f_val*10+0.5);   
}

void degree_display(void)
{
    float degree_value=0;
    int temp0=0, temp1=0, temp2=0, temp=0;
    int v1=0, v2=0;
                        
    Command(HOME);
    LCD_String("Degree : ");
   
    if(rot_value>=rot_base)
    {                  
        degree_value=(float)(rot_value-rot_base)*80/200;
        LCD_String("+");  
    }
    else
    {
        degree_value=(float)(rot_base-rot_value)*80/200;
        LCD_String("-");
    }
   
    temp=(int)(degree_value*10);
   
    temp2=temp/100;
    temp=temp%100;
    temp1=temp/10;
    temp0=temp%10;
   
    Data(0x30+temp2);
    Data(0x30+temp1);
    LCD_String(".");
    Data(0x30+temp0);
   
    Command(LINE2);
    LCD_String("Value : ");
   
    v1=temp10/10;
    v2=temp10%10;
   
    Data(0x30+v1);
    LCD_String(".");
    Data(0x30+v2);
    LCD_String("V");
}
// LCD 초기화 함수
void LCD_init(void)
{                         
   DDRC = 0xFF;   // 포트 C 출력 설정
   PORTC &= 0xFB;   //E = 0;
  
   // 충분한 지연시간을 통한 안정화 과정
    delay_ms(15);
   Command(0x20);   // D5=1
   delay_ms(5);
   Command(0x20);   // D5=1
   delay_us(100);
   Command(0x20);   // D5=1

   // 초기화 과정
   Command(0x28);   // function set
   Command(0x06);   // entry mode set
   Command(0x01);   // all clear
   Command(0x0c);   // display on
}
// 인스트럭션 쓰기 함수
void Command(unsigned char byte)
{
   Busy();

   // 인스트럭션 상위 바이트
   PORTC = (byte & 0xF0);   // 데이터  
   PORTC &= 0xFE;   // RS = 0;          
   PORTC &= 0xFD;   // RW = 0; 
   delay_us(1);    
   PORTC |= 0x04;   // E = 1;
   delay_us(1);
   PORTC &= 0xFB;   // E = 0;

   // 인스트럭션 하위 바이트
   PORTC = ((byte<<4) & 0xF0);   // 데이터
   PORTC &= 0xFE;   // RS = 0;
   PORTC &= 0xFD;   // RW = 0;
   delay_us(1);       
   PORTC |= 0x04;   // E = 1;
   delay_us(1);
   PORTC &= 0xFB;   // E = 0;
}

// 문자열 출력 함수
void LCD_String(char flash *str)
{                         
   char flash *pStr=0;

   pStr = str;  
   while(*pStr) Data(*pStr++);
}

// char flash : pointer declaration for program memory
// char eeprom : pointer declaration for EEPROM

//데이터 쓰기 함수
void Data(unsigned char byte)
{
   Busy();
       
   // 데이터 상위 바이트
   PORTC = (byte & 0xF0);   // 데이터
   PORTC |= 0x01;   //RS = 1;
   PORTC &= 0xFD;   //W = 0;
   delay_us(1);       
   PORTC |= 0x04;   //E = 1;
   delay_us(1);
   PORTC &= 0xFB;   //E = 0;

   // 데이터 하위 바이트
   PORTC = ((byte<<4) & 0xF0);     // 데이터
   PORTC |= 0x01;   //RS = 1;
   PORTC &= 0xFD;   //RW = 0;    
   delay_us(1);       
   PORTC |= 0x04;   //E = 1;
   delay_us(1);
   PORTC &= 0xFB;   //E = 0;
}

// Busy Flag Check -> 일반적인 BF를 체크하는 것이 아니라
// 일정한 시간 지연을 이용한다.
void Busy(void)
{
   delay_ms(2);
}

 

위 코드는

 

RC 서보 모터를 시작할 때 0도로 설정하고

 

가변저항의 값을

 

3V - 3.5V 구간으로 조정하면, CW 방향으로 100msec 단위로 0.4도씩 증가

 

3.5V - 5V 구간으로 조정하면, CW 방향으로 100msec 단위로 1.6도씩 증가

 

2V -1.5V 구간으로 조정하면, CCW 방향으로 100msec 단위로 0.4도씩 증가

 

1.5V - 0V 구간으로 조정하면, CCW 방향으로 100msec 단위로 1.6도씩 증가

 

2-3V 구간으로 조정하면, 모터 현재 각도를 유지하고 현재 각도를 LCD에 출력하게 끔 코딩했습니다. 잘 돌아갑니다.

 

제가 하고 싶은것은 위 코드 2개를 이용하여 0 - 1.5V까지는 서보모터가 약하게 돌며

                                                                      1.5V - 3V까지는 중간으로 돌며

                                                                      3V - 4V가 되면 빠르게 돌면서

                                                                      4V에 도달 시  화재로 판단하여 LED 점등(PA7 단자) 및 스피커 알람, LCD에 fire 점등을 하고 싶습니다.

 

 따로 따로는 가능한데 둘을 취합하는 과정에서 자꾸 문제가 생겨 문의합니다...

오늘 답변은 정말 감사했습니다.

 



  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

댓글 : 1

조회수 : 95

master님의 댓글

master 작성일

무슨 문제가 생긴다는 것인지 상세하게 적으셔야합니다.
전체를 봐드리려면 보드가 있어야합니다.
보드가 없어서 불가능하므로 답변이 가능한 부분을 질문해주세요

게시물 검색

BASIC4MCU > 질문게시판 목록

제목 날짜
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은… 스태프  19-01-15
공지 사이트 이용 안내 댓글[10] master  17-10-29
공지 [무료 공개] 소스코드 하이라이트 v2.0 beta [… 댓글[1] 첨부파일master  18-01-23
질문 두더지 정리본입니다. 아두이노배우기 새글 20-02-28
답변 답변 : 두더지 정리본입니다. master 새글 20-02-28
답변 답변 : 답변 : 두더지 정리본(늦은시간에 죄송합니다.… 아두이노배우기 새글 01:52
답변 답변 : 답변 : 답변 : 두더지 정리본(늦은시간에 죄… master 새글 08:19
답변 답변 : 답변 : 답변 : 답변 : 두더지 정리본(늦은… 댓글[3] 아두이노배우기 새글 16:09
질문 아두이노 두더지 잡기 아두이노배우기  20-02-27
답변 답변 : 아두이노 두더지 잡기 댓글[1] master  20-02-27
질문 아두이노+스텝모터+L298N 질문드립니다. 첨부파일빈군  20-02-27
답변 답변 : 아두이노+스텝모터+L298N 질문드립니다. 댓글[3] master  20-02-27
질문 STM32 MCU DFSDM기능 문의 댓글[1] 첨부파일Hongchoon  20-02-26
질문 DC모터 제어중 부저 추가 댓글[2] 아두이노배우기  20-02-25
질문 적외선 DC모터 제어 아두이노배우기  20-02-25
답변 답변 : 적외선 DC모터 제어 댓글[1] master  20-02-25
질문 아두이노 IDE (ino파일) 로 업로드 하면 작동되는… 댓글[1] 첨부파일이츠라  20-02-25
질문 atmega128 while 속 if문 실행 문제 이동욱  20-02-24
답변 답변 : atmega128 while 속 if문 실행 … master  20-02-24
질문 Limit Sensor 를 이용한 LED의 자동 작동에… 첨부파일아두이프로  20-02-24
답변 답변 : Limit Sensor 를 이용한 LED의 자… 댓글[1] master  20-02-24
질문 HC-11을 이용하여 1:N 통신중입니다. 댓글[4] 아두이노배우기  20-02-23
질문 스텝모터 정지 댓글[2] 아두이노배우기  20-02-23
답변 답변 : 스텝모터 정지 댓글[2] master  20-02-23
질문 정말 감사합니다. 박취  20-02-19
질문 ov9655카메라와 stm32f4 보드를 이용한 영상처… 댓글[7] flap  20-02-19
질문 GLCD 텍스트 출력 댓글[2] 전자학습자  20-02-17
질문 아두이노 HC-11 통신관련입니다. 아두이노배우기  20-02-15
답변 답변 : 아두이노 HC-11 통신관련입니다. master  20-02-16
답변 답변 : 답변 : 아두이노 HC-11 통신관련입니다. 아두이노배우기  20-02-16
게시물 검색


Privacy Policy
MCU BASIC ⓒ 2017
PC버전