мега16
Dec 26 2010, 12:11
Вобщем,нужно для светодиодного табло,на сдвиговые регистры пихать биты из массива,я так понимаю-нужно с конца массива поочередно брать биты. На си, например массив
Код
unsigned char code[]={0x38,0x7C,0x38,0xFE,0xFE,0x7C,0x38,0x7C};
Как их вытащить? На си код хотелось бы увидеть.
kurtis
Dec 26 2010, 12: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); /* альтернативный вариант */
}
Methane
Dec 26 2010, 12:26
Цитата(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
Dec 26 2010, 12:35
Код
size_t i;
-а что это? Компилятор CVAVR ругается на это.
Цитата(мега16 @ Dec 26 2010, 18:35)

Код
size_t i;
-а что это? Компилятор CVAVR ругается на это.
Поставьте просто int, а можно и char, если массив у вас такой короткий.
sigmaN
Dec 26 2010, 12:55
a ведь никто и не посоветует человеку привыкать к стандартному заголовку stdint.h
http://en.wikipedia.org/wiki/Stdint.hи использовать uint8_t вместо unsigned char ))
мега16
Dec 26 2010, 13:02
Пробую в Протеусе, матрица на 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
Dec 26 2010, 13:05
Methane ответил на Ваш вопрос. а вы же пытаетесь байт выдать за бит )
мега16
Dec 26 2010, 13:16
Извиняюсь-забыл это добавить, опять непонятно-то что красным отмечено
for(j=0;j<8;j++) push_bit( (code[i]&(1<<j))?1:0 )
Цитата(Xenia @ Dec 26 2010, 21:36)

.. если массив у вас такой короткий.

