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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

Уважаемые коты, довольно ламерский вопрос :)
подскажите, пожалуйста, как правильно написать на Си такую конструкцию:

зажечь произвольный бит в восьмибитном порту, номер бита задается переменной

т.е.
1. объявляем переменную (кстати, какой тип лучше подойдет?)
2. присваиваем ей значение от 0 до 7
3. зажигаем соответствующий бит, скажем, в PORTB (остальные биты не трогаем!)

что-то у меня ступор... на асме я бы писал sbi, а тут что?
эти сишные скобочки и палочки :)

UPD.: попробую конструкцию switch-case, вроде по смыслу подходит.
но может, есть способ поизящнее?
Реклама
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

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

Сообщение coredumped »

Denkot писал(а):зажечь произвольный бит в восьмибитном порту, номер бита задается переменной

т.е.
1. объявляем переменную (кстати, какой тип лучше подойдет?)
2. присваиваем ей значение от 0 до 7
3. зажигаем соответствующий бит, скажем, в PORTB


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

uint8_t BIT_X;
BIT_X = 3;
PORTX  |=  1<<BIT_X; //set bit
PORTX  &=  ~(1<<BIT_X); //clear bit

Все будет только лучше, в крайнем случае - хуже.
Реклама
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

coredumped агромаднейшее мурмяу, пойду пробовать :)
а то наветвил кэйзов так, что сам заблудился уже :)
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

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

Сообщение isx »

vitalik_1984 писал(а):menu (punkt++);break}//тут меню это функция вызова строк меню по номеру punkt
case 11://обрабатываем нажатие 1
{chislo[punkt][numb_chislo++]=0x31;//тут добавляем к строке нажатую кнопку
menu (punkt);//обновляем экран


Вот я тоже хотел типо такого замутить, но когда мы нажимаем клавишу "1" то попадаем в case 11, но при нажатии следующей клавиши получается мы вылетаем из него и попадаем в другой case, которому будет присвоено это значение...
Ночью вот мысль созрела (прямс как Менделеев себя чувствую, который во сне таблицу придумал :))) ). А что если каждому пункту меню задать определённый код. К примеру:

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

                                                     -Установить Ширину        (x=111)               - "ввод числа"
                - Настройка(x=11)              -Установить Высоту    (x=112)                  - "ввод числа"
                                                   -Установить Длину         (x=113)                - "ввод числа"
 Меню(x=1)
                                                      -Установить значение "а"     (x=121)            - "ввод числа"
                - Ввод   (x=12)                   -Установить значение "b"  (x=122)            - "ввод числа"     
                                                      -Установить значение "c"      (x=123)           - "ввод числа"


Далее делаем КУЧУ CASE-ов и присваиваем им эти ИКСЫ.
Как в этом случае можно будет реализовать кнопку "НАЗАД", тоесть при нажатии на которую справа будет удаляться одна цифра (каким оператором или группой таковых)?
Рационально ли данное решение с точки зрения затрат ресурсов МК или можно всё сделать как-то проще?
Реклама
Эиком - электронные компоненты и радиодетали
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

еще раз (и наверное еще не раз :) ) спопрошайничаю насчет азов

подскажите, как на Си проверить состояние бита в порту ввода-вывода
например, для проверки пятой ноги порта D на асме я писал

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

sbic PinD,5


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

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

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

Лог.операции И ( & ) и ИЛИ ( | ) в помощь.
Реклама
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

Аlex писал(а):Лог.операции И ( & ) и ИЛИ ( | ) в помощь.

да это понятно.
у меня совершенно простой вопрос, до глупости простой
идентичны ли строки кода:

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

sbic PinD,5

и

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

if (PIND,5 == 0) 


все верно или где-то криво?

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

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

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

да это понятно
Не заметно.

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

if(PIND & (1<<5)){

}
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

угу... а объясните тогда почему нельзя написать через == ?
почему именно через логическое & ?
разве выражение (PIND,5 == 0) не приведет к тому же результату?
если нет, то почему?

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

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

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

почему нельзя написать через == ?
выражение (PIND,5 == 0) не приведет к тому же результату?
А почему можно ? С чего Вы взяли что должно привести к такому-же результату? Кто Вам такое сказал ?

