질문게시판 > 코드비젼, mega128을 이용한 타이머 인터럽트 사용한 모터의 키제어(2)

TODAY365 TOTAL2,175,673
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | 코드비젼, mega128을 이용한 타이머 인터럽트 사용한 모터의 키제어(2)

페이지 정보

작성자 방구석MCU 작성일2020-11-11 00:16 조회3,420회 댓글1건

본문

	

안녕하세요 마스터님

마스터님이 말씀해주신 대로 keypress() 루틴에서

딜레이나 lcd루틴을 빼고, 주석처리를 하니 버튼을 누를 때, 모터가 부드럽게 회전하였습니다.

감사합니다. 근데 한 가지 또 문제가 있는데, 

아래 코드를 보시면 모터 스피드를 UP, DOWN시키는 키를 한번 누를 때마다 스피드가 일정하게 증가하는(+20)

것이 아니라 갑자기 PWM = 240 풀스피드로 증가하거나 풀스피드에서 최저 속도로 내려오는 등 버튼이 한번 누를 때 

여러번 눌린것으로 ATMEGA128이 판단하는 거 같습니다. 

혹시 무엇이 문제인지 알려주실 수 있으신가요?

 

#include <io.h>

#include <mega128.h>

#include <stdio.h>

#include <delay.h>          

#include "mydef_ver3.h"      

#include "lcd.h"

 

// Declare your global variables here

 

u08 sec;

u08 time_count;

bit time_flag;        

u16 tmp_buf[10];

u08 tmp_index;

u08 lcd_mode;

u08 temp;

u08 pwm;

bit over;

 

u08 str_motor[] = "MOTOR CO";

u08 str_name[] = "NTROLLER";

u08 str_start[] = "TART]";

u08 str_welcome[] = "WELCOME:";

u08 str_title1[] = "DESIGNED";

u08 str_title2[] = " BY KYT";                      

u08 str_keyread[] = "Key-scan";                   

u08 str_press[] = "PRESS [S";

u08 str_ad[] = "AD-VALUE";

u08 str_second[] = "SECOND: ";

u08 str_pwm[] = "PWM ";

u08 str_duty[] = "DUTY";

 

u08 str_blank[] = "       ";

u08 str_cw[] = "CW";

u08 str_ccw[] = "CCW";

unsigned char direction='x'; 

volatile unsigned char Hall;

volatile unsigned int count;

volatile unsigned int i;

 

 

void lcdcontrol(void);

void pwm1_control(u08 a);        

void step(void);

void keypress();

void beep(void);

 

void pwm_upcontrol(void)

{

        if(pwm >= 240) 

        pwm = 240;  

        else

        {

        pwm = pwm + 20;

        }

        OCR1AL = pwm;

        OCR1BL = pwm;

        OCR1CL = pwm;  

}

 

 

void pwm_downcontrol(void)

{

       if(pwm <= 20) 

        pwm = 20;

       else

       {

       pwm = pwm -20;

       }     

       OCR1AL = pwm;

       OCR1BL = pwm;

       OCR1CL = pwm;

}

 

 

 

 

void keypress(void)

{

u08 old_key = 0;

u08 new_key;

new_key = KEY_IN & KEY_MASK;        

      

        if(new_key!=old_key){

                     

         switch(new_key){ 

          case START:  

          /* lcd_home();    

           lcd_clear(); 

           lcd_control_write(0x80);            

           lcd_print_data(str_pwm,4);

           lcd_control_write(0xC0);            

           lcd_print_data(str_duty,4);*/ 

          if(pwm == 0 || direction == 'x')

          {

        

           if(temp == 0)

           {  

           temp = 20;

           }

           direction = '+';

           pwm = temp;

          } 

              

           

          else if(direction == '+' || direction == '-')

          {  

            for(;pwm=0;)

            {

            pwm = pwm - 20; 

            delay_ms(50);

            }  

            PORTD = 0x00;

            direction = 'x';     

          }

         

          break;  

            

          case CW:

                  

          if(direction == '+')

          { 

           for(; pwm==0; pwm = pwm - 20)

            {

            delay_ms(50); 

            }

            

           direction = '-' ;  

           

           

            for(; pwm == temp; pwm = pwm + 20)

            {

            delay_ms(500);

            }

          }   

          

          else if(direction == '-')

          {  

          for(; pwm == 0; pwm = pwm - 20)

            {

            delay_ms(500); 

            }               

            

            direction = '+' ;

            

          for(; pwm == temp; pwm = pwm + 20)

            {

            delay_ms(500);

            }

            }

           

          break;

        

          case UP:

                  pwm_upcontrol();

                  break;      

                         

          case DOWN:    

                  pwm_downcontrol();            

                  break;                      

         } 

    

          step();                

          /*pwm1_control(temp);                    

          lcd_control_write(0xC7);            

          lcd_print_data("%",1);*/  

        }   

        old_key = new_key;                                                  

    }

 

 

