뉴티씨



  • HOME
  • 고객지원
  • 질문답변

 

 
jmod-128-1과 l298n 모터드라이버로 dc모터 2개 제어
 글쓴이 : 김원
작성일 : 24-11-29 01:26
조회 : 401  
안녕하세요..

​OCR0와 OCR2의 값을 동일하게 주었는데도 모터 속도가 달라서 질문드립니다..

OCR0 쪽 모터가 좀더 빠른경향이 있고요.. 모터 둘다 돌리다가 외부 전원을 빼도 OCR0쪽 모터가 천천히 돌아가는 현상이 일어납니다..

혹시 코드상 문제가 있는건지 궁금합니다..
/*
#define ENA 4  PB4    OC0
#define ENB 7  PB7    OC2
#define IN1 0  PB0
#define IN2 1  PB1
#define IN3 2  PB2
#define IN4 3  PB3
*/

#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>


void init_adc();
unsigned short read_adc(unsigned char channel);
unsigned short smooth_adc(unsigned char channel);
void pwm_init();
void init_uart0();
void putchar0(char c);
void puts0(char *ps);

void motor_init()
{
TCCR0 = (1 << WGM00) | (1 << WGM01) | (1 << COM01) | (1 << CS02); // Fast PWM, 비반전, 분주비 64
// Timer/Counter2 설정 (모터 B)
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM21) | (1 << CS21) | (1 << CS20); // Fast PWM, 비반전, 분주비 64
}

//전진,후진 반복
int main(){
DDRF=0x00;
DDRA=0xff;
DDRB=0xff;
motor_init();
init_adc();
init_uart0();
PORTA=0x80;
PORTB=0x05; //항상 돌아가게끔

char debug_buffer[50]; //디버깅용 버퍼

while(1)
{
unsigned short value1 = smooth_adc(0);  // ADC 채널 0 읽기
unsigned short value2 = smooth_adc(1);  // ADC 채널 1 읽기

sprintf(debug_buffer, "검은색선: %d, 갈색선: %d\r\n", value1, value2);
puts0(debug_buffer);
_delay_ms(100);


OCR0=0;  //out1,2 쪽 속도제어
OCR2=0;  //out3,4 쪽 속도제어
if ((value1+value2) > 700)
{
if(value1>value2)
{
OCR0=100;
PORTA = 0x81;
}
else
{
OCR2=100;
PORTA = 0x82;
}
}

else if ((value1+value2) < 400)
{
OCR0=128; // out 1,2
OCR2=128; //out 3,4
PORTA = 0x84;
}

_delay_ms(1000);


}
}

void init_adc() {
ADMUX = 0x40;  // AVCC(+5V) 기준 전압 사용, ADC0 채널 기본 선택
ADCSRA = 0x87; // ADC 활성화, 프리스케일러 128분주
}

unsigned short read_adc(unsigned char channel) {
ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);  // 원하는 채널 선택
ADCSRA |= (1 << ADSC);  // ADC 변환 시작
while (!(ADCSRA & (1 << ADIF))) ;  // 변환 완료 대기
ADCSRA |= (1 << ADIF);  // ADIF 플래그 클리어
return ADC;  // 16비트 ADC 결과 반환
}

// ADC 이동 평균 필터
unsigned short smooth_adc(unsigned char channel) {
unsigned long sum = 0;
for (int i = 0; i < 10; i++) {
sum += read_adc(channel);  // ADC 값 10번 읽기
_delay_ms(1);
}
return (unsigned short)(sum / 10);  // 평균값 반환
}

// PWM 초기화 함수
void pwm_init() {
// Timer/Counter0 설정 (모터 A)
TCCR0 = (1 << WGM00) | (1 << WGM01) | (1 << COM01) | (1 << CS02); // Fast PWM, 비반전, 분주비 64

// Timer/Counter2 설정 (모터 B)
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM21) | (1 << CS21) | (1 << CS20); // Fast PWM, 비반전, 분주비 64

}

// UART 초기화 함수
void init_uart0() {
UCSR0B = 0x18;  // RX, TX 활성화
UCSR0C = 0x06;  // 8비트 데이터, 패리티 없음, 1스톱 비트
UBRR0H = 0;    // 보레이트 상위 바이트
UBRR0L = 103;  // 9600 보레이트 설정 (F_CPU = 16MHz)
}

void putchar0(char c) {
while (!(UCSR0A & (1 << UDRE0))) ;  // 송신 준비 완료 대기
UDR0 = c;  // 문자를 송신
}

void puts0(char *ps) {
while (*ps != '\0') {
putchar0(*ps++);  // 문자열의 각 문자를 순차적으로 송신
}
}

 
   
 

 


1