реклама на сайте
подробности

 
 
> Гусеничный робот
Faoxis
сообщение Dec 13 2014, 21:08
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 3-12-14
Пользователь №: 83 952



Здравствуйте! Есть гусеничный робот. Спереди на нем стоят два фотодиода. Есть черная линия по которой он должен ездить и поворачивать с помощью ШИМа. У правляющий порт - С. Комбинация PORTC |= 0x82U; заставляет его ехать вперед. Вроде бы ничего сложного, но уже несколько дней не могу понять в чем накосячил. Стоит на месте и не едет. При этому, если без ШИМа подать на ножки напряжения, то начинает ехать прямо как ему и положено.

Я не прошу разбирать весь код (но и не откажусь Опубликованное фото), но не могли бы вы окинуть свежий взгяд на листинг программы ? Вдруг увидите что-нибудь. Спасибо!

CODE
#include <mega32.h>
#include <delay.h>

unsigned char x = 0, y = 0;
unsigned char K = 0;

/////////////////////////////////////////////////////////////////////////////////////////
////////////////////// Объявленияе функций //////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

//Заставляем робот ехать вперед (настройка портов)
//-----------------------------------------------------------------------------------------
void start();

//Настройка АЦП
//-----------------------------------------------------------------------------------------
void init_adc();

//Чтение из АЦП
//-----------------------------------------------------------------------------------------
unsigned int read_adc(unsigned char Pin_ADC);

//Настройка таймера 0 и 2
//-----------------------------------------------------------------------------------------
void init_timer02();

//Настройка таймера 0 и 2
//-----------------------------------------------------------------------------------------
void init_timer1();

// Вызов прерывания
//-----------------------------------------------------------------------------------------
interrupt [TIM1_OVF] void workplease(void);



/////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Функция main //////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void main()
{
init_adc();
init_adc();
init_timer02();
init_timer1();

start();

#asm("sei") // Разрешение прерывания
while(1)
{


}
}




/////////////////////////////////////////////////////////////////////////////////////////
////////////////////// Описание функций /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

// Установка АЦП
//-----------------------------------------------------------------------------------------
void init_adc()
{
ADMUX = 0x40U; //выбираем источник питания АЦП 5v
ADCSRA |= 0x07U; // устанавливаем предделитель 128 (ADPS2, ADPS1, ADPS0), он нужен из-за того, что ацп занимает много тактов
ADCSRA |= 0x80U; // Включаем АЦП (ADEN)
}

// Чтение из АЦП
unsigned int read_adc(unsigned char Pin_ADC)
{
ADMUX |= Pin_ADC & 0x07U; // Разрешаем менять только 3 последний бита
delay_us(10); // Задержка на 10 микросек по даташиту
ADCSRA |= 0x40U; // Выставлем бит ADIF для запуска преобразования
while((ADCSRA & 0x10) == 0); // Ждем пока оно совершится

return ADCW; // Возвращем сразу значение старшего и младшего бита АЦП
}

// Порты
//-----------------------------------------------------------------------------------------
void start()
{

DDRD |= 0x80U;
DDRB |= 0x08U;

DDRC |= 0x82U;

PORTC |= 0x82U;
}

// Таймеры 0 и 2
//-----------------------------------------------------------------------------------------
void init_timer02()
{
// Указываем явным образом начальное значение регистра счета
TCNT0 = 0x00U;
TCNT2 = 0x00U;

// Укахываем начальное значение регистра сравнения
// Впоследствии оно будет меняться ШИМом
OCR0 = 0x3F;
OCR2 = 0x3F;

// Регистр настройки
TCCR0 = 0x48U; // Fast PWM
TCCR0 |= 0x20U; // Сброс в 0 при прямом счете
TCCR0 |= 0x01U; // Считаем ипульсы кварцевого генератора без предделителя

TCCR2 = 0x48U; // Fast PWM
TCCR2 |= 0x20U; // Сброс в 0 при прямом счете
TCCR2 |= 0x01U; // Считаем ипульсы кварцевого генератора без предделителя

}

// Таймера 1
//-----------------------------------------------------------------------------------------
void init_timer1()
{
TCCR1B |= 0x04U; // устанавливаем режим СТС (сброс по совпадению
TIMSK |= 0x10U; // устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)

OCR1AH = 0b00000111; // определяем число сравнения. Определяем как часто делать прерывания
OCR1AL = 0b00000000;

TCCR1B |= 0x01U; //запуск таймера без предделителя
}

// Прерывание
//-----------------------------------------------------------------------------------------
interrupt [TIM1_OVF] void workplease(void)
{
x = read_adc(0x00); // Значение с ножки А0
y = read_adc(0x01); // Значение с ножки А1

K = x - y; // Модуль разности

if (x < y)
OCR0 = OCR0 - K * 10;
else
OCR2 = OCR2 - K * 10;


}



Сообщение отредактировал IgorKossak - Dec 14 2014, 00:03
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 19:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01362 секунд с 7
ELECTRONIX ©2004-2016