|
Дополнение для радиоаппаратуры 2.4GHz |
|
|
|
Mar 25 2012, 15:42
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Добрый день. Разрабатываю дополнение для радиоаппаратуры. Вот кое-что написал прошу Ваших комментариев, по алгоритму, организации кода, что можно улучшить. Код /** Задача: Необходимо управлять коллекторным двигателем по средствам ШИМ. Двигатель должен начинать движение с ускорением. Управление должно происходить в зависимости от входных сигналов. Входы: 1. Основной сигнал - прямоугольные импульсы амплитудой 5В, длительностью 20 мС, вехняя часть 1000 - 2000 мкС. 2. Два дискретных датчика - верхнее и нижнее положение. Выходы: Два выхода процессора, их комбинации управляют двигателем. Вверх - по ч.с., вниз против ч.с. |--------------------------------------------------------| | |Стоит |Вверх |Вниз |Зафиксирован | |--------------------------------------------------------| |Выход1 | 0 1 0 1 | |--------------------------------------------------------| |Выход2 | 0 0 1 1 | |--------------------------------------------------------| */
#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include "AE_Util.h"
#define PULSE_PIN PIND #define PULSE_PPIN PD2 #define PULSE_MID_WIDTH 188// Средняя длительность импульса 1500/8 = 188. #define PULSE_WIDTH_TOLER 5 // Допуск по ширине импульса #define PULSE_QUANTITY 10 // Количество анализируемых импульсов (0...255)
#define MOT_DDR DDRD #define MOT_PORT PORTD #define MOT_PIN1 PD4 #define MOT_PIN2 PD5 #define MOT_UP sbi(MOT_PORT, MOT_PIN1); cbi(MOT_PORT, MOT_PIN2) #define MOT_DOWN cbi(MOT_PORT, MOT_PIN1); sbi(MOT_PORT, MOT_PIN2) #define MOT_STANDBY cbi(MOT_PORT, MOT_PIN1); cbi(MOT_PORT, MOT_PIN2)
#define SEN_PIN PINA #define SEN_UP_PIN PA0 #define SEN_DOWN_PIN PA1
enum {S_NO, S_UP, S_DOWN, S_BOTH};
// Глобальные переменные volatile u8 g_abPUW[PULSE_QUANTITY];// Массив ширин верхней части импульса 1 == 8 мкС. volatile u8 g_bPulNum;
// Глобальные функции u8 Measuring(); u8 GetSen();
ISR(INT0_vect) { if(PULSE_PIN & (1 << PULSE_PPIN)) // Начало верхней части { TCCR0=0x03; TCNT0=0x00; } else // Конец верхней части { if(TCCR0 != 0)// Только если таймер предварительно был запущен, чтобы замеры делать с начала импульса { g_abPUW[g_bPulNum++] = TCNT0; TCCR0=0x00; }
} }
int main(void) { sbi(MOT_DDR, MOT_PIN1); sbi(MOT_DDR, MOT_PIN2);
// Чтобы входные импульсы стабилизировались _delay_ms(500); while(1) { if(GetSen() != S_DOWN) { MOT_DOWN; while(GetSen() != S_DOWN); MOT_STANDBY; } else { u8 bTol, bMid; do { bMid = Measuring(); if(bMid <= PULSE_MID_WIDTH) { bTol = PULSE_MID_WIDTH - bMid; } else { bTol = bMid - PULSE_MID_WIDTH; } }while(bTol < PULSE_WIDTH_TOLER); MOT_UP; while(GetSen() != S_UP); MOT_STANDBY; _delay_ms(500); MOT_DOWN; while(GetSen() != S_DOWN); MOT_STANDBY; } }
return 0; }
u8 Measuring() { g_bPulNum = 0; TCCR0=0x00;// Таймер выключен sbi(GICR, INT0);// Разрешаем прерывание INT0 cbi(MCUCR, ISC01);// Прерывание будет происходить при любом изменении уровня на INT0 sbi(MCUCR, ISC00); sbi(GIFR, INTF0);// Сбросить прерывание INT0 sei();// Глобальное разрешение прерываний
while(g_bPulNum < PULSE_QUANTITY);// Ожидаем необходимое количество импульсов
cli(); cbi(GICR, INT0); TCCR0 = 0x00;
// Вычисляем среднее значение u8 b; int iMid = 0; for(b = 0; b < PULSE_QUANTITY; b++) { iMid += g_abPUW[b]; } iMid /= PULSE_QUANTITY;
return iMid; }
u8 GetSen() { volatile u8 bRes = SEN_PIN & (1 << SEN_DOWN_PIN); bRes |= (SEN_PIN & (1 << SEN_UP_PIN)); return bRes; }
|
|
|
|
|
 |
