Страница 64 из 628

Добавлено: Ср сен 09, 2009 19:46:54
smac
Marsyk писал(а):Здравствуйте может кто знает, вообще какие есть программы кроме вот этих: PonyProg2000, ProgCode, IC-Prog 1.06.
Если речь об AVR, то есть еще AVReal, на мой взгляд один из лучших программаторов для AVR.

Добавлено: Ср сен 09, 2009 20:33:27
ARV
последнее время запал на avrdude, который в комплекте с WinAVR идет - мощная штука! настроить можно на что угодно, на любую схемку!

Добавлено: Пт сен 11, 2009 23:17:38
Vergilium
Здраствуйте. Подскажите пожалуйста как мне сдвинуть в лево двумерный масив. Вот так вот не совсем коректно работает.

x = str[0][0];
for (i=0;i<=7;i++)
{
for (j=0;j<4;j++)
{
str[j]=str[j+1];
}
str[j]=str[i+1][0];
}
str[7][4]=x;

Может както по иному можно это сделать.


ЗЫ программа на WinAVR для ATmega16.

Добавлено: Сб сен 12, 2009 00:10:43
Synergetik
Vergilium писал(а):Здраствуйте. Подскажите пожалуйста как мне сдвинуть в лево двумерный масив. Вот так вот не совсем коректно работает.
А вот так не лучше?

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

for (i=0;i<=7;i++)
  {
    x=str[i][0];   //Запоминаем нулевой элемент каждой i-ой строки

    for (j=0;j<4;j++)
      {
        str[i][j]=str[i][j+1]; //Доходим до предпоследнего элемента
      }

    str[i][j]=x; //Последнему присваиваем значение нулевого
}

Добавлено: Сб сен 12, 2009 00:31:48
Yellow Tiger

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

#define ROWS    4
#define COLS    7
int     i, tmp, *iptr, array[ROWS][COLS];

        iptr = (int *)array;
        tmp = *iptr;
        for (i=0; i<ROWS*COLS-1; ++i)
                iptr[i] = iptr[i+1];
        iptr[i] = tmp;
Из вот этого (взял массив 4х4):

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

1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16
сделает вот это:

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

2, 3, 4, 5
6, 7, 8, 9
10, 11, 12, 13
14, 15, 16, 1

Добавлено: Сб сен 12, 2009 00:44:57
Vergilium
А вот так не лучше? Код:
for (i=0;i<=7;i++)
{
x=str[0]; //Запоминаем нулевой элемент каждой i-ой строки

for (j=0;j<4;j++)
{
str[j]=str[j+1]; //Доходим до предпоследнего элемента
}

str[j]=x; //Последнему присваиваем значение нулевого
}


В таком случае сдвигатся будут части массива по отдельности, а мне нужно чтоб элемент str[0][0] стал последним элементом всего массива, а не последним первой части(str[0][4]).

Мой алгоритм в принцыпе работает только есть один косяк. Обьяснять долго вот лучше раз увидеть.

Добавлено: Сб сен 12, 2009 01:11:40
Yellow Tiger
Vergilium писал(а):...мне нужно чтоб элемент str[0][0] стал последним элементом всего массива, ...
Повторить решение ещё раз? Изображение

Добавлено: Сб сен 12, 2009 01:16:46
Vergilium
Повторить решение ещё раз?
Нет, ваш пример работает так же как и мой но более компактней так что буду использовать его, ну теперь я не могу понять в чем косяк с индикацией на 1й матрице.

Добавлено: Сб сен 12, 2009 01:25:21
Yellow Tiger
Vergilium писал(а):ваш пример работает ... более компактней ...
Ага, и быстрее.

Добавлено: Сб сен 12, 2009 01:36:57
Vergilium
Ага, и быстрее.
Согласен. Просто я никак не могу понять указатели, нет что это такое я знаю ну вот использовать не могу. :cry:

Добавлено: Сб сен 12, 2009 11:07:26
Synergetik
Vergilium писал(а):В таком случае сдвигатся будут части массива по отдельности, а мне нужно чтоб элемент str[0][0] стал последним элементом всего массива, а не последним первой части(str[0][4]).

Мой алгоритм в принцыпе работает только есть один косяк. Обьяснять долго вот лучше раз увидеть.
Извините, неверно понял задачу. Просто для меня сдвиг двумерного массива влево - первый столбец становится нулевым, второй - первым, нулевой - последним.

Хотя уже по строкам:

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

x = str[0][0];
...
str[7][4]=x; 
Должен был сообразить. Но увы, только со второго раза.

В вашей программе в строчке str[j]=str[i+1][0]; происходит переполнение по строке, когда вычисляем str[i+1][0], а там может находится что угодно, так как эта ячейка не принадлежит массиву. В этом случае нужно делать проверку:

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

if(i<7)                //Пока не достигли самой последний строки
    str[i][j]=str[i+1][0]; //Последний элемент каждой i-й строки
  else               //Достигли самого последнего элемента, так как
    str[i][j]=x;   //и по i, и по j максимум (7 и 4)
