회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
752 마이크로프로세서 HOT8051질문입니다2 스카드잼 1450 2010.10.19
751 마이크로프로세서 HOT코드비전 질문입니다..ㅋㅋ1 POV매니아 7033 2010.10.19
750 마이크로프로세서 HOTATmega128 led의 불이 왔다갔다 하는 소스인데 분석좀 부탁 드립니다,3 goesoo 3379 2010.10.14
749 마이크로프로세서 HOT8051보드질문2 스카드잼 1269 2010.10.13
748 마이크로프로세서 HOT질문 하나 더 드려볼게요 ㅠ1 오창길2 1529 2010.10.13
747 펌웨어 & 코딩언어 HOTGPS 데이터를 받아서 지도로 맵핑을 하고자 합니다. 더그라스 1086 2010.10.13
746 마이크로프로세서 HOTisp 다운로드 관련 질문 드립니다6 텐지무용 1397 2010.10.13
745 마이크로프로세서 HOT인터럽트 관련 아이디어좀...3 가랑 1161 2010.10.11
744 마이크로프로세서 HOTkeil 컴파일러에서 delay함수 만드는 법 문의드립니다.4 히쟈 3384 2010.10.11
743 마이크로프로세서 HOT어떤 좋은 MCU를 써야할까요?3 letsgokcs 892 2010.10.08
742 마이크로프로세서 HOTpwm제어!! 부탁드립니다^^;;4 128 1887 2010.10.07
마이크로프로세서 HOTPWM 으로 DC 모터를 제어할때 문의 사항2 이씨죽고잡기 2052 2010.10.07
740 마이크로프로세서 HOT코드비젼 isp 다운로드 속도 질문2 운기칠삼 1482 2010.10.07
739 마이크로프로세서 HOT질문 드려요~^^1 오창길2 2173 2010.10.05
738 마이크로프로세서 HOTAT89S52와 ATMEGA128의 차이점 질문입니다.1 마검량 2043 2010.10.05
737 마이크로프로세서 HOTAtmega128 과 바코드 통신 yjw 1888 2010.10.05
736 마이크로프로세서 HOT바코드와 ATmega128 연동1 붑붑붑붑 1475 2010.10.04
735 마이크로프로세서 HOTLED POV를 제작해보려 합니다1 POV매니아 2339 2010.10.04
734 마이크로프로세서 HOTAVR과 STM의 프로그래밍에 질문입니다.2 브이프 995 2010.10.02
733 마이크로프로세서 HOT인터럽트가 무엇인가요 ㅠ4 성공하자yh 1009 2010.10.01
Prev 1 ... 16 17 18 19 20 21 22 23 24 25 ... 58 Next
  • 천재란 인내에 대한 위대한 자질 이외에는 아무것도 아니다.
    - 뷰퐁
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.