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

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

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

Сообщение 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
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

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

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

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

Сообщение 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
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

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

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

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

Сообщение mastech »

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

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

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

Сообщение ARV »

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

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

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

Сообщение 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

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

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

Сообщение 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 *")
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

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

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

Сообщение es131245 »

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

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

Сообщение WiseLord »

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

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

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

Сообщение 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
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

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

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

Сообщение Psych »

ARV писал(а):вообще-то strcmp есть для этого

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

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

Сообщение pokk »

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

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

Сообщение WiseLord »

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

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

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

Сообщение Siarzhuk »

pokk писал(а):Добрый день, подскажите какие могут быть ограничения на использования #ifdef
т.е где её нельзя использовать ?

Использовать можно везде где её найдёт и обработает препроцессор.

pokk писал(а):В общем возникла проблема следующая:
сделал включение выключение отладочного кода программы по #ifdef всё работает пошёл дальше
добавил ещё один #ifdef на вывод отладочной информации на индикатор и этот #ifdef в упор не хочет убирать код
уже всякие разные названия на придумал всё равно и внутрь case поставил и в глобальный дефайн воткнул результат один не убивает код. какие могут быть причины ?

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

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

Сообщение pokk »

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

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

Сообщение 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;
  ...
}
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

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

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