void step(void)

{    

     

    Hall = PIND & 0x38;

       

    if(direction == '+')

    {if(Hall == 0x10)  //CW

      {

      OCR1AL;

      PORTD = 0b00000100;

      } // CW 0~60 

     

          

     else if(Hall == 0x30)

     {

     OCR1BL;

      PORTD = 0b00000100;

     } 

       // CW 60~120

    

    else if(Hall == 0x20)

    {

    OCR1BL;  

    PORTD = 0b00000001;

    } 

   

       // 120~180

   

    else if(Hall == 0x28)

     {

     OCR1CL;

     PORTD = 0b00000001;

     } 

  

     //180~240

   

    else if(Hall == 0x08)

     {OCR1CL;

    PORTD = 0b00000010;}

   

     //240~300

 

    else if(Hall == 0x18)

     {

     OCR1AL;

     PORTD = 0b00000010;

     }    

    //300~360        

      }     

      

    else if(direction == '-')

    {if(Hall == 0x20)   //CCW

       {

       OCR1AL;

       PORTD = 0b00000010;

       } 

        // CCW 0~60 

       

    else if(Hall == 0x30)

     {

     OCR1CL;

     PORTD = 0b00000010;

     }

       // CCW 60~120

    

    else if(Hall == 0x10)

     {

     OCR1CL;

     PORTD = 0b00000001;

     }

       // CCW 120~180

   

    else if(Hall == 0x18)

    {

    OCR1BL;  

    PORTD = 0b00000001;

    }  

     // CCW 180~240

   

     else if(Hall == 0x08)

     {

     OCR1BL;

      PORTD = 0b00000100;

     }  

      // CCW 240~300               

 

     else if(Hall == 0x28) 

      {

      OCR1AL;

      PORTD = 0b00000100;

      }

     // CCW 300~360    

    }

  }      

 

void beep(void)

{

  BUZ_RLY = BUZ_RLY | BUZZER_ON; 

  delay_ms(100);

  BUZ_RLY = BUZ_RLY & BUZZER_OFF;       

}

      

 

void pwm1_control(u08 x)

{

u08 l,m,n,o,p;

s16 duty_ratio;      

             

     l = 0x30+ (x/100);

     m = 0x30+ (x%100)/10;

     n = 0x30+ (x%10);

     lcd_control_write(0x84);            

     lcd_data_write(l);

     lcd_data_write(m);

     lcd_data_write(n);

     

     duty_ratio = x*0.39;           //100/255

     o = 0x30+ duty_ratio/10;

     p = 0x30+ duty_ratio%10;

     lcd_control_write(0xC5);            

     lcd_data_write(o);

     lcd_data_write(p);                    

}

 

#define ADC_VREF_TYPE 0x20              //AD0 INPUT

 

 

 

 

// Timer 0 overflow interrupt service routine

interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{

// Reinitialize Timer 0 value

   TCNT0=0x28;

// Place your code here  

    if(count == 1)

    {   

    keypress();

    count = 0; 

    i = i + 1;

    } else count = count + 1;

 

}

 

void main(void)

