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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Valek3306
Встал на лапы
Сообщения: 95
Зарегистрирован: Вт авг 03, 2010 22:51:57
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение Valek3306 »

Аlex, я хотел с помощью трех таймеров в режиме ШИМ организовать функцию которая меняла бы цвет RGB светодиода по непрерывному спектру.
Маленький хакер в подстанцию влез
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Ещё бы хотелось понять, что в Вашем понятии означает фраза "не работает...".
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Valek3306 писал(а):Не подскажите по чему такой алгоритм не работает... что я делаю не так?

Как правильно заметил Alex, ваш алгоритм нам не известен, а так как вы не сильны в программировании, мы не имеем права утверждать, что ваш код соответствует вашему алгоритму

Вот если бы вы написали что вам конкретно нужно, тогда вопрос с соответствием был бы решен.

вообще посмею предположить, что ни одно из условий просто не соблюдается, поэтому ничего не работает.
Начальные условия
int r = 254; // Step 2 255 000 000
int g = 0;
int b = 0;
int t = 2;
мысленно проходим код вместо контроллера так как стоит знак & нужно совместное событие, то есть если в шаге есть хоть один нет, то пропускаем.

Шаг 1 r = 255?- нет: пропускаем.
Шаг 2 r > 0 - да, g =255 -нет: пропускаем
Шаг 3,4 r = 0 - нет : пропускаем
шаг 5 r < 255 нет: пропускаем
шаг 6 r = 255? нет: пропускаем

PS для логических условий в Си употребляется двойной знак &
для сравнения двойное =
пример
if ((a==b)&&(c<15)){/*что нужно сделать*/};
читаем как : если а равно б и це меньше 15, делаем то что нужно.

Тут еще какой подвох может быть
if ((b=0)&(c<15))
даже если c реально меньше 15 ,а b =0
считается так:b приравнивается к нулю, результат вычисления 0x00
дальше c <15 результат 1

далее идет операция побитового и
0x00&1 результат 0!!!!!
В условии пишем всегда == || &&
Почитайте смысл логических и битовых операций.
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

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

Сообщение unalex »

полезный совет начинающим
не пытайтесь переделать чужой код, который не факт что рабочий
лучше потихоньку делайте свой, пусть попроще, но именно так вы разберетесь что к чему и почему
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
BGert
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Вс ноя 25, 2012 13:57:12

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

Сообщение BGert »