если нет, то почему?
Потому, что нельзя. :)
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

Аlex писал(а):
почему нельзя написать через == ?
выражение (PIND,5 == 0) не приведет к тому же результату?
А почему можно ? С чего Вы взяли что должно привести к такому-же результату? Кто Вам такое сказал ?

да никто... я пишу выражение "пятая нога порта Д равна нулю"
если оно истинно, почему условие не сработает?
Аlex писал(а):Потому, что нельзя. :)

вот поэтому я и не знаю Си... все говорят, делай так, не делай вот так... никто ничего не объясняет...

вот кусок кода:

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

k = 5;
  if(PIND & (1<<k))
  {
   PORTD  |=  1<<k; //set bit
   }

отладчик виснет на строчке с условием...

если пишу через == - так же прекрасно виснет :)

собственно задача: как зажигать и гасить бит, номер которого задается переменной, мне любезно объяснили
теперь надо понять как проверять состояние бита, номер которого задан переменной
собственно, об это и бьюсь :)

а вообще, имеет право на жизнь конструкция PIND,5 ? компилятор на нее молчит в тряпочку и не ругается.
и какой у нее получается тип - булевый?
тогда, можно ли написать просто if (PIND,5) ?

UPD.: попробовал - вроде заработало
зачем тогда логическое &, значит, можно все-таки просто засунуть в if нужный пин?
или все-таки это против каких-то правил, которых я не знаю?
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

Ну вроде на асме пишете, посмотрите, что Вам компилятор нагенерил...
Запятая - здесь точно не к месту.

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

#define BITSET(var,bitno)   ((var) |= 1 << (bitno))   
#define BITCLR(var,bitno)   ((var) &= ~(1 << (bitno)))
#define BITTST1(var,bitno)   ((var) & (1 << (bitno)))
#define BITTST0(var,bitno)   (!((var) & (1 << (bitno))))
#define BITINV(var,bitno)   var=(var^(1 << (bitno)))

#define LED 1
#define MY_PIN 5

#define OUTPORT  PORTD
#define INPORT  PIND

#define SET_LED()  BITSET(OUTPORT,LED)
#define CLR_LED()  BITCLR(OUTPORT,LED)   
//----------
//
if(BITTST1(INPORT,MY_PIN)) SET_LED();
else CLR_LED();
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

isx писал(а):Вот я тоже хотел типо такого замутить, но когда мы нажимаем клавишу "1" то попадаем в case 11, но при нажатии следующей клавиши получается мы вылетаем из него и попадаем в другой case, которому будет присвоено это значение...

ни в какой другой кейс мы не попадаем,если вы конечно не хотите совмещение функций для клавиш.
просто в текстовую строку добавляем эту цифру и обновляем экран.
вывод на экран,это уже другая подпрограмма.
если нажата кнопка перехода в другое меню,то показываем новое меню и пишем уже в другую часть массива.
конечно счетчик символов нужно обнулять или восстанавливать,если обратно делаем расчет.
isx писал(а): Ночью вот мысль созрела (прямс как Менделеев себя чувствую, который во сне таблицу придумал :))) ). А что если каждому пункту меню задать определённый код.


это я вам уже реализовал.
можно при желании присвоить словарное значение каждому пункту.
punkt это как раз переменная-числовое представление пункта меню.
можно до 255 делать,если переменная чар.
isx писал(а): Рационально ли данное решение с точки зрения затрат ресурсов МК или можно всё сделать как-то проще?

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

urry писал(а):

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

#define BITTST1(var,bitno)   ((var) & (1 << (bitno))) 
#define BITTST0(var,bitno)   (!((var) & (1 << (bitno))))
#define BITINV(var,bitno)   var=(var^(1 << (bitno)))


а в студии уже есть в стандартных такие макросы правда битсет и битклеар пришлось дописать.
Последний раз редактировалось vitalik_1984 Пн июн 04, 2012 17:12:42, всего редактировалось 1 раз.
В поисках истины человек развивается.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

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

Сообщение isx »

vitalik_1984 писал(а):если вы конечно не хотите совмещение функций для клавиш.