{

// Declare your local variables here

u08 i;

u08 a,b,c;

u08 old_key,new_key;

 

 

    DDRA = 0x00;

    PORTA = 0x00;      //LCD DATA PORT

    

    

    DDRB = 0xF0;        //INPUT & OUTPUT MODE

    PORTB = 0xEF;

    delay_ms(3);    // 상단 커패시터 충전

    PORTB = 0x0F;

    

    DDRC = 0xF0;

    PORTC =0x0F;       //BCD KEY INPUT AND LCD CONTROL PORT    

    

    DDRD= 0x07;

    PORTD=0x00;        //Hole sensor & Low input

    

    DDRE = 0x00;

    PORTE =0x00 | (0x03 << 6);

    

    DDRF = 0x00;

    PORTF =0x00;       //CURRENT SENSING

    

    DDRG = 0xFF;

    PORTG = 0x00;      //BUZZER AND RELAY CONTROL PORT  

 

 

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 10.800 kHz

// Mode: Normal top=0xFF

// OC0 output: Disconnected

// Timer Period: 20 ms

ASSR=0<<AS0;

TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);

TCNT0=0x28;

OCR0=0x00;

 

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 43.200 kHz

// Mode: Ph. correct PWM top=0x00FF

// OC1A output: Non-Inverted PWM

// OC1B output: Non-Inverted PWM

// OC1C output: Non-Inverted PWM

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer Period: 11.806 ms

// Output Pulse(s):

// OC1A Period: 11.806 ms Width: 0.97222 ms

// OC1B Period: 11.806 ms Width: 0.97222 ms

// OC1C Period: 11.806 ms Width: 0.97222 ms

// Timer1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

// Compare C Match Interrupt: Off

TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<COM1C1) | (0<<COM1C0) | (0<<WGM11) | (1<<WGM10);

TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x15; // PWM 1

 

OCR1BH=0x00;

OCR1BL=0x15; // PWM 2

 

OCR1CH=0x00;

OCR1CL=0x15; // PWM 3

 

 

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);

ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);

 

EICRA=(0<<ISC31) | (0<<ISC30) | (0<<ISC21) | (0<<ISC20) | (0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);

EICRB=(0<<ISC71) | (0<<ISC70) | (0<<ISC61) | (0<<ISC60) | (0<<ISC51) | (0<<ISC50) | (0<<ISC41) | (0<<ISC40);

EIMSK=(0<<INT7) | (0<<INT6) | (0<<INT5) | (0<<INT4) | (0<<INT3) | (0<<INT2) | (0<<INT1) | (0<<INT0);

 

// USART0 initialization

// USART0 disabled

UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);

 

// USART1 initialization

// USART1 disabled

UCSR1B=(0<<RXCIE1) | (0<<TXCIE1) | (0<<UDRIE1) | (0<<RXEN1) | (0<<TXEN1) | (0<<UCSZ12) | (0<<RXB81) | (0<<TXB81);

 

// Analog Comparator initialization

// Analog Comparator: Off

// The Analog Comparator's positive input is

// connected to the AIN0 pin

// The Analog Comparator's negative input is

// connected to the AIN1 pin

ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);

SFIOR=(0<<ACME);

 

// ADC initialization

// ADC disabled

ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

 

  ADMUX=ADC_VREF_TYPE & 0xff;

    ADCSRA=0x87;

 

    lcd_mode = 1;

    

    lcd_init();

    lcd_clear();

    lcd_home();

 

    lcd_control_write(0x80);

    lcd_print_data(str_motor,8);

    lcd_control_write(0xC0);        

    lcd_print_data(str_name,8);    

        

    delay_ms(3000);

 

    lcd_home();    

    lcd_clear();

 

    lcd_control_write(0x80);

    lcd_print_data(str_title1,8);    

       

    lcd_control_write(0xC0);        

    lcd_print_data(str_title2,7);    

        

    delay_ms(3000);

 

    lcd_home();    

    lcd_clear();  

     

    lcd_control_write(0x80);            

    lcd_print_data(str_press,8);

    

    lcd_control_write(0xC0);            

    lcd_print_data(str_start,5); 

    

    /*lcd_home();    

    lcd_clear(); 

 

    lcd_control_write(0x80);            

    lcd_print_data(str_pwm,4);

 

    lcd_control_write(0xC0);            

    lcd_print_data(str_duty,4); */     

         

 

//*********************** SECTION m8 *******************         

 //    #asm("sei")

//*********************** SECTION m9 ********************

 

    BUZ_RLY = 0x00;

    old_key = 0;    

 

//*********************** SECTION m10 ********************    

    while (1)

    {

      keypress(); 

    } 

    

}

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

댓글 1

조회수 3,420

master님의 댓글

master 작성일

