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

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

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

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

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

BASIC4MCU > 질문게시판

코드비젼, mega128을 이용한 타이머 인터럽트 사용한 모터의 키제어

페이지 정보

작성자 방구석MCU 작성일20-11-06 18:01 조회3,944회 댓글1건

본문

처음 질문올립니다.

코드 비젼을 이용해서 모터 제어를 하고 있습니다.

전체 코드는 아래에 나와있습니다. 이게 bldc 홀센서 모터를 제어하고 있었습니다.

시계 방향, 반시계 방향 상은 모두 다 맞추었고 메인루틴안에 while(1) 안에 넣게 되었을 때 부드럽게 돌아가는 것을 확인하였습니다.

다음에 타이머 인터럽트를 이용해서 키제어 루틴을 읽어와서 모터를 제어하는 것인데

여기서 오랫동안 막혀있었습니다. 타이머0 오버플로우 인터럽트를 이용해서 20ms마다 키제어를 읽어오도록 코드를 짰는데

이걸 제 나름대로 적용시켜서 코드를 짜봤는데, 모터 회전이 버벅거리는 현상이 나타나게 되었습니다.(방향은 제대로 되어있는데, 이전보다 훨씬더 버벅거리면서 돌아갑니다.)

긴글 읽어주셔서 감사합니다. 혹시 어떤 부분이 문제인지 확인해주 실 수 있으신가요?

 

#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 update_lcd(void);

void pwm1_control(u08 a);        

void step(u08 y);

void keypress();

 

 

interrupt [TIM0_OVF] void timer0_ovf_isr(void) //20ms 마다 타이머 오버플로우 인터럽트 발생

    if(count == 1)

    {

    keypress();

    count = 0;

    }

    else count = count + 1; 

    TCNT0=40;

     

 

 

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(500);

            }  

            PORTD = 0x00;

            direction = 'x';     

            

          }

          break;  

            

          case CW: 

             

          if(direction == '+')

          { 

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

            {

            delay_ms(500); 

            }

            

           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:

                    if(pwm >= 240) pwm = 240;

                    else

                     pwm = pwm + 20; 

                

                     break;             

          case DOWN:

                    if(pwm <= 20) pwm =20;

                    else

                     pwm = pwm -20;    

                                  

                    break;                      

         } 

          temp = pwm; 

          step(temp) ;

          delay_ms(200);                  

          pwm1_control(temp);                    

          lcd_control_write(0xC7);            

          lcd_print_data("%",1);  

        }   

        old_key = new_key;                                                  

    }

 

 

void step(u08 y)

{    

 

// #asm("cli")

    OCR1AL = y;

    OCR1BL = y;

    OCR1CL = y;       

    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

 

 

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: Timer 0 Stopped

// Mode: Normal top=0xFF

// OC0 output: Disconnected

ASSR=0<<AS0;

TCCR0=7;

TCNT0=40;  //11.0592M/1024/216 = 50Hz (20ms)

TIMSK=1;

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); //Phase correct mode

TCCR1B=0x04;   

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/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer2 Stopped

// Mode: Normal top=0xFF

// OC2 output: Disconnected

