Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как последовательно вытаскивать биты из массива?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
мега16
Вобщем,нужно для светодиодного табло,на сдвиговые регистры пихать биты из массива,я так понимаю-нужно с конца массива поочередно брать биты. На си, например массив
Код
unsigned char code[]={0x38,0x7C,0x38,0xFE,0xFE,0x7C,0x38,0x7C};
Как их вытащить? На си код хотелось бы увидеть.
kurtis
Код
size_t i;
unsigned char some_value;

for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
    some_value = code[i];
    // some_value = *(code + i); /* альтернативный вариант */
}
Methane
Цитата(kurtis @ Dec 26 2010, 17:18) *
Код
size_t i;
unsigned char some_value;

for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
    some_value = code[i];
    // some_value = *(code + i); /* альтернативный вариант */
}

БИТЫ не прочитали.

Код
size_t i;
unsigned char some_value;

for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
    some_value = code[i];
    // some_value = *(code + i); /* альтернативный вариант */
   for(j=0;j<8;j++) push_bit(  (code[i]&(1<<j))?1:0  )
}
мега16
Код
size_t i;
-а что это? Компилятор CVAVR ругается на это.
Xenia
Цитата(мега16 @ Dec 26 2010, 18:35) *
Код
size_t i;
-а что это? Компилятор CVAVR ругается на это.

Поставьте просто int, а можно и char, если массив у вас такой короткий. sm.gif
sigmaN
a ведь никто и не посоветует человеку привыкать к стандартному заголовку stdint.h http://en.wikipedia.org/wiki/Stdint.h
и использовать uint8_t вместо unsigned char ))
мега16
Пробую в Протеусе, матрица на 1 букву 8х8 светодиодов, вот с этим кодом горят все светодиоды,что то не то.
Код
unsigned char counter;

unsigned char code[]={0x38};
int i;
unsigned char some_value;

DDRD=0x0F;

    RESET=1;  //линия сброса отключена
    
    for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
    some_value = code[i];
    
for (counter = 0; counter < 64; counter++){  // цикл
DS = some_value;      //записываем в линию данных
//Дергаем ногой чтоб пропихнуть бит в регистр
SH_CP = 1;
SH_CP = 0;
  }
  //Дергаем ногой и защёлкиваем данные
  ST_CP = 1;
  ST_CP = 0;
      }
sigmaN
Methane ответил на Ваш вопрос. а вы же пытаетесь байт выдать за бит )
мега16
Извиняюсь-забыл это добавить, опять непонятно-то что красным отмечено
for(j=0;j<8;j++) push_bit( (code[i]&(1<<j))?1:0 )
Wise
Цитата(Xenia @ Dec 26 2010, 21:36) *
.. если массив у вас такой короткий. sm.gif


..Тот задумчивый и кроткий,
У кого массив короткий.
Нет сомнений за душой,
У кого массив большой.
rolleyes.gif
мега16
Юмор я понимаю, но мне проблему решить..
Methane
Цитата(мега16 @ Dec 26 2010, 18:16) *
Извиняюсь-забыл это добавить, опять непонятно-то что красным отмечено
for(j=0;j<8;j++) push_bit( (code[i]&(1<<j))?1:0 )

push_bit - функция которую. вам нужно написать
что-то вроде
static void
push_bit(char in)
{
strob = 0; //сигнал строба в 0
data_out = in; // BIT (1 нога процессора) должна опустится в 0 если на входе 0. Или подняться в 1, если на входе функции не 0.
strob = 1; // по фронту строба сдвигули бит дальше.
}

Про оператор (condition)? val_for_true:val_for_false посмотрите в книжке про С. Я не помню как оно называется.

Цитата(мега16 @ Dec 26 2010, 18:45) *
Юмор я понимаю, но мне проблему решить..

Лучше решите проблему как сделать ее дешевле в Китае.
мега16
Да уж,это слишком сложно для меня
Methane
Цитата(мега16 @ Dec 26 2010, 19:04) *
Да уж,это слишком сложно для меня

Совершенно верно. На С любой дурак писать может. А вот сделать у нас, дешевле чем в Китае, это уже фиг! А сделать так чтобы китайцы не начали делать тоже самое но еще дешевле, это уже вообще не реально, как смерть фотона от старости.
мега16
Пойти изучать Баском АВР чтоли, все таки для себя самому сделать охота..
kurtis
Напишите сначала программу которая просто выдает 1 байт в порт.
Methane
Цитата(мега16 @ Dec 26 2010, 19:12) *
Пойти изучать Баском АВР чтоли, все таки для себя самому сделать охота..

