Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Си указатель на таблицу
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Alhen
Все решено перехожу на Си!
Только вот незадача, первая же простенькая практическая задача
для AVR контроллера поставила в тупик.
Суть программы:
- в памяти программ размещается таблица или массив;
- берем по очереди байт из массива и выкидываем в коммуникационный порт.

Массив находится в пристегиваемом файле и я не понимаю как указать
какому либо поинтеру на начало таблицы.
На ассемблере все получается достаточно гармонично:
Код
    ldi zh,high(Transmit_Buff*2); Load Z-pointer
    ldi zl,low(Transmit_Buff*2); to the beginning of Receive_Buff

Transmit_Loop:

USART_Transmit:
; Wait for empty transmit buffer
    sbis UCSRA,UDRE
    rjmp USART_Transmit
; Put data  into buffer, sends the data
    lpm  Data_IN, Z+
    out UDR, Data_IN

        ldi  TempReg,high(end_of_file*2); Check if we got high end_of_file
        cp   TempReg,zh        ; Compare
        breq got_high_end_of_file; If equal then check the Low part
            rjmp go_further:

got_high_end_of_file:
        ldi  TempReg,low(end_of_file*2); Check if we got low end_of_file
        cp   TempReg,zl        ; Compare
        breq got_low_end_of_file; If equal then reload Z-pointer
            rjmp go_further:

got_low_end_of_file:
        ldi zh,high(Transmit_Buff*2); Load Z-pointer
        ldi zl,low(Transmit_Buff*2); to the beginning of Receive_Buff

go_further:
rjmp Transmit_Loop

Transmit_Buff:

.include "AIS_LOG.txt"

end_of_file:
nop

Реализация подбной программы на Си AVR для меня загадка.
Тем более что я нашел подходящую конструкцию на VisualDSP,
Код
complex_fract16 in[VEC_SIZE] =
{
    #include "in.dat"
};

но в CVAVR такое не проходит!!!
beer_warrior
Код
struct {
        volatile    BYTE    mode;
        volatile    WORD    timeout;
        volatile    BYTE    errc;
        
        volatile    WORD    tx_cnt;
        volatile    WORD    tx_len;
        BYTE*tx_buf;
        
        volatile    WORD    rx_cnt;
        volatile    WORD    rx_len;
        BYTE*                rx_buf;
        } UCB;

//RS485 direction
#define    DIR_BIT        2
#define DIR_TX        PORTD |= (1<<DIR_BIT)
#define DIR_RX        PORTD &= ~(1<<DIR_BIT)
//--------------------------------------------------------------------------
//UART modes
#define    TX_BUSY        0
#define    RX_BUSY        1
#define    RX_READY    2

//--------------------------------------------------------------------------
SIGNAL(SIG_USART_TRANS)
{
if(UCB.tx_cnt < UCB.tx_len)
    {
    UDR0 = UCB.tx_buf[UCB.tx_cnt++];
    }
else
    {
    UCB.tx_cnt = 0;
    CLR_TX_BUSY;
    _NOP();
    _NOP();
    _NOP();
    DIR_RX;
    }
}
//--------------------------------------------------------------------------
BYTE TxStart(WORD len)
{
if(UCB.mode & TX_BUSY) return 1;
DIR_TX;
_NOP();
_NOP();
_NOP();
UCB.tx_cnt  = 0;
UCB.tx_len  = len;
SET_TX_BUSY;
SIG_USART_TRANS();
return 0;
}
//--------------------------------------------------------------------------

Структура UCB содержит связанные с УАРТом переменные
присутствует кое-что лишнее для RS485, можно выкинуть.
Указатель UCB.tx_buf указывает на массив для отправки.
Old1
Цитата(Alhen @ Feb 2 2006, 22:19) *
Массив находится в пристегиваемом файле и я не понимаю как указать
какому либо поинтеру на начало таблицы.


Код
__flash unsigned char TABL[10]={1,2,3,4,5,6,7,8,9,10};//определение таблицы во flash


