회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
3364 마이크로프로세서 HOTpwm제어!! 부탁드립니다^^;;4 128 1887 2010.10.07
3363 자유주제 HOT다들..납땜할때19 꽃다운청춘 6036 2010.10.07
3362 Allegro & OrCAD HOT4층 PCB 제작 어렵나요?6 헨슨 2427 2010.10.07
마이크로프로세서 HOTPWM 으로 DC 모터를 제어할때 문의 사항2 이씨죽고잡기 2055 2010.10.07
3360 자유주제 HOT시험기간이네요4 종이악마 4320 2010.10.07
3359 마이크로프로세서 HOT코드비젼 isp 다운로드 속도 질문2 운기칠삼 1482 2010.10.07
3358 자유주제 HOT[냉무] 나의 납덩이리들은 언제 모일려나...ㅠㅠ7 짱쓰 5602 2010.10.07
3357 자유주제 HOT그냥 쓰잘데기 없는 글입니다.2 러브리데이 2946 2010.10.06
3356 자유주제 HOT라임쩌는 군대의 좋은점^^12 러브리데이 2187 2010.10.06
3355 중고장터 HOTICD-U40 팝니다. bluewing 4457 2010.10.06
3354 중고장터 HOT마이크로 로봇 ATMEGA128 트레이닝킷 판매합니다.6 bluewing 5067 2010.10.06
3353 중고장터 HOTAVR JTAGICE MK2 에뮬레이터 팝니다. bluewing 5044 2010.10.06
3352 중고장터 HOTARM 개발보드 마이크로비젼 MV2440-LCD 팝니다. bluewing 4217 2010.10.06
3351 자유주제 HOT공학 고수님들께 공부길잡이 알려주세요7 종이악마 3947 2010.10.06
3350 자유주제 HOT다들 주무시나봐요...3 가랑 3507 2010.10.06
3349 자유주제 HOT자연의 세계.14 가랑 1482 2010.10.06
3348 마이크로프로세서 HOT질문 드려요~^^1 오창길2 2177 2010.10.05
3347 마이크로프로세서 HOTAT89S52와 ATMEGA128의 차이점 질문입니다.1 마검량 2047 2010.10.05
3346 중고장터 HOT뉴코란도 구합니다.11 설록맨 3177 2010.10.05
3345 전기전자 아무거나 HOTPspice / Pulse droop 질문합니다 ^^ bluewingo 1412 2010.10.05
  • 일은 인류를 사로잡는 모든 질환과 비참을 치료해 주는 주요한 치료제이다.
    - 칼라일
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.