TCCR2=(0<<WGM20) | (0<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (0<<CS20);

TCNT2=0x00;                                    

OCR2=0x00;

 

// Timer/Counter 3 initialization

// Clock source: System Clock

// Clock value: Timer3 Stopped

// Mode: Normal top=0xFFFF

// OC3A output: Disconnected

// OC3B output: Disconnected

// OC3C output: Disconnected

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer3 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

// Compare C Match Interrupt: Off

TCCR3A=(0<<COM3A1) | (0<<COM3A0) | (0<<COM3B1) | (0<<COM3B0) | (0<<COM3C1) | (0<<COM3C0) | (0<<WGM31) | (0<<WGM30);

TCCR3B=0x00;

TCNT3H=0x00;

TCNT3L=0x00;

ICR3H=0x00;

ICR3L=0x00;

OCR3AH=0x00;

OCR3AL=0x00;

OCR3BH=0x00;

OCR3BL=0x00;

OCR3CH=0x00;

OCR3CL=0x00;

 

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

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

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

// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

// INT2: Off

// INT3: Off

// INT4: Off

// INT5: Off

// INT6: Off

// INT7: Off

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,944

master님의 댓글

master 작성일

인터럽트 함수 안에서는 가능한 빨리 처리를 마치고 빠져나와야 합니다...만
keypress();
시간이 많이 걸리는 함수를 사용하고 있어서 체류 시간이 제법 깁니다.
LCD도 키지말고, 딜레이도 사용하지 않도록 만들어보세요

게시물 검색

BASIC4MCU > 질문게시판 목록

제목 날짜
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은… 스태프  19-01-15
공지 사이트 이용 안내 댓글[25] master  17-10-29
질문 Atmega IO핀 출력 상태 질문이요.. 댓글[3] chelsea 새글 13:32
답변 답변 : Atmega IO핀 출력 상태 질문이요.. 댓글[6] master 새글 14:34
질문 아두이노 센서 쉴드 v5.0 과 음성인식 모듈(V2)통… 댓글[6] 첨부파일AutoSun 새글 22-07-05
질문 초음파 센서를 사용한 dc모터 제어에 관해 질문 있습니… 첨부파일뉴비에오 새글 22-07-04
답변 답변 : 초음파 센서를 사용한 dc모터 제어에 관해 질… 댓글[2] master 새글 22-07-05
질문 아두이노 Sensor Shield 5.0 시리얼 통신 … 댓글[2] AutoSun  22-07-04
질문 Atmega 코드 좀 봐주세요. 댓글[1] 첨부파일chelsea  22-07-04
질문 아두이노 while문 탈출 질문 yhj2644  22-07-01
답변 답변 : 아두이노 while문 탈출 질문 댓글[8] master  22-07-01
질문 ESP32-C3 리튬폴리머 ADC 전압 체크 관련 문의… 댓글[3] cansad  22-06-30
질문 ESP32-C3 리튬폴리머 ADC 전압 체크 관련 문의 댓글[3] cansad  22-06-30
질문 빵판없이 디스플레이 넣을 수 있을까요? 댓글[2] 첨부파일오소로롯  22-06-29
질문 라즈베리파이4 신형 선택문제 댓글[1] maximum  22-06-26
질문 음전압 ADC 댓글[2] 412904  22-06-26
질문 아두이노 센서값 출력 질문입니다! 댓글[1] 아궁2  22-06-24
질문 ATmega128, ATmega28 RS232통신 첨부파일Moon4201  22-06-24
답변 답변 : ATmega128, ATmega28 RS232… 댓글[1] master  22-06-25
질문 서보모터, 온습도센서 코드 질문 댓글[2] 첨부파일kshdlfaldfh  22-06-22
답변 답변 : 서보모터, 온습도센서 코드 질문 댓글[15] master  22-06-22
질문 steppermulti5 질문 응애  22-06-21
답변 답변 : steppermulti5 질문 댓글[1] master  22-06-22
질문 atmega128 avr usart 질문 snoflak  22-06-21
답변 답변 : atmega128 avr usart 질문 댓글[5] master  22-06-21
질문 사용자 정의 함수 변환 하는 방법 댓글[2] 첨부파일da0800  22-06-21
질문 atmega128 댓글[1] 양의노래  22-06-20
질문 아두이노 동시동작 재질문 댓글[9] 첨부파일죠르디  22-06-20
질문 초음파센서로 dc모터 제어하기 댓글[1] 첨부파일난쟁2  22-06-20
질문 아두이노 동시동작 댓글[7] 죠르디  22-06-19
게시물 검색


Privacy Policy
MCU BASIC ⓒ 2017
PC버전