запись в указатель адреса начала таблицы:
Код
unsigned char __flash *PTR;//определение указателя на flash
//.........
PTR=TABL;//запись в указатель начального адреса таблицы

Да, я работаю с ИАРом, возможно в CVAVR указатель на массив и сам массив во flash описывается немного подругому, но обращение к нему и к массиву делается также...
Alhen
Цитата
__flash unsigned char TABL[10]={1,2,3,4,5,6,7,8,9,10};//определение таблицы во flash


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

#include "tabl.dat";

вот теперь как определить его в виде TABL[length_of_table] ?
или определить начальный адрес размещения данных, а потом передать это значение указателю?
vet
Цитата(Alhen @ Feb 3 2006, 07:52) *
Цитата

__flash unsigned char TABL[10]={1,2,3,4,5,6,7,8,9,10};//определение таблицы во flash


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

#include "tabl.dat";

вот теперь как определить его в виде TABL[length_of_table] ?
или определить начальный адрес размещения данных, а потом передать это значение указателю?

Вам поможет программа bin2asc. На входе она получает бинарник, на выходе - выдаёт текстовый файл со списком байтов, который можно вставлять в исходники.
Old1
Цитата(Alhen @ Feb 3 2006, 08:52) *
Не могу я набирать массив ручками, там пару тысяч байт, поэтому храню его в отдельном
файле в текстовом формате и должен пристегнуть его.

По подробнее плиз, что из себя файл с массивом представляет, и как вы его создаете?
Кстати, я в таких случаях тоже не набираю ручками. Файл (с определением массива) генерю при помощи простенькой проги написанной на DELPHI (каждый раз пишу под задачу, делать универсальную лень), там (и не только там) это делается элементарно...
BVU
Таблицу всегда можно представить массивом, либо структурой. В 'C' всегда адрес массива он же адрес первого элемента массива может быть представлен указателем.
int buff[100];
int *f;
f = buff; или f = &buff[0];
Nixon
Я делал вот так:

в файле "data.txt" :
Код
#define MACROS1 { 1, 2, 3, 4, ... остальные данные  }


