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

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

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


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

페이지 정보

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

조회수 14,529

master님의 댓글

master 작성일

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

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 24176
공지 사이트 이용 안내댓글[31] master 17-10-29 38529
질문 lm75a 온도센서 관련 질문입니다.댓글[6] 이미지첨부파일 hanmw0707 24-12-01 111
질문 리얼타임클락 질문이요 ㅠㅠ댓글[1] 이미지 팬케이크 24-11-22 47
질문 가속도센서 2개를 강아지 2마리에 각각 달아서 스마트폰으로 움직임을 보고 싶은데요댓글[1] gainomax 24-11-21 116
질문 라즈베리파이 4B 사용 중 막히는 부분 질문합니다댓글[1] 한마바키 24-11-12 6367
질문 스위치로 PI 모터 제어 바밤 24-11-11 82
답변 답변글 답변 : 스위치로 PI 모터 제어 master 24-11-12 76
질문 아트메가128 마이크로프로세서댓글[3] 옹심이 24-11-05 218
질문 초음파 센서로 장애물 인식댓글[1] 나난ㄴ 24-10-31 181
질문 이런 투명 LCD는 뭐라고 부르나요?댓글[2] 이미지 펌린이 24-10-29 228
질문 모터제어 중 RPM 계산 질문입니다.댓글[3] suuuuuuuh 24-10-24 269
질문 아트메가 128과 블루투스 모듈(HC-06) 연결 질문댓글[1] 메가아트 24-10-24 184
질문 ATmega128 질문 DFplayer mini댓글[1] Miin 24-10-18 6557
질문 스탭모터 3개 회로도 질문.. 삉삉이 24-10-11 202
답변 답변글 답변 : 스탭모터 3개 회로도 질문.. 이미지 master 24-10-12 258
질문 수분수위센서와 멀티플렉서댓글[3] 김고래쓰 24-10-10 466
질문 ATmegq128 PI 제어기 추가댓글[1] 바밤 24-10-08 191
답변 답변글 답변 : ATmegq128 PI 제어기 추가댓글[1] master 24-10-08 297
질문 아두이노 ide 네오픽셀 각 셀 각자 코드 현수 24-09-29 148
질문 아두이노 IDE 프로마이크로 네오픽셀 현수 24-09-29 152
답변 답변글 답변 : 아두이노 IDE 프로마이크로 네오픽셀 master 24-09-29 157
질문 아두이노 프로마이크로 ide 현수 24-09-28 165
답변 답변글 답변 : 아두이노 프로마이크로 ide master 24-09-28 286
질문 ATmega128로 압력센서댓글[1] 이미지첨부파일 바밤 24-09-27 351
질문 아두이노 회로 배선 질문드립니다댓글[3] 이미지 아브 24-09-23 488
질문 아두이노 및 전기배선 작동이 안되어 해결 부탁드립니다 첨부파일 호떡아 24-09-14 278
답변 답변글 답변 : 아두이노 및 전기배선 작동이 안되어 해결 부탁드립니다 master 24-09-14 256
질문 USB host하고 Stop모드를 같이 쓰려는데댓글[1] 이미지 라칸 24-09-12 430
질문 아두이노 압력 센서로 LED 불빛 들어오게 할려고 하는데... 이미지첨부파일 윤시기 24-09-12 598
게시물 검색

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