Тогда самую последнюю строку str[7][4]=x; можно исключить.

По идее, ваша программа должна правильно работать, за исключением последнего элемента, которому должно присваиваться чёрт те знает что.

Добавлено: Сб сен 12, 2009 13:23:06
Yellow Tiger
Vergilium писал(а):...никак не могу понять указатели, нет что это такое я знаю ну вот использовать не могу. :cry:
Ничего магического, нужно только немного "поработать компилятором"... Итак, предположим программист помещает в тексте программы объявления переменных:

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

int     i;
int     tmp;
char    *s = "Temp= xxx°C";
int     j;
компилятор отводит в сегменте данных место под хранение этих переменных(*):

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

        .DATA
0x0000        dw  ?   ;int     i;
0x0002        dw  ?   ;int     tmp;
0x0004        db  'Temp= xxx°C',0 ;char *s=...;
0x0010        dw  ?   ;int     j;
Далее программист хочет написать код, который вписывает текущее значение температуры в заготовленное в строке место (" = xxx") - как? В приведенном примере просто - достаточно вписать три символа в s[6], s[7], и s[8]. А что, если строк будет несколько разных, а процедура - одинаковая для всех? Писать под каждый случай свой код? Неразумно... вот тут-то и нужны указатели. Если функция одна на все строки, то ей необходимо каким-то образом сообщить, где в сегменте данных расположена нужная строка; но каким образом(?), ведь нам неизвестно, что адреса переменных в сегменте данных - 0h, 2h, 4h и 10h - это знает только компилятор...
В языке Си можно завести переменную с типом "указатель на символьный тип", затем присвоить этой переменной адрес нужной строки и передать эту переменную функции (или коду), которая (который) обрабатывает строку. Для случая работы с самой строкой, инструкции ассемблера имели бы такой вид (если в температуру пишется строка '020'):

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

put_3chr:
		lds	si,strOff		    ; DS:SI points to static string
		mov	[si+6],'0'			; put 1st char to string
		mov	[si+7],'2'			; put 2nd char to string
		mov	[si+8],'0'			; put 3rd char to string
а для двух строк, обрабатываемых через указатели char *strptr1 и char *strptr2, такой:

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

use_ptr_twice:
		mov	si,strptr1		   ; DS:SI points to string 1
		mov	[si+6],'0'			; put 1st char to string
		mov	[si+7],'2'			; put 2nd char to string
		mov	[si+8],'0'			; put 3rd char to string
		mov	si,strptr2		   ; DS:SI points to string 2
		mov	[si+6],'0'			; put 1st char to string
		mov	[si+7],'2'			; put 2nd char to string
		mov	[si+8],'0'			; put 3rd char to string
Остается только напомнить две вещи:
1. Для правильного подсчета адресов относительно указателя, компилятор должен знать тип данных на которые он указывает, так как для char смещение указателя на следующий элемент означает увеличение адреса на 1, а для int - уже на 2 (для любого типа данных - на sizeof(тип_данных)).
2. Все массивы располагаются в памяти сплошными блоками и упорядоченно (младшие индексы пишутся последними), то есть, в массиве array[4][7] элемент array[1][0] следует сразу за array[0][6], а раз так, то ко всем элементам можно обратиться как к одномерному массиву, лишь применив другой указатель.
Несколько раз влезь в шкуру компилятора и работа с указателями наладится. :)))
Удачи!

(*) Ассемблер не какой-то конкретный - условный. :wink:

Добавлено: Сб сен 12, 2009 14:03:27
Vergilium
Yellow Tiger
Спасибо за обьяснения, теперь у меня более ясная картина на счет указателей. Буду пробывать на примерах. Но я никак не могу решить проблему того что в моей бегущей строке при сдвиге символы проходят первую матрицу дважды. Может в схеме косяк? Хотя врятли, скорее всего в коде или протеус бочит. Ладно буду искать проблему с помощью дебагера.

Добавлено: Сб сен 12, 2009 14:12:13
Synergetik
Раз уж зашёл разговор о двумерном массиве, не могу не спросить, на самом деле
Yellow Tiger писал(а):все массивы располагаются в памяти сплошными блоками и упорядоченно (младшие индексы пишутся последними),... а раз так, то ко всем элементам можно обратиться как к одномерному массиву, лишь применив другой указатель.
? А если массив не просто большой, а очень большой, а оперативки впритык, да она ещё и фрагментирована, но суммы фрагментов хватит, чтобы разместить массив по частям, то массив не будет размещён, так как нельзя его разместить как непрерывное целое?

Или смысл в том, что компилятор сам обрабатывает такие, запросы, как например, для одномерного массива:

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

int mass[10];
int *m=&mass[0];
for (int i=0; i<10; i++)
  temp=m[i];
(для одномерного массива получилось коряво, так как создали указатель-дублёр указателя массива, а можно было сразу использовать имя массива как указатель на нулевой элемент)