Ну к примеру клавиша "1" будет означать переход в превый пункт подменю если она нажата в главном меню, а если нажата в подменю, то переход осуществляется в первый пункт подменю 2-го уровня(ну то есть ПОДподменю :) )...
vitalik_1984 писал(а):а в студии уже есть в стандартных такие макросы правда битсет и битклеар пришлось дописать.

А вот я нашёл, она как, прокатит? http://devoid.com.ua/functions-about/c-functions/atof-atol.html
Описание функций C (Си) / C++ - atof-atol

Описание.

Эти функции преобразуют символьную строку в значение с пла-
вающей точкой двойной точности (atof), в целое значение (atoi)
или в длинное целое значение (atol).
Исходная строка string представляет собой последователь-
ность символов, которые могут быть интерпретированы как числовое
значение определенного типа.
Denkot
Встал на лапы
Сообщения: 82
Зарегистрирован: Вт дек 14, 2010 16:07:50

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

Сообщение Denkot »

urry писал(а):Ну вроде на асме пишете, посмотрите, что Вам компилятор нагенерил...
Запятая - здесь точно не к месту.


как это сделать?

пока суть да дело, наковырял я моргалку тем временем
быдлокодно очень, баг на баге, но работает :)
из-за ошибок работает, конечно, не совсем так, как планировалось, но сойдет, это ж моргалка, а не фобос-грунт :)))
общий алгоритм такой:
функцией random генерится номер бита - дважды (два псевдослучайных числа, t и k)
дальше стоит тот самый if :)
если бит k в порту потушен, он зажигается плавно (ШИМ)
если бит t зажжен, он тушится плавно (ШИМ)

ШИМ сделан на простых циклах изменяемой длины без всяких таймеров и прочих заморочек.

баги выражаются в том, что светодиоды иногда гаснут или зажигаются скачком
но это даже вносит элемент разнообразия в работу девайса - ШИМ то есть, то его нет

UPD.: да, мой кривой if действительно не работает.
поэтому и скачки: МК зажигает уже горящие светодиоды (условие проверки не работает).
пошел переписывать...
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

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

Сообщение isx »

isx писал(а):
vitalik_1984 писал(а):если вы конечно не хотите совмещение функций для клавиш.

Ну к примеру клавиша "1" будет означать переход в превый пункт подменю если она нажата в главном меню, а если нажата в подменю, то переход осуществляется в первый пункт подменю 2-го уровня(ну то есть ПОДподменю :) )...
vitalik_1984 писал(а):а в студии уже есть в стандартных такие макросы правда битсет и битклеар пришлось дописать.

А вот я нашёл, она как, прокатит? http://devoid.com.ua/functions-about/c-functions/atof-atol.html
Описание функций C (Си) / C++ - atof-atol

Описание.

Эти функции преобразуют символьную строку в значение с пла-
вающей точкой двойной точности (atof), в целое значение (atoi)
или в длинное целое значение (atol).
Исходная строка string представляет собой последователь-
ность символов, которые могут быть интерпретированы как числовое
значение определенного типа.

И ещё вот проблема появилась. Сделал я меню вышеуказанным методом, получилось типа:

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

Опрос кнопок
 Если нажата какая нидь кнопка, то узнаём её код (key).
 key = 0, то punkt = 1
 key > 0 и punkt = -1, то punkt = 2

