Файлы  •  Ссылки  •  Прошивки  •  Правила  •  Архив  •   FAQ  •  Участники  •  Поиск
Регистрация  •  Вход

Программисты C нужна помощь...

Список форумов » Среда разработчика
АвторСообщение
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




19-01-2013 22:57

Только не пинайте сильно, в Си я не силен, точнее ваАще никак. Все, что писАл раньше исключительно на голом асме, но тут надо.

Короче есть проблема: подключил устройство к разным портам проца (разводка ног портов просто убийственная - выкручиваюсь) Инициализировал порты, все гут. Теперь надо отправлять на ноги сигнал, т.е. надо байт раскидать по битам разных портов по возможности не трогая остальные данные. Думаю вопрос банальный и давно решенный и есть красивые решения, но я запутался...
o_l_e_g
Участник
Сообщения: 2422




19-01-2013 23:06

Васисуалий, А конкретней? Подозреваю городишь аналогию PLC на МК, так?
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




19-01-2013 23:19

STM32F4xx на Discovery + классика WH1602. В принципе имеем целую кучу шестнадцатиразрядных портов, но эти разрабоДчеГи (я всегда недолюбливал схемотехников от Томсона) умудрились развести устройства на плате так, что не осталось ни одного чистого порта, плюс к этому сам чип разведен внутри против всякой логики. Если не лень, глянь шит, сильно удивишся как у него порты расположены шок Короче я просто прилепил ноги индикатора туда, куда пришлось. Теперь есть задача - индикатору пофиг, он хочет видеть свои байты целиком, и ему пох, откуда они берутся. Мне тоже в конечном итоге все равно, через какие дыры в чипе они пролезут, значит надо взять один байт, и пропихать его через ноги нескольких портов не затронув установленные данные на остальных битах.

В принципе я могу наворотить всяких там дефов одного другому, но думаю, что проблема решалась миллионы раз и еще когда я пешком под стол ходил и на этот случай есть красивое решение...
o_l_e_g
Участник
Сообщения: 2422




19-01-2013 23:44

Васисуалий, Вроде, в четырехбитном режиме можно засунуть на один GPIO, одним ниблом? Если что, смотри библиотеки Булевой алгебры.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 00:34

Индикатор ожил, но код, мягко говоря полное гуано...

Короче вопрос в силе. Расскажите, кто знает, как это делают по взрослому...
o_l_e_g
Участник
Сообщения: 2422




20-01-2013 01:40

Васисуалий, http://how2.org.ua/микроконтроллеры/работаем-с-lcd-дисплеем-wh1602-в-s ... Может поможет?
Konstantin_18
Участник
Сообщения: 3293




20-01-2013 02:49

Васисуалий, понятно что вы хотите "union" , но вот как записать сразу не скажу. Особенно если одинаковые (по весу) биты в разных портах. А что маленькая процедурка (ложим байт - дрыгаем битами ) - это не кошерно ?
ПС. Кстати даже если суперэлегантно записать получится, то совсем не факт, что потом компилятор это подпрограммой не оформит. Так стОит ли изобретать ?
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 19:47

Блин, захекался искать! Перерыл весь тырнет, просмотрел кучу книг и интернет учебников по Си и нифига не нашел. шок Неуже ли в таком замечательном и мощном языке как Си не нашлось места для конструкции аналога:

BTFSS (бит_тест_из_стейт)

или

BTFSC (из_клир)

Не верю! шок
Konstantin_18
Участник
Сообщения: 3293




20-01-2013 20:54

Васисуалий,
PORTA = PORTA & 0xFE - clear bit.
PORTA = PORTA I 0x01 - set bit.
if (PORTA & 0x01) - test bit
Я понимаю, что синтаксис скорее от БЭЙСИКА, но компилер сделает из него именно то о чем ты пишешь.

Более СИ-шно подшучивать, дразнить
PORTA &= 0xFE
PORTA |= 0x01
улыбка

Я думал ты хочешь описать переменную, типа слово-2-байта,
которая бы логически соответствовала 16 битному порту,
причем физические биты этого порта были бы разбросаны по РАЗНЫМ битам РАЗНЫХ физических портов.
Т.е. пишем IDEPORT = 0xABCD и оно САМО по 16 ногам нужные биты разбросало.
ПС. Размерность приведена для примера.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 22:32