в основном файле
Код
...
#include "data.txt"
...
const VARIABLE1 char [SIZE] = MACROS1
AndyBig
А еще в IAR можно пристегнуть любой файл как бинарный массив, назначив его указателю с указанным именем. Это в опциях линкера, если не ошибаюсь.
k0t
Проще и удобнее всего подключение файла делать так:
__hugeflash unsigned char file[]={#include "file.c"};

file.c сделать из бинарника с помощью bin2asc smile.gif

Размер массива определяется так (если он меняется, иначе можно константу забить):
file_length=sizeof(file)/sizeof(unsigned char);
Old1
Цитата(k0t @ Feb 3 2006, 17:19) *
Проще и удобнее всего подключение файла делать так:
__hugeflash unsigned char file[]={#include "file.c"};

В каком компиляторе такое проходит? Попробовал в ИАРе для AVR 4.11, ругается:
Error[Pe010]: "#" not expected here ...
Error[Pe029]: expected an expression ...
vet
Цитата(Old1 @ Feb 3 2006, 21:46) *
Цитата(k0t @ Feb 3 2006, 17:19) *

Проще и удобнее всего подключение файла делать так:
__hugeflash unsigned char file[]={#include "file.c"};

В каком компиляторе такое проходит? Попробовал в ИАРе для AVR 4.11, ругается:
Error[Pe010]: "#" not expected here ...
Error[Pe029]: expected an expression ...

Команды препроцессора всегда пишутся в отдельной строке.
Alhen
2Nixon
Попробывал я обыграть макрос и в CodeVision прошел следующий вариант:
Код
#include "my_table.txt"
flash unsigned char my_array[] = in_table;


Включаемый файл при этом выглядел так:
Код
#define in_table {\
0x01, 0x02,\
0x03, 0x04 \
....
};\


Что еще приятно, работает sizeof
Код
a = sizeof(my_array);


2kOt
Вариант типа
Код
flash unsigned char my_array[]={#include "my_table.txt"};


в Code Vision не проходит?! Хотя все логично, тем более что в VDSP++ есть
подобная конструкция

2 Old1 & vet
По поводу конвертации бинарного файла я уже поднимал тему на форуме.
И программа BIN2ASC.exe показалась сперва чрезвычайно полезной, тем не менее мне пришлось
написать свою на Паскале, потому что я тогда работал на Ассемблере под AVR Studio
и программа не принимала сгенерированный ascii файл, по следующим причинам:
- она глючила на десятичные числа с нулями впереди, например 040 воспринимая их за операторы
- не понимала шестнадцатеричный формат без 0x - префикса (естественно)
- не признавала директиву db без точки впереди
- и к тому же, AVR Studio ругается на нечетное количество операндов в строке (наверное из-за
16 разрядной структуры памяти программ)

Код
.db 183, 001, 137, 255, 255, 134, 254, 255, 133, 255, 255, 255, 243, 041, 255,


а их то 11 то 15 штук в строке.
Любой после этого кинется писать свой конвертор.

2AndyBig и всем
Уже вижу что Си компиляторы все разные, может мне не стоит заморачиваться с Code Vision
, а сразу работать в IAR и т.п., что посоветуете.
Я то стартанул по известному курсу AVR123 http://electronix.ru/redirect.php?http://[banned]/. И могу сказать что Image Craft мне не нравится.
Он не генерит ассемблер, а самое главное ИМХО у него ограниченный Си.
k0t
Цитата(Old1 @ Feb 3 2006, 21:46) *
Цитата(k0t @ Feb 3 2006, 17:19) *

Проще и удобнее всего подключение файла делать так:
__hugeflash unsigned char file[]={#include "file.c"};

В каком компиляторе такое проходит? Попробовал в ИАРе для AVR 4.11, ругается:
Error[Pe010]: "#" not expected here ...
Error[Pe029]: expected an expression ...


Так ругаться не будет:

__hugeflash unsigned char file[]={
#include "file.c"
};
vet
Цитата(Alhen @ Feb 4 2006, 09:00) *
Уже вижу что Си компиляторы все разные, может мне не стоит заморачиваться с Code Vision
, а сразу работать в IAR и т.п., что посоветуете.
Я то стартанул по известному курсу AVR123 http://electronix.ru/redirect.php?http://[banned]/. И могу сказать что Image Craft мне не нравится.
Он не генерит ассемблер, а самое главное ИМХО у него ограниченный Си.


К IAR, пожалуй, слово "заморачиваться" подходит куда как точнее, чем к CV smile.gif
Собственно, мне CodeVision нравится именно своей простотой и удобством. Плюс полезные библиотеки в составе дистрибутива.
Насчёт ImageCraft соглашусь.
Old1
2 k0t & vet
Спасибо, но, я уже сам понял, что
Цитата
Команды препроцессора всегда пишутся в отдельной строке.

2 All
Кстати, если такая конструкция работает
Цитата
_hugeflash unsigned char file[]={
#include "file.c"
};
Значит элементы таблицы в текстовом файле скорее всего идут через запятую, но тогда не проще ли было бы в любом текстовом редакторе вручную модифицировать содержимое файла следующим образом:
Код
_hugeflash unsigned char file[]={
...//содержимое файла
}
и включить таблицу в проект, используя директиву #include?
k0t
Это-ж в РУЧНУЮ делать прийдется. А прог, которые из бинарника сгенерят файл с разделителями (запятыми) довльно много. Халява, сэр! smile.gif
Old1
Цитата(k0t @ Feb 6 2006, 09:55) *
Это-ж в РУЧНУЮ делать прийдется. А прог, которые из бинарника сгенерят файл с разделителями (запятыми) довльно много. Халява, сэр! smile.gif

Я предлагал не запячтые вручную ставить (у автора темы как я понял они уже стояли), а вручную прописать в файл определение массива...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.