Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вот так будет понятнее?

Код: Выделить всё

int adc = 2*(ReadADC(3) - 125);
if(adc < 0) { // назад
   PORTD &=~(1<<2); // выключить одну диагональ моста
   _delay_ms(1); // пауза
   PORTD|=(1<<1); // включить другую диагональ моста
} else { // вперед 
   PORTD &=~(1<<1); // выключить одну диагональ моста
   _delay_ms(1); // пауза
   PORTD|=(1<<2); // включить другую диагональ моста
}
OCR2B= abs(adc);
вообще говоря, задержки при переключениях диагоналей - это глупость: приведет к искажению ШИМа. правильный алгоритм должен быть чуток иной:
1. определяем "зону нуля" - значение АЦП, которое соответствует остановленному состоянию
2. измерили АЦП
3. проверили, вошли в зону нуля или нет
4. если в зоне - выключили ШИМ
5. если вне зоны, то надо сравнить знак этого результата АЦП с предыдущим результатом
6. если знаки совпадают, то перейти к п.8
7. если знаки разные, то для положительного значения текущего значения АЦП включить одну диагональ, для отрицательного - другую
8. задать скорость по абсолютному значению АЦП.
9. запомнить знак результата АЦП для следующей итерации
10. повторять в цикле с п.2
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Пт окт 17, 2014 12:42:38

Сообщение yuriy m »

Спасибо за наводку. Буду думать...
Реклама
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Пт окт 17, 2014 12:42:38

Сообщение yuriy m »

В связи с похоронами родного человека,немного было не до проекта...
Набросал код,пока не проверял,можно ли упростить или как-то более правильнее написать алгоритм ? Допусти имея мертвую зону в диапазоне 120-134 ацп, 0-120 перевести от 0 ,до 255 ?
Так как стиль у меня больше наверное не сишный ,а для промышленных контроллеров. Более 15 лет программирования разных промышленных контроллеров,а там язык отличается...
И еще ругается на ABS компилятор.
Warning 1 implicit declaration of function 'abs' [-Wimplicit-function-declaration]
Может что подключить надо ?

//--------------------------------ручной режим---------------------------------------------------
void manual()
{
PORTC &=~(1<<0); //выключить поворот
PORTD &=~(1<<6); //тоже
PORTD &=~(1<<5); //тоже

if (((ReadADC(3))>122)&&(ReadADC(3)<132)) //среднее положение ручки
{
OCR2B=0; // выключить шим
TCCR2A=0x00; // тоже
PORTD &=~(1<<1); // отключаем мост
PORTD &=~(1<<2); // тоже

}
else
{
int adc = 2*(ReadADC(3) - 135);

if(adc < 0) // назад
{
PORTD &=~(1<<2); // выключить одну диагональ моста
PORTD|=(1<<1); // включить другую диагональ моста
}
else // вперед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
PORTD|=(1<<2); // включить другую диагональ моста
}
OCR2B = abs(adc);
}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

подключить math.h или определить abs самостоятельно:
#define abs(x) ((x) < 0 ? -(x) : (x))

что касается упрощения алгоритма, то достаточно 1 раз обратиться к чтению АЦП, а не трижды.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Грызет канифоль
Сообщения: 269
Зарегистрирован: Чт мар 11, 2010 17:45:37
Откуда: г.фрязино

Сообщение mastech »

попросили сделать бутафорскую режиссерскую хлопушку та что с бегущими красными циферками)
суть какая когда "рычажок"(кнопка не нажата)) хлопушки поднят в индикаторах хаотично бегают цифры когда рычажок опущен(кнопка нажата) на индикаторе показывается номер дубля и после поднятия опускания дубль прибавляется, но!! пока рычажок опущен то номер дубля показывается на индикаторе.

что получилось у меня: рычажок поднят цифры бегают, закрываю хлопушку подсказывает дубль 1, поднимаю цифры бегают - опускаю дубль 2 и т.д, если держать хлопушку закрытой то дубли сами с интервалом в 1 секунду прибавляются(через задержку), реализовал в двух циклах, первый проверяет нажатие кнопки,если кнопка не нажата циферки бегают, кнопка нажата срабатывает брейк (вываливается из цикла) и переходит во второй цикл тоже проверяет кнопку если нажата то происходит вывод номера дубля с задержкой и пока кнопка нажата естественно дубли сами прибавляются только хлопушку открыть срабатывает брейк и переходит на бегающие цифры . все это безобразие происходит в общем цикле.
вопрос как остановить прибавление дублей пока кнопка нажата не могу сообразить как реализовать этот алгоритм?
контроллер Мега32 , 8 индикаторов.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

сделайте изменение счетчика не во втором цикле, а между двумя циклами
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Грызет канифоль
Сообщения: 269
Зарегистрирован: Чт мар 11, 2010 17:45:37
Откуда: г.фрязино

Сообщение mastech »

ARV писал(а):сделайте изменение счетчика не во втором цикле, а между двумя циклами
с этим разобрался. Спасибо.
теперь вопрос про прерывания, надо выключать с кнопки без фиксации: настроил так

Код: Выделить всё

volatile unsigned char sleepEnabled = 0;

