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

TODAY1,805 TOTAL10,480,229
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

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


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

페이지 정보

작성자 방구석MCU 작성일2020-11-11 00:16 조회15,601회 댓글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

조회수 15,601

master님의 댓글

master 작성일

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

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 24599
공지 사이트 이용 안내댓글[31] master 17-10-29 39536
질문 8체널 릴레이 delay 타임에 대한 질문입니다댓글[1] 왕왕초a 25-06-06 120
답변 답변글 답변 : 8체널 릴레이 delay 타임에 대한 질문입니다댓글[4] master 25-06-06 358
답변 답변글 답변 : 답변 : 8체널 릴레이 delay 타임에 대한 질문입니다 master 25-06-09 81
질문 tip42C 관련 질문입니다.댓글[4] 이미지첨부파일 노크공돌 25-05-30 789
질문 24V 모터를 구동하기 위해서 배터리 사용댓글[3] EYEbot 25-05-24 253
질문 ATMEGA128 외부 인터럽트 수행.댓글[2] 이미지첨부파일 소고기카레 25-05-11 487
질문 아두이노 메가 esp32-cam 질문입니다.댓글[1] 문외한사람 25-04-29 414
질문 esp32와 pms7003연결해서 데이터를 받고 싶은데 에러가 떠요댓글[1] 이미지첨부파일 boar 25-03-27 436
질문 DLM-64DCAA 고장나서 수리하고 싶습니다댓글[2] 이미지첨부파일 공부하고싶은콩 25-03-11 865
질문 로봇 얼굴 제작에 대하여 질문드립니다.댓글[4] 카모킹스 25-03-03 2748
질문 모터와 모터드라이브 질문있습니다댓글[1] ponyo 25-02-19 659
질문 공통음극형 FND를 9V로 동작하게 하고 싶어요.댓글[7] 멘토 25-01-21 7541
질문 oled 모듈 연결 질문입니다!댓글[1] 펌린이 24-12-17 724
질문 Atmega 128 타이머 질문있습니다댓글[1] ednda 24-12-11 729
답변 답변글 답변 : Atmega 128 타이머 질문있습니다 master 24-12-11 442
질문 ATmega128 2개로 hc-05,hc-06블루트수 통신 동콩이 24-12-04 563
답변 답변글 답변 : ATmega128 2개로 hc-05,hc-06블루트수 통신댓글[4] master 24-12-04 3637
질문 lm75a 온도센서 관련 질문입니다.댓글[6] 이미지첨부파일 hanmw0707 24-12-01 6963
질문 리얼타임클락 질문이요 ㅠㅠ댓글[1] 이미지 팬케이크 24-11-22 664
질문 가속도센서 2개를 강아지 2마리에 각각 달아서 스마트폰으로 움직임을 보고 싶은데요댓글[1] gainomax 24-11-21 836
질문 라즈베리파이 4B 사용 중 막히는 부분 질문합니다댓글[1] 한마바키 24-11-12 6927
질문 스위치로 PI 모터 제어 바밤 24-11-11 481
답변 답변글 답변 : 스위치로 PI 모터 제어 master 24-11-12 495
질문 아트메가128 마이크로프로세서댓글[3] 옹심이 24-11-05 1821
질문 초음파 센서로 장애물 인식댓글[1] 나난ㄴ 24-10-31 772
질문 이런 투명 LCD는 뭐라고 부르나요?댓글[2] 이미지 펌린이 24-10-29 1142
질문 모터제어 중 RPM 계산 질문입니다.댓글[3] suuuuuuuh 24-10-24 1598
질문 아트메가 128과 블루투스 모듈(HC-06) 연결 질문댓글[1] 메가아트 24-10-24 761
게시물 검색

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
모바일버전으로보기