//////Главный switch
 switch (punkt)
      {         
       
case -1:
         lcdA = "Lineyka v1.0";
         lcdB = "Glavnoe menu";
         break;   
case 1:       
   
        switch (key)
      {
        case 14: punkt = 2 ; break;
        case 20: punkt = 2; break;
        case 4: punkt = 11; break;           
     
        }
       
       
case 11:         
     
        switch (key)
      {
        case 14: punkt = 12  ; break;
        case 20: punkt = 12; break;
        case 4: punkt = 111; break;           
     
        }
       
       
                 
case 111:
     
        if (key == 4) {
        punkt = -1;}     
        lcdB = "chislo";
        break;     
             
           
case 21:

        switch (key)
      {
     
        case 4: punkt = -2; break;           
        }               
     
     
case 2:
             switch (key)
      {
        case 24: punkt = 1  ; break;
        case 40: punkt = 1; break;
        case 4: punkt = 21; break;           
     

}
Так вот, если я, находясь в основном меню нажимаю кнопку с кодом "4", которая означает "Ввод", то в результате опроса (использую матричную клаву) МК думает что эта кнопка нажимается с огромной частотой (частотой опроса ноги МК) и я автоматически перебегаю в конец иерархии меню (ведь в каждом пункте нажатие кнопки "ввод" переносит нас в следующую ступень нашего меню).
Как мне организовать ожидание отпускания кнопки чтоб такого не происходило?
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

это называется антидребезг или же делать фиксацию нажатия:
- если та же кнопка, то ничего не делаем,
если пол секунды ничего не нажато, то можно снова нажимать.
isx писал(а):А вот я нашёл, она как, прокатит? http://devoid.com.ua/functions-about/c- ... -atol.html

Пойдет для вашего случая, только причем тут цитирование меня, что вы привели? Я там совсем о другом там говорил.
В поисках истины человек развивается.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

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

Сообщение isx »

Хоть режьте хоть шерсть рвите, но в моём случае сделать это через switch похоже невозможно :dont_know: . Весь день убил только на меню.
К примеру из моего кода:
По нажатию клавиши с кодом 4 (находясь в case 1) я попадаю в cаse 11 сразу же (так как процесс тут аналогичный оператору GOTO) и поэтому сразу же срабатывает цепная реакция клавиши "Ввод", хотя на самом деле поступило с клавиатуры только одно нажатие. Именно с этим моментом мне ни удалось справиться ни с помощью GOTO, ни If, ни иных подобных в различных комбинациях. Да и отображаемое на экране не всегда соответствовало тому, что происходит в МК.
Решено было перебрать код, и в итоге получилось вот такое извращенство :)) :

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

.......................
if (punkt == 11) {         
       

        if ((key == 14) || (key == 20)) {key = -9; oldButton[key] = key; punkt = 12; lcdA = "Options"; lcdB = "Proverka";}
        if (key == 4) {key = -9; oldButton[key] = key; punkt = 111; lcdA = "Kalibrovka"; lcdB = "Wait!!! "; }

        } 
                     
if (punkt == 12) { ........
.........

Конечно понять что то тут т сложно, но понятно что я полностью перешёл на if операторы. Также в каждой строке пришлось указывать то, что должно отобразиться на дисплее, так как в иных случаях дисплей не соответствует процессам в МК. Сразу после использования кода кнопки, этот код затирается чем то ненужным и не встречающимся самостоятельно. Добавлена переменная с массивом данных о каждом предыдущем состоянии всех кнопок.
Прокомментируйте как нибудь. Это нормально или опять моя больная фантазия создала что то безумное из простой задачи? :)))
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

если число целое то можно использовать switch оператор -так проще...

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

.......................

switch (punkt)
      case '11': {         
       
       switch 
(key){
              case '14':case '20'//внимание тут нужны значки ' ' чтобы работало я пропустил давая пример.
                     { oldButton[key] = key;key = -9; punkt = 12; lcdA = "Options"; lcdB = "Proverka";break;}
               case '4': 
                     
{ oldButton[key] = key;key = -9; punkt = 111; lcdA = "Kalibrovka"; lcdB = "Wait!!! ";break; }
        }                     
      case 
'12' { ........
.........
 

isx писал(а):Прокомментируйте как нибудь. Это нормально или опять моя больная фантазия создала что то безумное из простой задачи?

похоже на то.Может проще посмотреть примеры как это другие сделали?
И учите СИ в конце концов
Вот книга

кстати можно сделать меню таким образом, что код каждого нажатия прибавляется к коду меню
И можно сделать все двумя кейсами,без вложений, правда меню будет немного ограничено.
В поисках истины человек развивается.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

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

Сообщение isx »

Спасибо за советы :) .. Если что то не так пойдёт переделаю. Щас трогать не хочу, ато итак целый день угробил....
За книгу тоже спасибо, но к сожалению времени нет совсем для чтения...Учёба, сессия, практика... Иногда в промежутках появляется денёк свободный, сразу лезу что нидь паять :)
По поводу кода нажатия тоже думал, но когда макет стал рисовать, то там огромное безобразие получилось. Может я опять накосячил, но помоему такое решение получится гораздо объёмнее...
Ответить

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