코드가 길어서 상세하게 봐드릴 시간은 없고요
추측컨데
예를들면 0.3초 동안 키를 누른다면
10ms마다 키를 체크하는 경우 30번 키 체크가 됩니다.
금새 최고점까지 올라가게 되겠죠
이를 해결하기 위한 방법으로는
엣지검출해서 오래 누르고 있어도 1회만 키가 누른 것으로 체크 하든지
키를 누르면 처리를 한 후 변수를 set 시키고, 변수가 set 되어 있으면 키를 누르지 않을 때까지 아무런 처리를 하지 않다가, 키를 누르지 않으면 변수를 clear 시켜서 다시 키를 입력 받을 수 있는 상태로 두는 방법도 있습니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 9698
공지 사이트 이용 안내댓글[24] master 17-10-29 29853
질문 esp32를 이용한 피에조부저 이미지새글 ejdog 22-05-27 12
질문 아두이노 서보모터 무한회전 문제 해결을 어떻게 해야할까요 새글 GinGer 22-05-27 16
답변 답변글 답변 : 아두이노 서보모터 무한회전 문제 해결을 어떻게 해야할까요 새글 master 22-05-27 17
질문 모터 엔코더 제어 질문드립니다. 새글 oreoreo 22-05-27 19
답변 답변글 답변 : 모터 엔코더 제어 질문드립니다. 새글 master 22-05-27 14
질문 아두이노 RF무선통신 관련 질문입니다.댓글[2] 새글 메론맛드링크 22-05-27 19
질문 아두이노 속도측정, 속도를 LCD에 표시, 가까워지면 부저 새글 wgtjdwls 22-05-27 20
답변 답변글 답변 : 아두이노 속도측정, 속도를 LCD에 표시, 가까워지면 부저 새글 master 22-05-27 17
질문 블루투스 관련 코드 도와주세요 새글 scape 22-05-27 19
답변 답변글 답변 : 블루투스 관련 코드 도와주세요 새글 master 22-05-27 16
질문 ATmega128 1602A LCD 출력 질문입니다.댓글[2] 새글 444222a 22-05-27 32
질문 ATmega128 스위치 채터링 관련 질문드립니다댓글[3] 새글 yeon 22-05-27 35
질문 마이크로칩 스튜디오 코드 해석 새글 최선을다하자 22-05-27 20
답변 답변글 답변 : 마이크로칩 스튜디오 코드 해석 새글 master 22-05-27 17
질문 적외선 거리 센서로 블루투스 알람 설정 코딩...댓글[1] 새글 ededed 22-05-26 22
질문 아두이노 api 질문댓글[1] 새글첨부파일 리니어 22-05-26 21
질문 atmega128 키패드 입력 오류에 대하여 질문 있습니다.댓글[2] 새글 마프하나 22-05-26 50
질문 초음파센싱을 통한 리니어벨트 (스텝모터사용) 조건문댓글[1] 새글 아두이노대학 22-05-26 31
질문 아트메가128/ srf05 초음파센서를 이용한 타이머 인터럽트 질문입니다 새글 아트메가넘어려워 22-05-26 31
답변 답변글 답변 : 아트메가128/ srf05 초음파센서를 이용한 타이머 인터럽트 질문입니다 새글 master 22-05-26 31
질문 atmega128에서 스위치1개는LED, 스위치 1개는 세그먼트의 동작하게 하려는데.. aasdw 22-05-26 59
답변 답변글 답변 : atmega128에서 스위치1개는LED, 스위치 1개는 세그먼트의 동작하게 하려는데..댓글[1] 새글 master 22-05-26 34
질문 Atmega128 블루투스 오류 질문 yhj2644 22-05-26 58
답변 답변글 답변 : Atmega128 블루투스 오류 질문 새글 master 22-05-26 33
질문 아두이노 간단한 프로그램 행복지수업 22-05-25 49
답변 답변글 답변 : 아두이노 간단한 프로그램 새글 master 22-05-26 31
질문 atmega128 타이머 작성시 키패트 입력으로 인터럽트 사용에 대하여 질문이 있습니다.댓글[1] 이미지 마프하나 22-05-25 89
질문 로드셀 무게 센서 질문드립니다.댓글[2] 제비고기 22-05-25 58
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기