Ну в принципе победил, индикатор работает. Правда накодил гору говнокода...

Вывод в порт для STM32 почему то выглядит так :

GPIOB->BSRRL = 0x30; // устанавливаем биты 4 и 5 порта GPIOB в 1
GPIOB->BSRRH = 0x30; // сбрасываем биты 4 и 5 порта GPIOB в 0

Это работает.

Дальше возникает проблема...

Я нигде не нашел простого теста стоячести бита в байте по типу комманды BTFSS или нестоячести BTFSC (асм для пиков)

Поэтому я сделал это по типу операции на гландах через опу...

Я прошелся по байту маской с одним установленным битом:
Код:

void Write_indicator(simbol)
{
 mask = 1;  // тест бита 0
  test_simbol = simbol & mask;
     if (test_simbol != 0)
         {
            GPIOE->BSRRL = 0x08;
         }

     mask = 2;  // тест бита 1
       test_simbol = simbol & mask;
          if (test_simbol != 0)
              {
               GPIOE->BSRRL = 0x10;
              }
          mask = 4;  // тест бита 2
            test_simbol = simbol & mask;
               if (test_simbol != 0)
                   {
                    GPIOB->BSRRL = 0x100;
                   }

               mask = 8;  // тест бита 3
                 test_simbol = simbol & mask;
                    if (test_simbol != 0)
                        {
                         GPIOB->BSRRL = 0x80;
                        }
                    mask = 16;  // тест бита 4
                      test_simbol = simbol & mask;
                         if (test_simbol != 0)
                             {
                              GPIOB->BSRRL = 0x20;
                             }

                         mask = 32;  // тест бита 5
                           test_simbol = simbol & mask;
                              if (test_simbol != 0)
                                  {
                                   GPIOB->BSRRL = 0x10;
                                  }
                              mask = 64;  // тест бита 6
                                test_simbol = simbol & mask;
                                   if (test_simbol != 0)
                                       {
                                        GPIOD->BSRRL = 0x80;
                                       }

                                   mask = 128;  // тест бита 7
                                     test_simbol = simbol & mask;
                                        if (test_simbol != 0)
                                            {
                                             GPIOD->BSRRL = 0x40;
                                            }
GPIOC->BSRRL = 0x2000;       // переключаем индикатор на вывод инфы на экран
Enable_Pulse();              // записываем данные в индикатор
Clear_Ind_Port();            // убираем мусор (в смысле чистим порт в 0)
}

Получилось работоспособно но как то грубо и неприкольно...

Надо искать выход, думаю он есть! стопудово
Konstantin_18
Участник
Сообщения: 3293




20-01-2013 22:40

