|
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++); // 문자열의 각 문자를 순차적으로 송신
}
}
|
|