Вопросы по С/С++ (СИ)
- Valek3306
- Встал на лапы
- Сообщения: 95
- Зарегистрирован: Вт авг 03, 2010 22:51:57
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Аlex, я хотел с помощью трех таймеров в режиме ШИМ организовать функцию которая меняла бы цвет RGB светодиода по непрерывному спектру.
Маленький хакер в подстанцию влез
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ещё бы хотелось понять, что в Вашем понятии означает фраза "не работает...".
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
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: Вопросы по С/С++ (СИ)
полезный совет начинающим
не пытайтесь переделать чужой код, который не факт что рабочий
лучше потихоньку делайте свой, пусть попроще, но именно так вы разберетесь что к чему и почему
не пытайтесь переделать чужой код, который не факт что рабочий
лучше потихоньку делайте свой, пусть попроще, но именно так вы разберетесь что к чему и почему
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Re: Вопросы по С/С++ (СИ)
unalex Спасибо большое за объяснение по циклу while. Вы так разжевали что дальше уже некуда )))
Так что буду пытаться исправить свою тупую ошибку (
Так что буду пытаться исправить свою тупую ошибку (
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
В цикле while () как таковом нет ничего ужасного, просто нужно ставить подходящие условия для продолжения программы, иначе она в нем зависнет.
К примеру
i=255;
while (i>0){
i--;
}
неплохо работает.
а вот если работая с кодом поглядели и случайно закомментировали
i=255;
while (i>0){
//i--;
}
все условие всегда будет соблюдаться, так как i не изменяется.Так же как и в случае с while (1) константа не может меняться и она не равна нулю, условие всегда соблюдается, висим тут до конца света.
аналогично с любым другим числом, не равным нулю.
К примеру
i=255;
while (i>0){
i--;
}
неплохо работает.
а вот если работая с кодом поглядели и случайно закомментировали
i=255;
while (i>0){
//i--;
}
все условие всегда будет соблюдаться, так как i не изменяется.Так же как и в случае с while (1) константа не может меняться и она не равна нулю, условие всегда соблюдается, висим тут до конца света.
аналогично с любым другим числом, не равным нулю.
- Valek3306
- Встал на лапы
- Сообщения: 95
- Зарегистрирован: Вт авг 03, 2010 22:51:57
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Хорошо, я для начала немного упростил, и все ровно не работает...
А алгоритм который у меня есть прост: меняю значения переменных так как в комментариях, попутно управляя ШИМом.
PS Код написан мной с нуля, просто сначала я это реализовал так
это прекрасно работало, но мне подсказали что это совсем не правильная реализация задачи.
Спойлер
Код: Выделить всё
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: Вопросы по С/С++ (СИ)
а случайно
не нужно ставить перед while (1)
Код: Выделить всё
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: Вопросы по С/С++ (СИ)
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% коктейля "Рекурсивный"...
Re: Вопросы по С/С++ (СИ)
в теме про опрос кнопок А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: Вопросы по С/С++ (СИ)
cnt_ms_butt-это обычная переменная-счётчик миллисекунд. В условии она уменьшается на 1 и проверяется на ноль. Если равна нулю - выполняется условие.
Re: Вопросы по С/С++ (СИ)
Всё до меня дошло наконец то =)
А почему не сразу таймер на 20 миллисекунд настроить ? Где дальше могут используются интервалы по одной миллисекунды ?
А почему не сразу таймер на 20 миллисекунд настроить ? Где дальше могут используются интервалы по одной миллисекунды ?
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Да где угодно - дин. индикация, программные таймеры для реализации всяческих задержек и интервалов, ... Жалко "убивать" таймер только на одни кнопки. 
Re: Вопросы по С/С++ (СИ)
Всё понятно благодарю за помощь.
Re: Вопросы по С/С++ (СИ)
Valek3306
Замечание не по коду, а по алгоритму в принципе. Перебирая значения каналов RGB ты получишь не то, что хочешь, а свистопляску из цветов. Нужно работать не в RGB схеме, а в HSB (Hue Saturation Brightness - Тон Насыщенность Яркость), перебирая канал H (тон), не затрагивая при этом яркость и насыщенность, что ты и делаешь работая с RGB. Единственная сложность - перевод из HSB в RGB представляет собой довольно громоздкую штуку, но ничего не попишешь.
Замечание не по коду, а по алгоритму в принципе. Перебирая значения каналов RGB ты получишь не то, что хочешь, а свистопляску из цветов. Нужно работать не в RGB схеме, а в HSB (Hue Saturation Brightness - Тон Насыщенность Яркость), перебирая канал H (тон), не затрагивая при этом яркость и насыщенность, что ты и делаешь работая с RGB. Единственная сложность - перевод из HSB в RGB представляет собой довольно громоздкую штуку, но ничего не попишешь.
- Valek3306
- Встал на лапы
- Сообщения: 95
- Зарегистрирован: Вт авг 03, 2010 22:51:57
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
И все же, по чему это не работает?
Код: Выделить всё
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);
};
}Маленький хакер в подстанцию влез
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
- unalex
- Мучитель микросхем
- Сообщения: 424
- Зарегистрирован: Сб авг 25, 2007 22:02:05
- Откуда: Германия, Viernheim
Re: Вопросы по С/С++ (СИ)
Valek3306 писал(а):И все же, по чему это не работает?
пошагай по коду и посмотри
задали значения, проверили ифом, увеличили на 1, затем цикл повторяем - ОПЯТЬ ЗАДАЛИ ЗНАЧЕНИЯ(зачем их снова задавать), проверили уменьшили на 1
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
Если хочешь получить всю палитру цветов и не хочешь заморачиваться с 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. т.е примерно так:
Вот примерно так. все вроде-бы нормально но компилятор категорически отказывается принимать выражение "addr &=~3". зато принимает "addr = ~3 & addr" "addr = addr & ~3" вот. Проблема в том что прошить железку надо с первого раза(дальше она лочится и можно выбрасывать).
Вопрос вообщем-то как записать правильно только с обычными операторами?
Вообщем есть неизвестный контроллер с компилятором Си. с 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" вот. Проблема в том что прошить железку надо с первого раза(дальше она лочится и можно выбрасывать).
Вопрос вообщем-то как записать правильно только с обычными операторами?