ISR(INT2_vect)
{
   if (sleepEnabled == 0)
   {
      sleepEnabled = 1;
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      sei();
    sleep_mode();
   cli();
}
   sleepEnabled = 0;
}
эту настройку взял отсюда http://forum.easyelectronics.ru/viewtop ... w=previous

работает но нестабильно, много повторных нажатий, кнопка подтянута через резистор, внутренний резистор тоже включен.
Нужно ли в теле программы разрешать прерывания( без разрешения работает).
если нужен код целиком то вечером скину.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 369
Зарегистрирован: Пт фев 01, 2013 21:05:30

Сообщение es131245 »

Как сравнивать массивы указателей разных типов?

Код: Выделить всё

uint8_t * Buf;
...
if(Buf=="String\r"){
Работает, но с предупреждением.

Код: Выделить всё

..\Src\usbd_cdc_if.c(45): warning:  #42-D: operand types are incompatible ("char *" and "uint8_t *")
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Такой вопрос.. в сообщении выше Вы проверяете именно то, что в коде написано (то есть, указывает ли buf на строку), или же пытаетесь этим кодом проверить то, что по адресу buf такая же по содержимому строка ("String") лежит? Если первое, то тогда ОК.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 369
Зарегистрирован: Пт фев 01, 2013 21:05:30

Сообщение es131245 »

Я хочу проверить содержимое буффера. Set\r ли там или нет.
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Тогда нужно для этого пробегать по строке, для чего писать отдельную функцию.

if(Buf=="String\r"){ же всего лишь проверяет, что указатель Buf указывает именно на строку "String\r" в памяти. И не более того, никакого анализа на совпадение строк при этом не происходит.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

es131245 писал(а):Я хочу проверить содержимое буффера. Set\r ли там или нет.

Код: Выделить всё

void main(void)
{
 uint8_t *buf;
const uint8_t comp[]="String\r";
 if (Compare(buf,comp)) printf("Не совпадает"); else printf("Совпадает");
}


uint8_t Compare (const uint8_t * buf1,const uin8_t * buf2)
{
 uint8_t n=0;
 while((buf1[n]==buf2[n])&&buf2[n]&&buf1[n])n++;
 return (buf1[n]|buf2[n]);

}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вообще-то strcmp есть для этого
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

ARV писал(а):вообще-то strcmp есть для этого
Ну там ветвлений больше.
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Добрый день, подскажите какие могут быть ограничения на использования #ifdef
т.е где её нельзя использовать ?
В общем возникла проблема следующая:
сделал включение выключение отладочного кода программы по #ifdef всё работает пошёл дальше
добавил ещё один #ifdef на вывод отладочной информации на индикатор и этот #ifdef в упор не хочет убирать код
уже всякие разные названия на придумал всё равно и внутрь case поставил и в глобальный дефайн воткнул результат один не убивает код. какие могут быть причины ?
PS: использую CodevisionAVR
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Никаких ограничений. Только следует понимать, что всё, что начинается с # - это инструкции препроцессора, компилятор этих #ifdef и прочего не видит в принципе - он компилирует только код, отданный ему препроцессором.

А вообще по поводу нерабочего дебага, хорошо бы приводить кусок кода, а то никто не знает, что Вы там написали, и почему это может не работать.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

pokk писал(а):Добрый день, подскажите какие могут быть ограничения на использования #ifdef
т.е где её нельзя использовать ?
Использовать можно везде где её найдёт и обработает препроцессор.
pokk писал(а):В общем возникла проблема следующая:
сделал включение выключение отладочного кода программы по #ifdef всё работает пошёл дальше
добавил ещё один #ifdef на вывод отладочной информации на индикатор и этот #ifdef в упор не хочет убирать код
уже всякие разные названия на придумал всё равно и внутрь case поставил и в глобальный дефайн воткнул результат один не убивает код. какие могут быть причины ?
Если не убирает - значит ключ определён - не важно во что он определён - 0, 1, 100500 - срабатывать будет всегда - т.е. надо убирать #define совсем.. А вообще пример кода покажите - определение ключа и [неработающее] использование оного.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Вопрос решился благодарю все за помощь. (попутал #ifdef и #if :oops: )
Прорезались зубы
Аватара пользователя
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Сообщение slavokhire5 »

Привет котам:)

я опять с глупыми вопросами. мое устройство получает настройки от ведущего - пока немного, всего штук 6 типа uint8_t.
т.к. настройки нужны очень много где, я объявляю их глобально.
как лучше в плане понимания кода посторонним человеком сделать, 6 отдельных переменных (прим1), или структуру с настройками (прим2)? либо какой-то третий вариант?

пример1:

Код: Выделить всё

uint8_t adc_gain;
...
void adc_setup(void)
{
   ....
   ADC_CONTROL_REG = adc_gain;
  ...
}

пример2:

Код: Выделить всё

tDevice_Settings set;
...
void adc_setup(tDevice_Settings *set)
{
   ....
   ADC_CONTROL_REG = set->adc_gain;
  ...
}
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Конечно же лучше в структуру. В неё и укладывать принятые данные сразу удобнее, по байтикам. И визуально восприниматься будет лучше.
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»