회원가입 ID/PW 찾기
AA

안녕하세요.

DC Motor를 PWM으로 제어를 하고자 하여 OCRB, OOCRC을 이용하여 제어를 하고 있습니다.

원하는 PWM이 출력이 되어 모터의 가감속과 방향을 바꾸어 가면서 제어가 되는데.

이상하게 Delay_ms()함수를 사용을 하면 전혀 동작을 하지 않네요.

혹 PWM의 time와 Delay_ms()와의 관계가 있는지 다른 설정이 필요한지에 대하여

고수님의 의견을 듣고자 합니다.

관련 소스와 회로도를 첨부 하여 드립니다.

프로그램이 다운로드 되지 않는 분을 위해 소스를 아래 추가 하여 드립니다.
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL   //CPU clock 설정 : 8MHz
#define PULSE_DUTY 1500000UL // 1500000ns = 1.5 ms   (ns단위)
#define PULSE_WIDTH 20000000UL // 20000000ns = 20ms    (ns 단위)
#define PULSE_CNT 50   // Pulse count. 한 번 command안에서 실행되는 펄스 갯수

volatile unsigned long clk_period = (uint16_t) (1000000000UL/F_CPU) * 8;   // clkio/8 사용하므로 period는 x8
volatile uint8_t pulse_count = PULSE_CNT;

volatile char nStopCheck = 0;

SIGNAL(TIMER3_COMPB_vect)
{
 cli();
 pulse_count--;
 if(pulse_count == 0)
 {
  TCCR3A = 0x00;
  TCCR3B = 0x00;
  nStopCheck = 1;
 }
 sei();
}

