뉴티씨



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

 

 
jmod-128-1과 l298n 모터드라이버로 dc모터 2개 제어
 글쓴이 : 관리자
작성일 : 24-11-29 14:37
조회 : 412  
안녕하세요? 고객님,
저희 뉴티씨를 이용하여 주셔서 감사합니다.

죄송하지만, 사용하시는 제품은 저희 제품이 아닌 것으로 판단됩니다.
구매하신 회사에 문의하시는 것이 좋겠습니다.

감사합니다.

>
>
> 안녕하세요..
>
> ​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