КАРАУЛ... Массивы глючат (Решено)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

КАРАУЛ... Массивы глючат (Решено)

Сообщение krysun »

....толи лыжи не едут (
Пример:

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

x=massiv[5];   //Работает
//********************
x=massiv[i];   //НЕ работает

Листинг:

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

#include <mega162.h>
#include <delay.h>
interrupt [PCINT1] void pin_change_isr1(void)
{}
int a=0b10000000;    // масска
int digit[10]={           
0b00111111,               // 0
0b00000110,               // 1
0b01011011,               // 2
0b01001111,               // 3
0b01100110,               // 4
0b01101101,               // 5
0b01111101,               // 6
0b01111101,               // 7
0b01111111,               // 8
0b01101111,               // 9
};
void main(void)
{
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTB=0x00;
DDRB=0xB7;
PORTD=0x00;
DDRD=0x08;
GICR|=0x10;
PCMSK1=0x0F;
MCUCR=0x00;
EMCUCR=0x00;
GIFR=0x10;
TIMSK=0x00;
ETIMSK=0x00;
ACSR=0x80;
#asm("sei")
while (1)
      {
      char i,j;
      for (j=0;j<10;j++){ 
        PORTB.0=0;              //Врубаем ОЕ
        for(i=0;i<=7;i++)
        {
        PORTB.5=digit[j]&a;     // DATA - с "[j]" не работает (а с цыфрой, напр."[5]"-ok
        PORTB.7=1;PORTB.7=0;    // Дергаем CLOCK
        a=a>>1;                 // смещаем маску
        if (a==0b00000000) {a=0b10000000;}; // проверяем маску
        }
        PORTB.0=1;              //Вырубаем ОЕ
      }     
      delay_ms(1000);
      };
}


Не могу прочитать значения в цикле for массива по указанному переменной индексу.
Как быть?
Последний раз редактировалось krysun Сб ноя 13, 2010 23:36:41, всего редактировалось 1 раз.
Это лыжи не едут!!!
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: КАРАУЛ... Массивы глючат ((

Сообщение DX168B »

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

int digit[6]={0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5};    //Наш массив.
int a = 0;    // Это будет нашим индексом для массива
int data;    //Суда мы впишем считанный байт из массива

int main()
{
   DDRA = 0xFF;    //Порт А настроим на выход.
   a = 2;    //Например нам надо считать второй байт из массива (0xF1)
   for(int i = 0; i < a; i++){data = digit[i];}    //Вытащим его из массива.
   PORTA = data;    //И например отправим его (байт из массива) в Порт А
   ...............    // и т.д.
   ......
   .....
}

Ещё у меня работало даже такое:

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

int digit[6]={0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5};    //Наш массив.
int a = 0;    // Это будет нашим индексом для массива

int main()
{
   DDRA = 0xFF;    //Порт А настроим на выход.
   a = 3;    //Например нам надо считать третий байт из массива (0xF2)
   PORTA = digit[a];    //И например отправить его (байт из массива) в Порт А
   ...............    // и т.д.
   ......
   .....
}

И без извратов. :) :)

----------
Попробуй так:

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

  while(1)
  {
        for (int j = 0; j < 10; j++)
        {
               PORTB.0 << 0;              //Врубаем ОЕ
               for(int i = 0; i <= 7; i++)
               {
                       PORTB.5 = digit[j]&a;     //
                       PORTB.7 << 1;
                       PORTB.7 << 0;    // Дергаем CLOCK
                       a = a >> 1;                 // смещаем маску
                       if (a == 0b00000000) {a = 0b10000000;} // проверяем маску
               }
               PORTB.0 << 1;              //Вырубаем ОЕ
        }     
        _delay_ms(1000);
  }

Можно ещё попробовать вынести переменные i и j в объявление глобальных переменных (до функции main() так же, как массив и переменная a). И не обязательно, чтобы они были char типа. Один фиг туда число записывается.
I am DX168B and this is my favourite forum on internet!
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

Re: КАРАУЛ... Массивы глючат ((

Сообщение lix »

Всегда девятку выводит? _delay_ms надо в цикл по j поместить.
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

Re: КАРАУЛ... Массивы глючат ((

Сообщение lix »

а еще тип значение массива digits лучше сделать unsigned char для экономии флеш и добавить FLASH чтобы этот массив не занимал место в оперативке.
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

Re: КАРАУЛ... Массивы глючат ((

Сообщение krysun »

lix писал(а):Всегда девятку выводит? _delay_ms надо в цикл по j поместить.

Да нет, не всегда... Всегда разные числа (рандомные в том числе). Вопрос в чтении массива по индексу...
Примерчики почитал, сейчас запустю свою махину, проверю)
Спасибо.
ЗЫ: С делеем правы.... Кроме девятки предыдущих просто не увижу) Но... Как говорится, наступил бы еще и на эти грабли)
Это лыжи не едут!!!
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

Re: КАРАУЛ... Массивы глючат ((

Сообщение krysun »

Ничего не вышло.....
Кстати, на объявление переменной непосредственно в цикле

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

      for (int v = 0; v < 10; v++){}

пишет следующее:
Error: C:\cvavr2\my_project\tvister\1.c(94): undefined symbol 'int'
Error: C:\cvavr2\my_project\tvister\1.c(94): undefined symbol 'v'
Error: C:\cvavr2\my_project\tvister\1.c(94): undefined symbol 'v'


Благим матом, короче :(
Это лыжи не едут!!!
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

Re: КАРАУЛ... Массивы глючат ((

Сообщение krysun »

И вроде бы все правильно.
И код должен работать, и объявление, в принципе, нормальное.
А нет же.... Не пашет.
Не читает он индекс как цифру.... Не хочет выводить биты.
Паника.
Это лыжи не едут!!!
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Re: КАРАУЛ... Массивы глючат ((

Сообщение DrWatson »

Куда данные-то выводятся (регистр сдвига? какой? TICxx? какой?) далее к каким пинам что подключено (DI - PINB.5, CLK - PINB.7, OE - PINB.0 - что за OE, как в даташите описан? где LD (LOAD и т.п.))?
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
Аватара пользователя
van_de_luxe
Встал на лапы
Сообщения: 103
Зарегистрирован: Вс окт 31, 2010 16:46:10
Откуда: Оттуда

Re: КАРАУЛ... Массивы глючат ((

Сообщение van_de_luxe »

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

int a=0b10000000;    // масска
int digit[10]=           

лучше объяви как volatile unsigned char
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: КАРАУЛ... Массивы глючат ((

Сообщение avreal »

DX168B писал(а):И не обязательно, чтобы они были char типа. Один фиг туда число записывается.
Я даже более жёстко выражусь — «лучше, чтобы они были не char, поскольку туда число записывается».
В зависимости от контроллера/компилятора char может оказаться как знаковым, так и беззнаковым, поэтому если нужен просто «короткий» счётчик или там переменная для хранения малых чисел, то ндо явно указать знаковость — unsigned char или signed char.
Для упрощения раньше просто писались для себя typedef-ы

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

typedef unsigned char uchar;
typedef signed char schar;
По нынешним временам для унификации стоит применять стандартизованные начиная с C99 типы фиксированного размера.

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

#include <stdint.h>

uint8_t small_counter;
Даже если компилятор не соответствует стандарту С99, стоит написать свои typedef-ы для этих стандартизованных типов.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: КАРАУЛ... Массивы глючат ((

Сообщение DX168B »

Ставь AVR Studio 4 и WinAVR. Там хоть таких багов с обьявлениями переменных нет.
На конструкцию, типа for (int i = 0; i < 10; i++) компилятор у меня не ругается.
Но ругается на такое: PORB.3 = 1;
I am DX168B and this is my favourite forum on internet!
Murav
Опытный кот
Сообщения: 877
Зарегистрирован: Чт фев 18, 2010 13:51:56

Re: КАРАУЛ... Массивы глючат ((

Сообщение Murav »

DX168B писал(а):На конструкцию, типа for (int i = 0; i < 10; i++) компилятор у меня не ругается.

Такие конструкции появились только в стандарте C99(ну и в C++ откуда собственно они и пришли), который очень многие копиляторы не поддерживают. А GCC - поддерживает.
DX168B писал(а):Но ругается на такое: PORB.3 = 1;

А это - расширение языка, которое добавлено в некоторых компиляторах. Например в CVAVR.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: КАРАУЛ... Массивы глючат ((

Сообщение avreal »

Если бы ещё кое-что приятное из С99 в С++ пришло, было бы вообще хорошо.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

Re: КАРАУЛ... Массивы глючат ((

Сообщение krysun »

Хм, за ответы спасибо!

Значит, стоит забросить CVAVR и переходить на WinAVR?

Ну да ладно. Но интересует вопрос: "Как???" же все-таки объявить массив и обратится к нему по "small_counter" индексу (в подцикле for цикла for, сори за каламбур), что-бы прочитать данные?

На вопрос КУДА, и ЧЕРЕЗ ЧТО я вывожу, скажу:
mega162 -> HC244n -> HC4094 -> 3-и 7SEG индикатора.
Я поднимал тему по иному вопросу этого же девайса....
В итоге тоже ничего не вышло. 4094 подключен к mega162 по SPI.
Выводить получается, но как-то все "раком".
При:

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

SPI(7); //например

на все три индикатора выводятся эти "семерки".

Вот темка:
http://forum.radiokot.ru/viewtopic.php?f=20&t=36422
Можете ознакомится.

ps: Толкать биты по одному и таким образом зажигать нужные цыфры "без проблемм".
Использовать же SPI, или хотя-бы массив с маской - кукиш.
Вот и ломаю голову.
А дальше еще и со звуком разбиратся ((
Это лыжи не едут!!!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: КАРАУЛ... Массивы глючат ((

Сообщение ARV »

я дам "странные" советы...

сделайте функции, выполняющие отдельные задачи, чтобы алгоритм вырисовывался четко. например: вы там что-то куда-то выводите, беря данные из массива. вот и сделайте примерно так:

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

#define MAXIMUM 32
unsigned char massiv[MAXIMUM];
static void send_byte(unsigned char byte); // функцию сами сделайте

int main(void){
   unsigned char i;
   for(i=0; i< MAXIMUM; i++){
      send_byte(massiv[i]);
   }
}


для выдачи отдельных битов байта посоветую использовать такой вариант маски:

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

unsigned char mask;
for(mask=0x01; mask; mask <<=1){
   // тут "накладываете" mask на передаваемый байт и т.п.
}
разумеется, сдвиг маски и ее начальное значение определяются тем, со старшего или младшего бита вы выдаете число (мой пример - с младшего)

для работы с битами не пользуйтесь фичами типа PORTB.0, а используйте метод, который работает правильно ВСЕГДА и на ЛЮБОМ компиляторе:

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

PORTB |= (1<<BIT_NUMBER); // для установки бита BIT_NUMBER
PORTB &= ~(1<<BIT_NUMBER); // для сброса бита BIT_NUMBER
if(PINB & (1<<BIT_NUMBER)) {
   // для проверки значения бита BIT_NUMBER
}


мне кажется, когда вы сделаете "красивым" свой код - проблема пропадет, т.к. ее причина именно (по моему мнению) в неаккуратности, что затрудняет поиск ошибки.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

Re: КАРАУЛ... Массивы глючат ((

Сообщение krysun »

Спасибо, чудненькие советы.
Просто кроме CVAVR ничем не пользовался....
Это лыжи не едут!!!
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: КАРАУЛ... Массивы глючат ((

Сообщение avreal »

ARV писал(а):

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

#define MAXIMUM 32
unsigned char massiv[MAXIMUM];
static void send_byte(unsigned char byte); // функцию сами сделайте

int main(void){
   unsigned char i;
   for(i=0; i< MAXIMUM; i++){
      send_byte(massiv[i]);
   }
}

мне кажется, когда вы сделаете "красивым" свой код - проблема пропадет, т.к. ее причина именно (по моему мнению) в неаккуратности, что затрудняет поиск ошибки.
+1
Могу только добавить для борцунов за каждй такт и каждый байт — в примере кода выше функция send_byte объявлена static не зря. Компилятор теперь знает, что из других файлов она не вызывается, поэтому может подставить её тело по месту вызова («проинлайнить»), и не хранить рядом ещё одно тело этой функции на случай вызова снаружи. В результате размер и скорость будут таки же, как и для кода, вручную вписанного в тело цикла, но читаемость текста прораммы сильно увеличится, что, как уже говорилось, приводит к уменьшению числа ошибок и к ускорению поиска оставшихся.

Для компилятора, удволетворяющего станадрту C99 можно ещё «тонко намекнуть»

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

static inline void send_byte(unsigned char byte);
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
krysun
Открыл глаза
Сообщения: 41
Зарегистрирован: Вт окт 19, 2010 02:24:42
Откуда: Odessa

Re: КАРАУЛ... Массивы глючат ((

Сообщение krysun »

Проблема решилась. Ваши примеры и советы работают 100%. Это у меня лыжи не едут.
В mega162 в FUSE-ах было выставлено M161C=0 (режим совместимости с mega161 МК).
При вызове SPI("что-то") несколько раз (или любой другой функции вывода), зацикливался только 1-й вызов.
Потому и выводились на все индикаторы одинаковые цыфры.

Как FUSE снял, так сразу все и заработало.

Возьмите на заметку.

Спасибо большое за помощь! :beer:

Ах, да. С массива тоже все "ОК". (И все из-за того же FUSE-а)
Это лыжи не едут!!!
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»