void init_CNT3()
{
 DDRE |= 0x10;         // PE4/OC3B output
 DDRE |= 0x20;         // PE4/OC3C output

 TCCR3A = 0x2B;        // Counter 3, Channel B, Channel C, Compare Output Mode, Fast PWM
 TCCR3B = 0x1A;        // Waveform generation mode 15. clkio/8 clock 사용.

 OCR3A = (uint16_t) (PULSE_WIDTH/clk_period);  // 20ms 주기 설정
 OCR3B = (uint16_t) (PULSE_DUTY/clk_period);   // default로 1.5ms 가운데
 OCR3C = (uint16_t) (PULSE_DUTY/clk_period);   // default로 1.5ms 가운데

 ETIMSK = 0x0A;        // Timer/Counter3, Output Compare B, Compare C Match Interrupt Enable

 sei();
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Funtion : DCMove
//
// Description : DC 모터를 구동 시키는 함수
//    (OCR3B, OCR3C를 이용하여 PWM을 출력하여 모터를 구동 시킴)
// Parameter :
//  . nLeftMotorSpeed  : Left  DC motor 이동 속도 ( 0: 정지, 1~19 까지 가감속 지정 가능)
//  . nLeftMotorDirection : Left DC motor 방향 설정 (1: Forward, 2: Backward)
//  . nRightMotorSpeed : Right DC motor 이동 속도 ( 0: 정지, 1~19 까지 가감속 지정 가능)
//  . nRightMotorDirection : Right DC motor 방향 설정 (1: Forward, 2: Backward)
//////////////////////////////////////////////////////////////////////////////////////////////////
void DCMove(char nLeftMotorSpeed, char nLeftMotorDirection,
   char nRightMotorSpeed, char nRightMotorDirection)
{
 if( nLeftMotorSpeed != 0 )
 {
  // 방향 설정 : DCMOTOR01_DIR (1<<5)
  if( nLeftMotorDirection == 1 ) PORTA |= (1<<5);   //Left DC Motor High(Forward)
  else if( nLeftMotorDirection == 2 ) PORTA &= ~(1<<5);  //Left DC Motor Low(Backward)

  OCR3B = (uint16_t) (1000000UL/clk_period) * nLeftMotorSpeed;  // 1ms * Speed
 }

 if( nRightMotorSpeed != 0 )
 {
  // 방향 설정 : DCMOTOR02_DIR (1<<7)
  if( nRightMotorDirection == 1 ) PORTA |= (1<<7);   //Right DC Motor High(Forward)
  else if( nRightMotorDirection == 2 ) PORTA &= ~(1<<7);  //Right DC Motor Low(Backward)

  OCR3C = (uint16_t) (1000000UL/clk_period) * nRightMotorSpeed;  // 1ms * Speed
 }
}

void Delay_us(unsigned char time_us)
{
 register unsigned char i;

 for(i = 0; i < time_us; i++)    // 4 cycle +
    {
  asm volatile(" PUSH  R0 ");    // 2 cycle +
  asm volatile(" POP   R0 ");    // 2 cycle +
  asm volatile(" PUSH  R0 ");    // 2 cycle +
  asm volatile(" POP   R0 ");    // 2 cycle +
  asm volatile(" PUSH  R0 ");    // 2 cycle +
  asm volatile(" POP   R0 ");    // 2 cycle +
    }
}

void Delay_ms(unsigned int time_ms)
{
 register unsigned int i;

 for(i = 0; i < time_ms; i++)
 {
  Delay_us(250);
  Delay_us(250);
     Delay_us(250);
  Delay_us(250);
 }
}


int main(void)
{

 init_CNT3();

 DDRA = 0xFF; // PA4 ~ PA7 : (1<<4) | (1<<5) | (1<<6) | (1<<7)
 PORTA = 0xFF; // DCMOTOR01_EN (1<<4), DCMOTOR02_EN (1<<6)

 DDRE |= (1<<PE4);     // PE4 Output pin 설정
 DDRE |= (1<<PE5);     // PE5 Output pin 설정
 PORTE &= ~0x10;     // 초기 Low로 설정 하여 긴급 동작을 방지
 PORTE &= ~0x20;     // 초기 Low로 설정 하여 긴급 동작을 방지

 pulse_count = PULSE_CNT;

 DDRD = 0xff;
 OCR3B = 0;
 OCR3C = 0;

/*
// DCMove()함수가 않되어 일반적으로 LED를 On/Off하도록 하여 보았지만 아래 코드도
// 동작을 하지 않네요.
 while(1)
 {
  PORTD = 0x00;
  Delay_ms(500);
  PORTD = 0xff;
  Delay_ms(500);
 }
*/

while(1)
{
 DCMove(10, 1, 10, 2);
Delay_ms(500);
 DCMove(10, 2, 10, 1);
Delay_ms(500);
}

 return 0;
}

댓글 2
  • No Profile
    같은걸루 고민 해결 했는데...여기서는 프로그램 다운이 안되네요..
  • No Profile
    PWM 레지스터 설정할시에 일정 시간이 되면 자동적으로 펄스를 만들어 내겠다고 MCU 와 약속을 하신겁니다. 그런데 delay 함수를 사용하시면 펄스를 내보내겠다고 약속한 시간에 delay 함수가 실행이 될수 있기때문에 mcu  가 혼동하는 거에요..^^

하드웨어 설계 및 개발에 대하여 개발자들이 자유롭게 토론하는 공간입니다.
- Q&A, 자유주재 토론, 관련 정보 공유
- 분야 : 마이크로프로세서 응용, 전기/전자(아날로그/디지털) 회로 설계, C/C++ 프로그래밍, 펌웨어,
         PCB Artwork, 트러블슈팅 등 하드웨어 설계에 관한 전반인 내용
※ 게시글에 맞는 분류를 선택하여 글을 작성해 주시면 쾌적한 사이트 운영에 많은 도움이 됩니다.
※ 하드웨어 인사이트는 회원들간의 거래정보를 게재할 뿐이지, 그 어떤 책임과 의무도 가지지 않습니다.

search
번호 분류 제목 글쓴이 조회 수 날짜
648 마이크로프로세서 HOT다시문의 드릴께요 ㅠㅠ 죄송해요ㅜㅜ3 정대철 832 2010.10.22
647 마이크로프로세서 HOTavr 키트관련 질문드려요 ^^;2 정대철 895 2010.10.20
646 마이크로프로세서 HOTavr로 디지털필터 꾸미기4 JYP 1817 2010.10.19
645 마이크로프로세서 HOT제가 atmega128이용해서 모터와 초음파센서를 쓰는 작품을 해볼려고하는데요1 온니무 2104 2010.10.19
644 마이크로프로세서 HOT8051질문입니다2 스카드잼 1448 2010.10.19
643 마이크로프로세서 HOT코드비전 질문입니다..ㅋㅋ1 POV매니아 7020 2010.10.19
642 마이크로프로세서 HOTATmega128 led의 불이 왔다갔다 하는 소스인데 분석좀 부탁 드립니다,3 goesoo 3375 2010.10.14
641 마이크로프로세서 HOT8051보드질문2 스카드잼 1265 2010.10.13
640 마이크로프로세서 HOT질문 하나 더 드려볼게요 ㅠ1 오창길2 1521 2010.10.13
639 마이크로프로세서 HOTisp 다운로드 관련 질문 드립니다6 텐지무용 1395 2010.10.13
638 마이크로프로세서 HOT인터럽트 관련 아이디어좀...3 가랑 1154 2010.10.11
637 마이크로프로세서 HOTkeil 컴파일러에서 delay함수 만드는 법 문의드립니다.4 히쟈 3377 2010.10.11
636 마이크로프로세서 HOT어떤 좋은 MCU를 써야할까요?3 letsgokcs 890 2010.10.08
635 마이크로프로세서 HOTpwm제어!! 부탁드립니다^^;;4 128 1882 2010.10.07
마이크로프로세서 HOTPWM 으로 DC 모터를 제어할때 문의 사항2 이씨죽고잡기 2050 2010.10.07
633 마이크로프로세서 HOT코드비젼 isp 다운로드 속도 질문2 운기칠삼 1478 2010.10.07
632 마이크로프로세서 HOT질문 드려요~^^1 오창길2 2158 2010.10.05
631 마이크로프로세서 HOTAT89S52와 ATMEGA128의 차이점 질문입니다.1 마검량 2041 2010.10.05
630 마이크로프로세서 HOTAtmega128 과 바코드 통신 yjw 1875 2010.10.05
629 마이크로프로세서 HOT바코드와 ATmega128 연동1 붑붑붑붑 1471 2010.10.04
Prev 1 ... 13 14 15 16 17 18 19 20 21 22 ... 50 Next
  • 비통 속에 있는 사람과의 약속은 가볍게 깨진다.
    - J.메이스필드
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.