JAVA.
мега16
Байт то в порт выводит, в том же коде есть,просто из массива вытаскивать не умею.
На JAVA для АВР компилятор есть чтоли?
kurtis
Приведите код который у вас выводит байт в порт
Methane
Цитата(мега16 @ Dec 26 2010, 19:23) *
Байт то в порт выводит, в том же коде есть,просто из массива вытаскивать не умею.

Все просто.

(code[i]&(1<<j))?1:0

Разберем.

code[i]
Это просто берем значение с индексом i из массива (вектора) code.
(1<<j)
Напишите прогу (для ПС)
for (int i=0;i<10;i++) printf ( " i= %i 1<<i= %i\n" i, (1<<i));
Полученные 10 значений переведите в бинарную форму из десятичной. Потом сами догадаетесь что значит 1<<i

Ну а & просто http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%...%86%D0%B8%D1%8F

В С, переменная истинна, если хоть один бит в ней не равен 0.


Цитата
На JAVA для АВР компилятор есть чтоли?

На java можно писать для более хорошо оплачиваемых вещей, кроме как AVR.
мега16

Цитата
Приведите код который у вас выводит байт в порт

Код
for (counter = 0; counter < 64; counter++){  // цикл
DS = 1;      //записываем в линию данных 1
//Дергаем ногой чтоб пропихнуть бит в регистр-отправляем через порт на сдвиговые регисты
SH_CP = 1;
SH_CP = 0;
  }
  //Дергаем ногой и защёлкиваем данные
  ST_CP = 1;
  ST_CP = 0;

-отправляются 64 бита и горят все светодиоды

Ах да,вы про байт,я про бит
kurtis
Код
#include <limits.h>

typedef unsigned char my_type;

my_type code[]={0x38,0x7C,0x38,0xFE,0xFE,0x7C,0x38,0x7C};

int main()
{
    unsigned int i, j;

    DDRD = 0x0F;
    RESET = 1;

    for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
        for (j=0; j<(sizeof(my_type)*CHAR_BIT); j++) {
            if (code[i] & j) {
                DS = 1;
            }
            else {
                DS = 0;
            }
            SH_CP = 1;
            SH_CP = 0;
        }

    }

    ST_CP = 1;
    ST_CP = 0;

    return 0;
}
Methane
Цитата(kurtis @ Dec 26 2010, 19:57) *
Код
#include <limits.h>

typedef unsigned char my_type;

my_type code[]={0x38,0x7C,0x38,0xFE,0xFE,0x7C,0x38,0x7C};

int main()
{
    unsigned int i, j;

    DDRD = 0x0F;
    RESET = 1;

    for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
        for (j=0; j<(sizeof(my_type)*CHAR_BIT); j++) {
            if (code[i] & j) {
                DS = 1;
            }
            else {
                DS = 0;
            }
            SH_CP = 1;
            SH_CP = 0;
        }

    }

    ST_CP = 1;
    ST_CP = 0;

    return 0;
}