..Тот задумчивый и кроткий,
У кого массив короткий.
Нет сомнений за душой,
У кого массив большой.
мега16
Dec 26 2010, 13:45
Юмор я понимаю, но мне проблему решить..
Methane
Dec 26 2010, 13:50
Цитата(мега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
Dec 26 2010, 14:04
Да уж,это слишком сложно для меня
Methane
Dec 26 2010, 14:08
Цитата(мега16 @ Dec 26 2010, 19:04)

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

Пойти изучать Баском АВР чтоли, все таки для себя самому сделать охота..
JAVA.
мега16
Dec 26 2010, 14:23
Байт то в порт выводит, в том же коде есть,просто из массива вытаскивать не умею.
На JAVA для АВР компилятор есть чтоли?
kurtis
Dec 26 2010, 14:30
Приведите код который у вас выводит байт в порт
Methane
Dec 26 2010, 14:31
Цитата(мега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
Dec 26 2010, 14:56
Цитата
Приведите код который у вас выводит байт в порт
Код
for (counter = 0; counter < 64; counter++){ // цикл
DS = 1; //записываем в линию данных 1
//Дергаем ногой чтоб пропихнуть бит в регистр-отправляем через порт на сдвиговые регисты
SH_CP = 1;
SH_CP = 0;
}
//Дергаем ногой и защёлкиваем данные
ST_CP = 1;
ST_CP = 0;
-отправляются 64 бита и горят все светодиоды
Ах да,вы про байт,я про бит
kurtis
Dec 26 2010, 14: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;
}
Methane
Dec 26 2010, 15:01
Цитата(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
Dec 26 2010, 15:04
это автору
мега16
Dec 26 2010, 15:28
ВОТ СПАСИБО- это работает !
мега16
Dec 28 2010, 02:45
Блин,работает,но неправильно вытаскивает байты.
AHTOXA
Dec 28 2010, 03:59
Цитата(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
Dec 28 2010, 06:19
Вот так оптимальнее будет:-)
Код
uint8_t temp = code[i];
for (uint8_t j=0; j<8; j++, temp>>=1)
{
if (temp & 1)
{
...
}
else
{
...
}
}
мега16
Dec 28 2010, 07:03
Почему же так?
Код
my_type code[]={11111111,00000000,11110000,11100111};
Methane
Dec 28 2010, 07:19
Цитата(мега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
Dec 28 2010, 12:58
Ну все ясно,работает правильно,вот в интернете шрифт нашел-попробовал,буква "А"-отражается нормально,правда повернуто-ну это понятно-шрифт для бегущего луча-т.е. для динамической индикации,я хочу собрать схему со статической.Главное-нормально работает код,все равно самому шрифт сделать придется,потому что 8 рядов светодиодов мало,хочу 16 сделать. Вот пример буквы "А"-
Код
my_type code[]={0x30,0x78,0xCC,0xCC,0xFC,0xCC,0xCC,0x00};

Спасибо большое всем.
Продолжаю тему. Решил так организовать вывод символов на табло- для каждого символа функция показанная выше, символы ,какие надо вывести, записываю в массив(очень желательно в еепром,так как туда можно будет потом писать снаружи через усарт), вытаскиваю из массива символы и подставляю функции,соответствующие символам.
Если так-
Код
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
Jan 5 2011, 08:52
Содержимое EEPROM располагается в своем собственном/отдельном адресном пространстве и доступ к EEPROM осуществляется через регистры модуля EEPROM.
Хм, а попонятнее можно,как же мне быть?
rezident
Jan 5 2011, 08:55
Цитата(мега16 @ Jan 5 2011, 16:53)

Хм, а попонятнее можно,как же мне быть?
Написать функцию извлечения данных из EEPROM, если таковой нет в библиотеке, сопутствующей вашему компилятору.
Вообще то CVAVR работает с EEPROM прозрачно-
Код
eeprom chap x;
x=1;
y=x;
-это нормально работает, а вот с массивом- нет, или Протеус это не понимает, на железе не проверял.
rezident
Jan 6 2011, 18:04
Цитата(мега16 @ Jan 6 2011, 20:33)

Вообще то CVAVR работает с EEPROM прозрачно-
...это нормально работает, а вот с массивом- нет
В приведенном вами примере все действительно прозрачно. Константа препроцессором или оптимизатором компилятора переносится прямо в EEPROM. Проблема-то у вас не в этом, а в прямом доступе к памяти EEPROM при обращении к переменным, расположенным там. Почитайте наконец об архитектуре МК, его адресном пространстве и о различиях в типах и областях расположения данных.
demiurg_spb
Jan 6 2011, 20:01
Цитата(rezident @ Jan 7 2011, 00:04)

В приведенном вами примере все действительно прозрачно. Константа препроцессором или оптимизатором компилятора переносится прямо в EEPROM.
Насколько я могу судить, CV сам использует функции чтения записи при обращении к EEPROM данным (не константам). Таким образом, для пользователя предоставляется прозрачный механизм работы с EEPROM по аналогии с обычными переменными в ОЗУ.
rezident
Jan 6 2011, 20:13
Ну я же написал выше, что при наличии библиотечных функций все просто. При отсутствии их нужно написать свои. По сути дела данные, расположенные во внутренней EEPROM, мало чем отличаются от данных, располагающихся во внешней м/с EEPROM.
demiurg_spb
Jan 7 2011, 07:05
to
мега16 приведите asm-листинг такого кода:
Код
char str1[] = "0123456789";
eeprom char str2[] = "0123456789";
for (uint8_t i=0; i<10; i++)
{
PORTB = str1[i];
PORTA = str2[i];
}
CVAVR на uint8_t ругается.
rezident
Jan 8 2011, 10:56
Цитата(мега16 @ Jan 8 2011, 10:36)

CVAVR на uint8_t ругается.
Цитата(мега16 @ Jan 8 2011, 16:45)

Ругается все равно.
Ничего удивительного. CodeVision это такой недокомпилятор, использующий свою собственную интерпретацию стандарта языка Си.
На другом форуме посоветовали- надо объявить массив eeprom глобальным, с необходимым размером, без инициализации. В main присвоить нужные значения элементам. И так работает.
CodeVision в топку! use gcc ))
demiurg_spb
Jan 9 2011, 14:47
Цитата(мега16 @ Jan 8 2011, 08:36)

CVAVR на uint8_t ругается.
замените uint8_t на unsigned char
мега16
Jan 24 2011, 05:20
Упростил так-
Код
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++) {
или не можно? Я так по всякому пробовал-но не получается.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.