А если не плодить переменные и вместо:
"
{
mask = 1; // тест бита 0
test_simbol = simbol & mask;
if (test_simbol != 0)
{
"
написать
if (simbol & 1) {

???
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 22:46

Да! Уже сообразил и исправил гы-гы

void Write_indicator(simbol)
{
mask = 1; // тест бита 0
if ((simbol & mask) != 0)
{
GPIOE->BSRRL = 0x08;
}
mask = 2; // тест бита 1
if ((simbol & mask) != 0)
{
GPIOE->BSRRL = 0x10;
}
mask = 4; // тест бита 2
if ((simbol & mask) != 0)

Добавлено 20-01-2013 22:47

Счас уберу и вторую переменную...
Konstantin_18
Участник
Сообщения: 3293




20-01-2013 22:50

Переменная mask тоже не нужна,
как и запись "!=0"
условие if выполнится если значение в скобках ненулевое

т.е. пишем
if (simbol & 1)

Но это уже больше казуистика улыбка
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 22:53

Ну вот теперь код выглядик как то логично...

Даже немного эротично помираю со смеху!

new-1.jpg



Konstantin_18
Участник
Сообщения: 3293




20-01-2013 22:57

А вот у меня еще вопрос. Это биты в единичку ставятся, а в ноль что не надо ?

if (simbol & 1) { GPIOE->BSRRL = 0x08; } else { GPIOE->BSRRH = 0x08; }

??? подшучивать, дразнить

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

Чтобы движок пробелы не убирал есть тэг Code.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 23:05

Так прикол в том, что BSRRL ставит в единичку указанный бит, а BSRRН сбрасывает. Причем именно то, что мне и надо, т.е. прозрачно для других бит порта. А в лесинке я только устанавливаю биты, сбрасываются они в конце, после подачи сигнала En на индикатор. Я для этого сочинил отдельный Void

Вот эти строки:
Код:

void Write_indicator(simbol)
{
     if ((simbol & 1) != 0)
         {
        GPIOE->BSRRL = 0x08;
         }
          if ((simbol & 2) != 0)
              {
                GPIOE->BSRRL = 0x10;
              }
               if ((simbol & 4) != 0)
                   {
                  GPIOB->BSRRL = 0x100;
                   }
                    if ((simbol & 8) != 0)
                        {
                        GPIOB->BSRRL = 0x80;
                        }
                         if ((simbol & 16) != 0)
                             {
                              GPIOB->BSRRL = 0x20;
                             }
                              if ((simbol & 32) != 0)
                                  {
                                    GPIOB->BSRRL = 0x10;
                                  }
                                   if ((simbol & 64) != 0)
                                       {
                                      GPIOD->BSRRL = 0x80;
                                       }
                                        if ((simbol & 128) != 0)
                                            {
                                            GPIOD->BSRRL = 0x40;
                                            }

GPIOC->BSRRL = 0x2000;       // переключаем индикатор на вывод инфы на экран
Enable_Pulse();              // записываем данные в индикатор
Clear_Ind_Port();            // убираем мусор (в смысле чистим порт в 0)
}



К стати в этих войдах тоже такой бардель, надо почистить... улыбка

Спасибо за тэг, никогда его не пользовал...
Konstantin_18
Участник
Сообщения: 3293




20-01-2013 23:15

Васисуалий, При первом вызове твоей процедуры биты в ноли КТО посбрасывает злость ?
У тебя же они в ее КОНЦЕ сбрасываются.

Я ж пишу :

if (simbol & 1) { GPIOE->BSRRL = 0x08; } else { GPIOE->BSRRH = 0x08; }

и НИЧЕГО в конце сбрасывать не нужно!

Добавлено 20-01-2013 22:17

символы " !=0 " тоже не нужны, если это АНСИшный СИ.

Добавлено 20-01-2013 22:17

ПС. Ты как-бы через строку читаешь.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 23:27

Дык процедура инициализации индикатора там впереди есть! Она порт чистым оставит...

Вот продолжаю причесывать и дописывать управление индикатором...

IMG_4863.jpg



Konstantin_18
Участник
Сообщения: 3293




20-01-2013 23:34

Так борьба ж за краткость, и как следствие - надежность.
Больше кода - больше ошибок!
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




20-01-2013 23:49

Konstantin_18 писал:
борьба за краткость, и как следствие - надежность!


Я еще бы сказал за понятность кода! Часто приходится вспоминать программки, которые писАл год и даже десять лет назад. Чем оно красивше написано, тем потом легче. Вот этот индикатор с этим STMом мне сегодня и нафиг не сдался - я просто балуюсь, но отлажу и положу себе готовый наборчик кодов для работы с индикатором, может оформлю в отдельный "инклюдик" и пусть будет... подмигивание улыбка Пьем пиво

Добавлено 21-01-2013 00:08

А вот, к стати, как сам компилятор представил мое творение на асме:

Код:

 35            if (simbol & 1)
08000548:   ldr r3, [r7, #4]
0800054a:   and.w r3, r3, #1
0800054e:   uxtb r3, r3
08000550:   cmp r3, #0
08000552:   beq.n 0x8000562 <Write_indicator+34>
 37               GPIOE->BSRRL = 0x08;
08000554:   mov.w r3, #4096 ; 0x1000
08000558:   movt r3, #16386 ; 0x4002
0800055c:   mov.w r2, #8
08000560:   strh r2, [r3, #24]


для куска :

Код:

if (simbol & 1)
         {
        GPIOE->BSRRL = 0x08;
         }


rommy
Участник
Сообщения: 5341




21-01-2013 00:57

Может в МК перекинуть тему?Тут она быстро потеряется.
INT1
Участник
Сообщения: 391




21-01-2013 07:06

Есть док
http://www.gaw.ru/html.cgi/txt/app/micros/avr/AVR035.htm
правда, он заточен под IAR AVR, но может что полезного найдешь.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




21-01-2013 09:17

Ну в принципе вопрос решен. Код мне уже нравится.
Rаmil
Гость 178.207.*.*





11-09-2014 13:21

Тема дааааавно решена, но я только что увидел
и могу предложить вот такой код, может кому и пригодится.

Код:
 

const short gpio_val[8] = {0x08,0x10,0x100,0x80,0x20,0x10,0x80,0x40};
short BSRRL;

void Write(char symbol)
{
   short tmp = 1;
   char i = 0;
   for(; i < 9; i++)
    {
      if(symbol&tmp)
       {
         BSRRL = gpio_val[i];
         break;
       }
     tmp = tmp<<1;
    }
}


поправил немного
slav0n
Забанен
Забанен
Сообщения: 2261




11-09-2014 21:29

Код:
void Write(char symbol)
   {
      short *p = gpio_val;
      while(symbol)
      {
         if(symbol & 1)BSRRL = *p;
         p++;
         symbol  >>= 1;
      }
   }

Murka
Профессор
Сообщения: 2746




15-09-2014 21:41

Васисуалий, А индикатор 5_ти вольтовый от 3.3 вольта?
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




15-09-2014 22:56

Питание от пяти, иначе он ваАще не работает, а вот входы толерантны...

Причем это был какой то там аналог "Винстара" а-ля почти фирма! Я не уверен, что такое же точно можно сделать с самим "Винстаром" или же с другими его аналогами...
Murka
Профессор
Сообщения: 2746




15-09-2014 23:03

Васисуалий, Та наверное можно, там-же в STM_e просто транзисторы на выходе стоят 5-ти вольтовые, кажись там ваще opendrain. Просто на фотке pullap_ы не видны, или их там нет?
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




15-09-2014 23:55

На плате их точно нет, а я их однозначно не ставил. В прочем если это интересно, предлагаю открыть новую тему по изучению макетки STM32F4 Discovery...
Murka
Профессор
Сообщения: 2746




16-09-2014 00:17

Не, это всё пока на будущее, сейчас открывать рано, работы полно.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5006




16-09-2014 00:22

Я на всякий случай тут темку создал >> http://monitor.net.ru/forum/viewtopic.php?t=535529
Rаmil
Гость 178.207.*.*





16-09-2014 12:24

slav0n, да так попроще. Ещё нужно добавить массив указателей на порты и будет полное соответствие задуманному автором.
Я проглядел как то, что порты разные.

Код:


const unsigned char gpio_val[8] = {0x08,0x10,0x100,0x80,0x20,0x10,0x80,0x40};


// массив указателей на порты
int  *BSRRL[8] = {&GPIOE->BSRRL,&GPIOE->BSRRL,&GPIOB->BSRRL,&GPIOB->BSRRL,
                            &GPIOB->BSRRL,&GPIOB->BSRRL,&GPIOD->BSRRL,&GPIOD->BSRRL};

void Write(char symbol)
   {
      short *p = gpio_val;
      while(symbol)
      {
         if(symbol & 1)  *BSRRL = *p;
         p++;
         BSRRL++;
         symbol  >>= 1;
      }
   }

Список форумов » Среда разработчика » Программисты C нужна помощь...
Перейти:  
Текущий раздел » Среда разработчика ( Программы, базы данных, документация, симуляторы и т.д.)


Похожая информация:
  • Что курят программисты? (про си, контроллер, таблицу и ...)







  • Электроника
    Прошивки и схемы на телевизоры, мониторы, dvd, телефоны. Schematic, Service Manual (mode), eeprom dumps Информация по ремонту для специалистов - справочники, инструкции, энциклопедия, советы и секреты ремонта,  настройка, сервисные режимы поиск и продажа электронных компонентов, магазины, datasheet, pdf, размещение в интернете рекламы на сайтах электронной тематики
    Powered by phpBB 2.0.18 © 2001, 2002 phpBB Group!