unalex Спасибо большое за объяснение по циклу while. Вы так разжевали что дальше уже некуда )))
Так что буду пытаться исправить свою тупую ошибку (
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

В цикле while () как таковом нет ничего ужасного, просто нужно ставить подходящие условия для продолжения программы, иначе она в нем зависнет.

К примеру
i=255;
while (i>0){
i--;
}
неплохо работает.
а вот если работая с кодом поглядели и случайно закомментировали
i=255;
while (i>0){
//i--;
}
все условие всегда будет соблюдаться, так как i не изменяется.Так же как и в случае с while (1) константа не может меняться и она не равна нулю, условие всегда соблюдается, висим тут до конца света.
аналогично с любым другим числом, не равным нулю.
Аватара пользователя
Valek3306
Встал на лапы
Сообщения: 95
Зарегистрирован: Вт авг 03, 2010 22:51:57
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение Valek3306 »

Хорошо, я для начала немного упростил, и все ровно не работает...
Спойлер

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

while (1)
      {
      // Place your code here
      int r = 255;          // Step 2   255   000   000                   
      int g = 0;
      int b = 0;
      int t = 2;
       
      if((r==255)&&(g<255)&&(b==0))           // Step 2   255   255   000
      {
      OCR0=g;
      g++;
      delay_ms(t);
      };
             
      }

А алгоритм который у меня есть прост: меняю значения переменных так как в комментариях, попутно управляя ШИМом.

PS Код написан мной с нуля, просто сначала я это реализовал так
Спойлер

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

NS(void) {          // Функция неприрывного спектра
      while(1){
      int r = 254;                     // Step 1  255   000   000
      int g = 0;
      int b = 0;

      while (g <= 254)    // Step 2   255   255   000
       {
       OCR0=g;
       g++;
       delay_ms(t);
       };
       
      while (r == 0 )         // Step 3   000   255   000
       {
       OCR1AH=0;
       OCR1AL=r;
       r--;
       delay_ms(t);
       };

      while (b <= 254 )          // Step 4   000   255   255
       {
       OCR2=b;
       b++;
       delay_ms(t);
       };
       
      while (g == 0 )         // Step 5   000   000   255
       {
       OCR0=g;
       g--;
       delay_ms(t);
       };
       
      while (r <= 254 )          // Step 6   255   000   255
       {
       OCR1AH=0;
       OCR1AL=r;
       r++;
       delay_ms(t);
       };

      while (b == 0)         // Step 7  255   000   000
       {
       OCR2=b;
       b--;
       delay_ms(t);
       };
       };
       prog=0;
};

это прекрасно работало, но мне подсказали что это совсем не правильная реализация задачи.
Маленький хакер в подстанцию влез
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
Аватара пользователя
Moto_v3x
Потрогал лапой паяльник
Сообщения: 307
Зарегистрирован: Ср мар 31, 2010 11:45:58
Откуда: Славянск

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

Сообщение Moto_v3x »

а случайно

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

      int r = 255;          // Step 2   255   000   000                   
      int g = 0;
      int b = 0;
      int t = 2;

не нужно ставить перед while (1)
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

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

Сообщение unalex »

Valek3306 писал(а):но мне подсказали что это совсем не правильная реализация задачи


а по-моему это нормальная реализация задачи, хотя можно упростить

Спойлер

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

int main()
{
   //инициализация портов, ШИМ и пр. .....
   //.....................................
   
   OCR1AH = 0;      //задаем один раз и больше не трогаем
   //Начальные условия
   OCR1AL = 255;   //Красный максимум
   OCR0 = 0;      //Зеленый минимум
   OCR2 = 0;      //Синий минимум
   
   unsigned char i = 0;   //переменная управляющая всеми каналами
   
   while(1)
   {
      while(i < 255)   //Красный в желтый (увеличиваем зеленый)
      {
         OCR0 = i;
         i++;
         delay_ms(TIME)
      }
      while(i > 0)   //Желтый в зеленый (уменьшаем красный)
      {
         OCR1AL = i;
         i--;
         delay_ms(TIME)
      }
      while(i < 255)   //Зеленый в голубой (увеличиваем синий)
      {
         OCR2 = i;
         i++;
         delay_ms(TIME)
      }
      while(i > 0) //Голубой в синий (уменьшаем зеленый)
      {
         OCR0 = i;
         i--;
         delay_ms(TIME)
      }
      while(i < 255)   //Синий в пурпурный (увеличиваем красный)
      {
         OCR1AL = i;
         i++;
         delay_ms(TIME);
      }
      while(i > 0)   //Пурпурный в красный (уменьшаем синий)
      {
         OCR2 = i;
         i--;
         delay_ms(TIME);
      }
   }
}


и еще упрощать много много раз и экспериментировать, убрать вообще переменную и оперировать непосредственно с OCR регистрами, while поменять на for(на вкус и цвет) и т. д.
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

в теме про опрос кнопок Аlex выложил программку.

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

interrupt [TIM1_OVF] void timer1_ovf_isr(void){
static unsigned char cnt_ms_butt=20;    // Счётчик для формирования периода в 20 мс.
TCNT1 -= 4000;          // Перезапускаем таймер на 1 мс.
//----------//
if(!--cnt_ms_butt){     // Формируем 20-ти миллисек. периоды
    cnt_ms_butt=20;
    mButt_1.cur = (PORT_BUTT_1&(1<<PIN_BUTT_1))!=0;                 // Считываем текущее значение вывода.
                                                                    // Дальше работаем с этим битом, т.к. порт может измениться в любой момент.
    if((mButt_1.cur==ACT_BUTT_LEV) && (mButt_1.prev!=ACT_BUTT_LEV)) // Если текущее значение - "нажата" и предыдущее - "не нажата"
        mButt_1.down = 1;                                                   // Устанавливаем флаг down
    if((mButt_1.cur!=ACT_BUTT_LEV) && (mButt_1.prev==ACT_BUTT_LEV)) // Если текущее значение - "не нажата" и предыдущее - "нажата"
        mButt_1.up = 1;                                                     // Устанавливаем флаг up
    mButt_1.prev=mButt_1.cur;                                       // Сохраняем текущее значение. Оно для следующего входа будет предыдущим
}
//----------//
}

Не могу понять вот эту часть

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

if(!--cnt_ms_butt){     // Формируем 20-ти миллисек. периоды

что это условие делает ? это типо задержка что ли ?
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

cnt_ms_butt-это обычная переменная-счётчик миллисекунд. В условии она уменьшается на 1 и проверяется на ноль. Если равна нулю - выполняется условие.
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Всё до меня дошло наконец то =)
А почему не сразу таймер на 20 миллисекунд настроить ? Где дальше могут используются интервалы по одной миллисекунды ?
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Да где угодно - дин. индикация, программные таймеры для реализации всяческих задержек и интервалов, ... Жалко "убивать" таймер только на одни кнопки. :)
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Всё понятно благодарю за помощь.
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

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