То есть увеличивая указатель на единицу (оператор m=*(m+sizeof(int)*i) ) компилятор сам перемещает указатель на то место, где находится следующий элемент, а не следующая ячейка в оперативке?

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

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

iptr = &array[0][0];
tmp = *iptr;
for (i=0; i<ROWS*COLS-1; ++i)
  iptr[i] = iptr[i+1];
iptr[i] = tmp;
? Кстати, не совсем понял вот эту операцию:

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

iptr = (int *)array;
Yellow Tiger, буду очень благодарен, если объясните принцип работы этой строки.


Vergilium писал(а):Но я никак не могу решить проблему того что в моей бегущей строке при сдвиге символы проходят первую матрицу дважды. Может в схеме косяк?
Vergilium, вот это

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

if(i<7)                //Пока не достигли самой последний строки
    str[i][j]=str[i+1][0]; //Последний элемент каждой i-й строки
  else               //Достигли самого последнего элемента, так как
    str[i][j]=x;   //и по i, и по j максимум (7 и 4)
не помогло?

Добавлено: Сб сен 12, 2009 14:19:22
Vergilium
Уррааа! Нашел косяк. Дело в том что в 4х матрицах 8х8 всего 32 столбика, а массив у меня был 7*5=35 столбиков поэтому после 32 столбиков происходит возврат и цикл повторяется далее т.е. еще 3 столбика с начала строки, потому и смешивались символы.

Да и еще хотел спросить как можно опредилять размер массива? Например если через UART данные сохранить в массиве, а потом в цикле выводить то мне нужно знать сколько символов было передано т.е. размер массива. Есть ли какаеть ф-ция которая это определяет? Заранее благодарен.

Добавлено: Сб сен 12, 2009 15:47:40
Yellow Tiger
Vergilium писал(а):...как можно опредилять размер массива? ... Есть ли какаеть ф-ция которая это определяет?
Есть. Если нужно определить размер памяти, отведенной под массив, то так:

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

int     array[7][5], arr_size;
        arr_size = sizeof(array);
а если количество элементов в массиве, то так:

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

int     array[7][5], arr_len;
        arr_len = sizeof(array) / sizeof(array[0][0]);
Synergetik писал(а):1. А если ... оперативки впритык, да она ещё и фрагментирована
2. То есть увеличивая указатель на единицу ... компилятор сам перемещает указатель на то место, где находится следующий элемент, а не следующая ячейка в оперативке?
3. ...с точки зрения юзера и тот и другой вариант практически неразличимы
Я ведь всё это уже описал выше. Во всяком случае я написал всё, что можно было написать за то время, которым я располагал - стремился дать основу. Остальное будет правильнее изучить самостоятельно, вооружившись хорошей книгой, компилятором (хорошо бы, чтобы он выдавал ассемблерный листинг) и терпением. Вот если в книге попадутся непреодолимые места, тогда нужно звать на помощь "зал". :)
Synergetik писал(а):...буду очень благодарен, если объясните принцип работы этой строки
"Принцип" прост - адрес начала массива помещается в указатель, а чтобы компилятор понимал, как работать с этим указателем, приходится насильно приводить тип данных из двумерного массива в одномерный (ведь дальнейшая работа с данными будет вестись именно как с одномерным массивом).

P.S. Я бы рекомендовал вам обоим отнестись к моим словам "поработай компилятором" не как к шутке, а как к директиве. Все характеристики всех языков - есть следствие тех или иных решений задач, возникающих перед компиляторами с этих языков.

Добавлено: Сб сен 12, 2009 16:35:40
Vergilium
Большое спасибо всем. Я только начинающий и еще много чему нужно научится.

МК ST7, вопросы

Добавлено: Вс сен 13, 2009 09:46:54
Igor_67
Здравствуйте, уважаемые!
Имеется несколько штук МК от STMicroelectronix семейства ST7. Как с ними работать? С программированием более-менее разобрался, а вот прошивать их чем? Может кто-нибудь посоветовать схему простого программатора для этого типа МК?
И хотелось бы еще какой нибудь рускоязычный ресурс про них, желательно с примерами.
Спасибо за внимание!

Добавлено: Вс сен 13, 2009 13:16:18
Vergilium
Здраствуйте. Вот я и опять стыкнулся с очередной проблемой, а собственно с премом строки по USART. Покопавшись в интернете нашел много вариантов на эту тему но не могу все сложить в кучу и чтоб работало.
Значить вот в чем задача: Принять данные по USART и сохранить в массиве, в принцыпе все пока. Вот что я накалякал.

И собственно присвоение принятого бита массиву. Происходит это в прерывании по окончению приема бита. А далее в основной программе происходит иницыализация УСАРТа и вывод строки на LED матрицу. Все компилется но не фига не работает. Может по прерыванию чтото не так? Или иницыализация не так? Вобщем помогите пожалуйста неопытному.

ЗЫ МК атмега16, среда ВинАВР.

Добавлено: Вс сен 13, 2009 13:52:38
Yellow Tiger
Вот тут обсуждался аналогичный вопрос.