Это чё?
kurtis
это автору
мега16
ВОТ СПАСИБО- это работает !
мега16
Блин,работает,но неправильно вытаскивает байты.
AHTOXA
Цитата(kurtis @ Dec 26 2010, 22:57) *
Код
    for (i=0; i<sizeof(code)/sizeof(code[0]); i++) {
        for (j=0; j<(sizeof(my_type)*CHAR_BIT); j++) {
            if (code[i] & j) {

В последней строчке надо
Код
            if (code[i] & (1 << j)) {

demiurg_spb
Вот так оптимальнее будет:-)
Код
uint8_t temp = code[i];

for (uint8_t j=0; j<8; j++, temp>>=1)
{
  if (temp & 1)
  {
    ...
  }
  else
  {
     ...
  }
}
мега16
Почему же так?
Код
my_type code[]={11111111,00000000,11110000,11100111};

Methane
Цитата(мега16 @ Dec 28 2010, 12:03) *
Почему же так?
Код
my_type code[]={11111111,00000000,11110000,11100111};


11110000 это десятичное число. И причем my_type должно быть 32 бита.
Лучше сделайте себе файлик,
#define BIN0000_0000 0x00
#define BIN0000_0001 0x01
#define BIN0000_0010 0x02
#define BIN0000_0011 0x03
и инклюдьте его туда где вам нужно что-то в бинарном виде рисовать.
мега16
Ну все ясно,работает правильно,вот в интернете шрифт нашел-попробовал,буква "А"-отражается нормально,правда повернуто-ну это понятно-шрифт для бегущего луча-т.е. для динамической индикации,я хочу собрать схему со статической.Главное-нормально работает код,все равно самому шрифт сделать придется,потому что 8 рядов светодиодов мало,хочу 16 сделать. Вот пример буквы "А"-
Код
my_type code[]={0x30,0x78,0xCC,0xCC,0xFC,0xCC,0xCC,0x00};


Спасибо большое всем.
мега16
Продолжаю тему. Решил так организовать вывод символов на табло- для каждого символа функция показанная выше, символы ,какие надо вывести, записываю в массив(очень желательно в еепром,так как туда можно будет потом писать снаружи через усарт), вытаскиваю из массива символы и подставляю функции,соответствующие символам.
Если так-
Код
char mass[]={"a,b,c"};
-все нормально выводит, а если-
Код
eeprom char mass[]={"a,b,c"};
-то ничего не происходит, не могу понять..
Вот такой код-
Код
   void read_stroka(){unsigned int i;
for(i=0; i<sizeof(mass); i++){
switch(mass[i]){
   case 'a': cifra0(); break;
   case 'b': cifra1(); break;
   case 'c': cifra2(); break;
   }
}
}
rezident
Содержимое EEPROM располагается в своем собственном/отдельном адресном пространстве и доступ к EEPROM осуществляется через регистры модуля EEPROM.
мега16
Хм, а попонятнее можно,как же мне быть?
rezident
Цитата(мега16 @ Jan 5 2011, 16:53) *
Хм, а попонятнее можно,как же мне быть?
Написать функцию извлечения данных из EEPROM, если таковой нет в библиотеке, сопутствующей вашему компилятору.
мега16
Вообще то CVAVR работает с EEPROM прозрачно-
Код
eeprom chap x;
x=1;
y=x;
-это нормально работает, а вот с массивом- нет, или Протеус это не понимает, на железе не проверял.
rezident
Цитата(мега16 @ Jan 6 2011, 20:33) *
Вообще то CVAVR работает с EEPROM прозрачно-
...это нормально работает, а вот с массивом- нет
В приведенном вами примере все действительно прозрачно. Константа препроцессором или оптимизатором компилятора переносится прямо в EEPROM. Проблема-то у вас не в этом, а в прямом доступе к памяти EEPROM при обращении к переменным, расположенным там. Почитайте наконец об архитектуре МК, его адресном пространстве и о различиях в типах и областях расположения данных.
demiurg_spb
Цитата(rezident @ Jan 7 2011, 00:04) *
В приведенном вами примере все действительно прозрачно. Константа препроцессором или оптимизатором компилятора переносится прямо в EEPROM.
Насколько я могу судить, CV сам использует функции чтения записи при обращении к EEPROM данным (не константам). Таким образом, для пользователя предоставляется прозрачный механизм работы с EEPROM по аналогии с обычными переменными в ОЗУ.
rezident
Ну я же написал выше, что при наличии библиотечных функций все просто. При отсутствии их нужно написать свои. По сути дела данные, расположенные во внутренней EEPROM, мало чем отличаются от данных, располагающихся во внешней м/с EEPROM.
demiurg_spb
to мега16 приведите asm-листинг такого кода:
Код
char str1[] = "0123456789";
eeprom char str2[] = "0123456789";
for (uint8_t i=0; i<10; i++)
{
    PORTB = str1[i];
    PORTA = str2[i];
}
мега16
CVAVR на uint8_t ругается.
sigmaN
#include <stdint.h>
мега16
Ругается все равно.
rezident
Цитата(мега16 @ Jan 8 2011, 10:36) *
CVAVR на uint8_t ругается.

Цитата(мега16 @ Jan 8 2011, 16:45) *
Ругается все равно.

Ничего удивительного. CodeVision это такой недокомпилятор, использующий свою собственную интерпретацию стандарта языка Си. laughing.gif

мега16
На другом форуме посоветовали- надо объявить массив eeprom глобальным, с необходимым размером, без инициализации. В main присвоить нужные значения элементам. И так работает.
sigmaN
CodeVision в топку! use gcc ))
WHALE
delete
demiurg_spb
Цитата(мега16 @ Jan 8 2011, 08:36) *
CVAVR на uint8_t ругается.
замените uint8_t на unsigned char
мега16
Проблема решена уже.
мега16
Упростил так-
Код
  void bits(){unsigned int i,j;
    for (i=0; i<32; i++) {
        for (j=0; j<8; j++) {
          if (mass[i] & (1 << j))
          {DS = 1;}     //записываем в линию данных
          else {DS = 0;}        
        }}}

Работать то работает, но хочется конкретно понять, а именно вот эту часть-
Код
if (mass[i] & (1 << j))

Если на словах сказать-получается так- Если первый байт(к примеру) равен 1 и следующий бит равен 1, то...,но как может быть байт равен единице,там же 8 битов. И вообще, можно ли вытащить биты без двух циклов, у меня там всегда 32 байта по 8 битов, так что можно так-
Код
for (i=0; i<256; i++) {
или не можно? Я так по всякому пробовал-но не получается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.