Сообщение menzoda »

Valek3306

Замечание не по коду, а по алгоритму в принципе. Перебирая значения каналов RGB ты получишь не то, что хочешь, а свистопляску из цветов. Нужно работать не в RGB схеме, а в HSB (Hue Saturation Brightness - Тон Насыщенность Яркость), перебирая канал H (тон), не затрагивая при этом яркость и насыщенность, что ты и делаешь работая с RGB. Единственная сложность - перевод из HSB в RGB представляет собой довольно громоздкую штуку, но ничего не попишешь.
Аватара пользователя
Valek3306
Встал на лапы
Сообщения: 95
Зарегистрирован: Вт авг 03, 2010 22:51:57
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение Valek3306 »

И все же, по чему это не работает?

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

while (1)
      {
      // Place your code here
      int r = 255;          // Step 2   255   000   000                   
      int g = 0;
      int b = 0;
      int t = 2;
       
      if((r==255)&&(g<255)&&(b==0))           // Step 2   255   255   000
      {
      OCR0=g;
      g++;
      delay_ms(t);
      };
             
      }
Маленький хакер в подстанцию влез
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
Аватара пользователя
Moto_v3x
Потрогал лапой паяльник
Сообщения: 307
Зарегистрирован: Ср мар 31, 2010 11:45:58
Откуда: Славянск

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

Сообщение Moto_v3x »

Valek3306 писал(а):И все же, по чему это не работает?

viewtopic.php?p=1601959#p1601959
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

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

Сообщение unalex »

Valek3306 писал(а):И все же, по чему это не работает?


пошагай по коду и посмотри

задали значения, проверили ифом, увеличили на 1, затем цикл повторяем - ОПЯТЬ ЗАДАЛИ ЗНАЧЕНИЯ(зачем их снова задавать), проверили уменьшили на 1
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

Чертеж1.jpg
(24.79 КБ) 947 скачиваний
Если хочешь получить всю палитру цветов и не хочешь заморачиваться с Hue Saturation Brightness, я в свое время делал так:

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

#define STEP        (1)                     // значение шага изменения ШИМ
#define STEPS       (255/STEP)
#define MAX_CNT     (STEPS*6)

signed char Rdir,Gdir,Bdir;
unsigned char R=0,G=255,B=0;
unsigned short cnt;

while(
1)
{
   /* здесь нужно поместить код, устанавливающий коэффициенты ШИМ равные переменным R,G,B. */
   
   switch
(cnt)
   {
      case    0:
         Rdir = 0;     Gdir = 0;     Bdir = +1;    break;
      case   STEPS:
         Rdir = 0;     Gdir = -1;    Bdir = 0;     break;
      case  2*STEPS:
         Rdir = +1;    Gdir = 0;     Bdir = 0;     break;
      case  3*STEPS:
         Rdir = 0;     Gdir = 0;     Bdir = -1;    break;
      case  4*STEPS:
         Rdir = 0;     Gdir = +1;    Bdir = 0;     break;
      case  5*STEPS:
         Rdir = -1;    Gdir = 0;     Bdir = 0;     break;
      default:
         break;
   }

   R += STEP*Rdir;   //получение переменных
   G += STEP*Gdir;
   B += STEP*Bdir;

   if(++cnt >= MAX_CNT)
      cnt = 0;
}
 

Изображение
Ставим плюсы: )
Аватара пользователя
Твори бобро
Родился
Сообщения: 18
Зарегистрирован: Чт дек 27, 2012 05:24:10

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

Сообщение Твори бобро »

Опять я тут со своими очевидными(не мне) вопросами.
Вообщем есть неизвестный контроллер с компилятором Си. с 32-ух битной адрессацией, и памятью. Есть исходник который почти компилируется, кроме функции обращения к памяти, программа изначально писалась под ARM7. т.е примерно так:

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

unsigned int read_word(unsigned int addr)
{
int ind;

 addr &=~3

if (!((ind=(addr^0x01300000)) & ~0xFFFFF))
    {
        return func_blablabla(ind);
    }
}


Вот примерно так. все вроде-бы нормально но компилятор категорически отказывается принимать выражение "addr &=~3". зато принимает "addr = ~3 & addr" "addr = addr & ~3" вот. Проблема в том что прошить железку надо с первого раза(дальше она лочится и можно выбрасывать).
Вопрос вообщем-то как записать правильно только с обычными операторами?
Ответить

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