Ответов
|
Mar 26 2012, 16:24
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Постараюсь конкретизировать вопросы. 1. С/С++ является аппаратно-независимый языком. Т.е. в основном коде программы не должно быть записей типа "PORTB"? Код #define MOTOR_PORT PORTA volatile uint8_t *pMotorPotr = &PORTB; Какой вариант более предпочтителен? Хотелось бы знать как специалисты соединяют аппарат с программой. Правильно ли я понимаю что в основном это делается чтобы при необходимости поменять камень? Как нибудь так. Код #ifdef KAMEN1 #define MOTOR_PORT PORTA #elif defined KAMEN2 #define MOTOR_PORT PORTB #endif Для AHTOXA: Большое спасибо! Очень трудно разбириться в вопросе без поддержки. Для MaxiMuz: Файл AE_Util.h: Код #ifndef AE_UTIL_H #define AE_UTIL_H
#define cbi(reg, bit) (reg &= ~(1<<bit)) #define sbi(reg, bit) (reg |= (1<<bit)) #define u8 unsigned char
#endif // AE_UTIL_H Здесь мои мизерные утилиты. А алгоритм такой: 1. Измеряем ширину верхних частей определенного кол-ва импульсов. 2. Находим среднее значение. 3. В зависимости от результата, управляем двигателем или не трогаем его. 4. Вообще должен получится самосвал. Если средняя ширина импульса отличается от заданной (кто-то дернул рычаг на передатчике), подаем кузов вверх. 5. Ждем пока отчитается датчик верхнего положения. 6. Пауза. 7. Переполюсовываем движек. 8. Дожидаемся отчета датчика нижнего положения. И опять пункт №1.
Сообщение отредактировал e-leks - Mar 26 2012, 16:27
|
|
|
|
|
Mar 26 2012, 17:59
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(e-leks @ Mar 26 2012, 19:24)  А алгоритм такой: 1. Измеряем ширину верхних частей определенного кол-ва импульсов. 2. Находим среднее значение. 3. В зависимости от результата, управляем двигателем или не трогаем его. 4. Вообще должен получится самосвал. Если средняя ширина импульса отличается от заданной (кто-то дернул рычаг на передатчике), подаем кузов вверх. 5. Ждем пока отчитается датчик верхнего положения. 6. Пауза. 7. Переполюсовываем движек. 8. Дожидаемся отчета датчика нижнего положения. И опять пункт №1. Не знаю, может, я чего-то не понял, но алгоритм тут проще простого - берем отсчеты с линии, на которой вы наблюдаете ваш ШИМ - сигнал (достаточно часто берем), например, в течение секунды. Получаем либо нули, либо единички. Единички приплюсовываем друг к другу в какой-то переменной, нули отбрасываем. Спустя секунду смотрим, сколько принято единичек. Если больше некоторого порога - что-то там включаем или выключаем. P.S. Еще раз. Все ваши сообщения составлены так, что из них крайне трудно что-то понять. Проще говоря, они составлены небрежно. Обижайтесь - не обижайтесь, но это так. Учитесь кратко и четко формулировать свои мысли ...
|
|
|
|
|
Mar 26 2012, 18:23
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Цитата(kovigor @ Mar 26 2012, 21:59)  ...в течение секунды. Получаем либо нули, либо единички. Единички приплюсовываем друг к другу в какой-то переменной, нули отбрасываем. Спустя секунду смотрим, сколько принято единичек. Если больше некоторого порога - что-то там включаем или выключаем... У сигнала ШИМ частота постоянна, это Вам не ЧИМ, соответственно количество единичек за определенный промежуток времени будет одинаково. Алгоритм измерения: 1. В начале верхней части импульса обнуляем регистр таймера и запускаем его. 2. В конце верхней части сохраняем результат регистра таймера в массив и при желании останавливаем таймер и обнуляем регистр. 3. Повторяем предыдущие пункты необходимое количество раз. 4. Берем элементы массива и высчитываем среднее значение. Цитата(kovigor @ Mar 26 2012, 21:59)  ...Все ваши сообщения составлены так, что из них крайне трудно что-то понять... Мне далеко до Вас в плане электронники, поэтому я обращаюсь к Вам. Подскажите как правильно задавать вопросы. Мой вопрос Цитата Хотелось бы знать как специалисты соединяют аппарат с программой? достаточно конкретен?
|
|
|
|
Сообщений в этой теме
e-leks Дополнение для радиоаппаратуры 2.4GHz Mar 25 2012, 15:42 kovigor Цитата(e-leks @ Mar 25 2012, 19:42) ... Mar 25 2012, 17:34 e-leks Цитата(kovigor @ Mar 25 2012, 21:34) ...к... Mar 25 2012, 18:22  AHTOXA Ошибка вроде всего одна: "по средствам ШИМ... Mar 25 2012, 21:26 MaxiMuz Цитата(e-leks @ Mar 25 2012, 18:42) ... Mar 26 2012, 11:26   kovigor Цитата(e-leks @ Mar 26 2012, 21:23) ... Mar 26 2012, 18:33    e-leks Цитата(kovigor @ Mar 26 2012, 22:33) Допу... Mar 27 2012, 16:55 AHTOXA Цитата(e-leks @ Mar 26 2012, 22:24) ... Mar 26 2012, 18:34 MaxiMuz Судя по описанию и самой программе , управление ск... Mar 27 2012, 11:45 kovigor Цитата(MaxiMuz @ Mar 27 2012, 14:45) а к ... Mar 27 2012, 13:03 MaxiMuz e-leks не указал каким компилятором пользуется, но... Mar 27 2012, 15:31 MaxiMuz По поводу Кодwhile(GetSen() != S_D... Mar 27 2012, 18:27 AHTOXA Цитата(MaxiMuz @ Mar 28 2012, 00:27) По п... Mar 28 2012, 17:45
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|