Страница 1 из 1
КАРАУЛ... Массивы глючат (Решено)
Добавлено: Сб ноя 06, 2010 01:18:26
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 массива по указанному переменной индексу.
Как быть?
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Сб ноя 06, 2010 03:51:27
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 типа. Один фиг туда число записывается.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Сб ноя 06, 2010 08:13:04
lix
Всегда девятку выводит? _delay_ms надо в цикл по j поместить.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Сб ноя 06, 2010 08:17:40
lix
а еще тип значение массива digits лучше сделать unsigned char для экономии флеш и добавить FLASH чтобы этот массив не занимал место в оперативке.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 01:52:18
krysun
lix писал(а):Всегда девятку выводит? _delay_ms надо в цикл по j поместить.
Да нет, не всегда... Всегда разные числа (рандомные в том числе). Вопрос в чтении массива по индексу...
Примерчики почитал, сейчас запустю свою махину, проверю)
Спасибо.
ЗЫ: С делеем правы.... Кроме девятки предыдущих просто не увижу) Но... Как говорится, наступил бы еще и на эти грабли)
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 02:21:03
krysun
Ничего не вышло.....
Кстати, на объявление переменной непосредственно в цикле
пишет следующее:
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'Благим матом, короче

Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 02:44:59
krysun
И вроде бы все правильно.
И код должен работать, и объявление, в принципе, нормальное.
А нет же.... Не пашет.
Не читает он индекс как цифру.... Не хочет выводить биты.
Паника.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 09:57:55
DrWatson
Куда данные-то выводятся (регистр сдвига? какой? TICxx? какой?) далее к каким пинам что подключено (DI - PINB.5, CLK - PINB.7, OE - PINB.0 - что за OE, как в даташите описан? где LD (LOAD и т.п.))?
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 10:19:40
van_de_luxe
лучше объяви как volatile unsigned char
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 10:27:05
avreal
DX168B писал(а):И не обязательно, чтобы они были char типа. Один фиг туда число записывается.
Я даже более жёстко выражусь — «лучше, чтобы они были
не char, поскольку туда
число записывается».
В зависимости от контроллера/компилятора char может оказаться как знаковым, так и беззнаковым, поэтому если нужен просто «короткий» счётчик или там переменная для хранения малых чисел, то ндо явно указать знаковость —
unsigned char или
signed char.
Для упрощения раньше просто писались для себя typedef-ы
Код: Выделить всё
typedef unsigned char uchar;
typedef signed char schar;
По нынешним временам для унификации стоит применять стандартизованные начиная с C99 типы фиксированного размера.
Даже если компилятор не соответствует стандарту С99, стоит написать свои typedef-ы для этих стандартизованных типов.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 19:28:54
DX168B
Ставь AVR Studio 4 и WinAVR. Там хоть таких багов с обьявлениями переменных нет.
На конструкцию, типа for (int i = 0; i < 10; i++) компилятор у меня не ругается.
Но ругается на такое: PORB.3 = 1;
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 20:26:43
Murav
DX168B писал(а):На конструкцию, типа for (int i = 0; i < 10; i++) компилятор у меня не ругается.
Такие конструкции появились только в стандарте C99(ну и в C++ откуда собственно они и пришли), который очень многие копиляторы не поддерживают. А GCC - поддерживает.
DX168B писал(а):Но ругается на такое: PORB.3 = 1;
А это - расширение языка, которое добавлено в некоторых компиляторах. Например в CVAVR.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Вс ноя 07, 2010 23:02:10
avreal
Если бы ещё кое-что приятное из С99 в С++ пришло, было бы вообще хорошо.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Пн ноя 08, 2010 01:01:51
krysun
Хм, за ответы спасибо!
Значит, стоит забросить CVAVR и переходить на WinAVR?
Ну да ладно. Но интересует вопрос: "Как???" же все-таки объявить массив и обратится к нему по "small_counter" индексу (в подцикле for цикла for, сори за каламбур), что-бы прочитать данные?
На вопрос КУДА, и ЧЕРЕЗ ЧТО я вывожу, скажу:
mega162 -> HC244n -> HC4094 -> 3-и 7SEG индикатора.
Я поднимал тему по иному вопросу этого же девайса....
В итоге тоже ничего не вышло. 4094 подключен к mega162 по SPI.
Выводить получается, но как-то все "раком".
При:
на все три индикатора выводятся эти "семерки".
Вот темка:
http://forum.radiokot.ru/viewtopic.php?f=20&t=36422Можете ознакомится.
ps: Толкать биты по одному и таким образом зажигать нужные цыфры "без проблемм".
Использовать же SPI, или хотя-бы массив с маской - кукиш.
Вот и ломаю голову.
А дальше еще и со звуком разбиратся ((
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Пн ноя 08, 2010 09:14:46
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
}
мне кажется, когда вы сделаете "красивым" свой код - проблема пропадет, т.к. ее причина именно (по моему мнению) в неаккуратности, что затрудняет поиск ошибки.
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Пн ноя 08, 2010 09:31:06
krysun
Спасибо, чудненькие советы.
Просто кроме CVAVR ничем не пользовался....
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Пн ноя 08, 2010 11:51:56
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);
Re: КАРАУЛ... Массивы глючат ((
Добавлено: Сб ноя 13, 2010 23:35:54
krysun
Проблема решилась. Ваши примеры и советы работают 100%. Это у меня лыжи не едут.
В mega162 в FUSE-ах было выставлено M161C=0 (режим совместимости с mega161 МК).
При вызове SPI("что-то") несколько раз (или любой другой функции вывода), зацикливался только 1-й вызов.
Потому и выводились на все индикаторы одинаковые цыфры.
Как FUSE снял, так сразу все и заработало.
Возьмите на заметку.
Спасибо большое за помощь!
Ах, да. С массива тоже все "ОК". (И все из-за того же FUSE-а)