WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение BCluster »

Мастер Ломастер писал(а): определить в программе указатель, присвоить ему нужный адрес, и работать с ним, как с указателем (т.е. адресом) вашей переменной - в этом случае все значительно проще, имхо.

Думал об этом варианте, а не подскажете как сделать указатель на EEPROM? Для общего развития пригодится :)
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Мастер Ломастер »

в WinAVR нет специального типа указателя для работы с EEPROM, просто объявите указатель и все.
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
shurikss123
Грызет канифоль
Сообщения: 271
Зарегистрирован: Пн окт 25, 2010 20:47:04
Откуда: Казахстан, Астана

Re: WinAvr в вопросах и ответах

Сообщение shurikss123 »

Мастер Ломастер писал(а):в WinAVR нет специального типа указателя для работы с EEPROM, просто объявите указатель и все.

а вот как объявить указатель, не силен в языках программирования.
Изображение
Мастер на все руки, кручу, кручу, кручу и матерюсь
Повелитель паяльной станции, лома, и пинцета!!!
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение BCluster »

Дык, а как компилятор узнает что мы хотим указать на еепром?)
Просто указатель если объявить и присвоить ему какое-то значение он будет указывать на ОЗУ, как я понимаю
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Мастер Ломастер »

BCluster писал(а):Дык, а как компилятор узнает что мы хотим указать на еепром?)
Просто указатель если объявить и присвоить ему какое-то значение он будет указывать на ОЗУ, как я понимаю

с EEPROM вы должны работать при помощи функций типа eeprom_read_byte() или eeprom_write_byte() (посмотрите в документации - есть много функций для работы с байтами, словами, блоками и т.п.). все эти функции в качестве параметра получают указатель, который внутри себя трактуют как указатель в EEPROM. в вашей программе это просто указатель.
shurikss123 писал(а):
Мастер Ломастер писал(а):в WinAVR нет специального типа указателя для работы с EEPROM, просто объявите указатель и все.

а вот как объявить указатель, не силен в языках программирования.

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

unsigned char *pchar; // указатель на байт без знака
int *pint; // указатель на int

pchar = (void*)12; // указатель будет указывать на 12-ю ячейку памяти
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение BCluster »

Спасибо, я не знал об этих функциях. Я на кодвижне писал для авр, черт бы его подрал )
Ну в таком случае можно вообще передавать в параметре этих функций адрес непосредственно - захотел 20 ячейку прочесть - передал eeprom_read_byte(20);
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Мастер Ломастер »

BCluster писал(а):Ну в таком случае можно вообще передавать в параметре этих функций адрес непосредственно - захотел 20 ячейку прочесть - передал eeprom_read_byte(20);
но лучше делать чуть иначе

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

eeprom_read_byte((void*)20);
иначе компилятор будет возмущаться
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение BCluster »

Мастер Ломастер писал(а):иначе компилятор будет возмущаться

Да, я просто не знаю специфики компилятора, наверняка будет вонинг
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: WinAvr в вопросах и ответах

Сообщение codenamehawk »

BCluster писал(а):
Мастер Ломастер писал(а): определить в программе указатель, присвоить ему нужный адрес, и работать с ним, как с указателем (т.е. адресом) вашей переменной - в этом случае все значительно проще, имхо.

Думал об этом варианте, а не подскажете как сделать указатель на EEPROM? Для общего развития пригодится :)


Пример для работы с еепром.
Применена структура для удобства работы с еепром, при старте, считываем значения из еепром в переменную в памяти и далее с нею работаем.
Запись производим по необходимости, например перед выключением проца.

Объявляем структуру и переменные.

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

struct term                                              // structura dla termometra 0
{
    int16_t term_on;
    int16_t term_off;
};

EEMEM   struct term       t_0_rom;                               // structura dla termometra w ROM
        struct term       t_0_ram;                               // structura dla termometra w RAM

Запись выглядит так

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

eeprom_write_block(&t_0_ram,&t_0_rom,sizeof(t_0_ram)); 

// запись блока данных, данные для записи располагаются по адресу &t_0_ram ,
// &t_0_rom указывает место в еепром, куда будут писаться данные
// sizeof(t_0_ram) высчитываем длину блока данных

&t_0_rom это и будет указатель на переменную в еепром. (На самом деле указываем адрес переменной в еепром)

Прочитать записанное

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

eeprom_read_block(&t_0_ram, &t_0_rom, sizeof(t_0_ram)); 
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

Re: WinAvr в вопросах и ответах

Сообщение TICLIR »

Доброе время суток. Нужен совет,есть функция вот отрывок
void kkoll( char oche);{
switch(oche){
case 1: if(!(knop2)){
temp1_min=temp1; //
zap_bu5(60,6,slow7); //
} break;
case 2: if(!(knop2)){
temp2_min=temp2; //
zap_bu5(60,7,slow7);
}
zap_bu5(60,6,slow12); //
дело в том компилятор не позволяет или не считает нужным заходить программе в эту
функцию пока не изменится переменная "oche",а мне надо что бы она заходила постоянно
ведь там она опрашивает кнопки. Вот как бы мне заставить компилятор что бы он позволил
программе заходить постаянно в эту функцию.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Мастер Ломастер »

ничего не понятно - дайте весь код.
битва с дураками проиграна, победители торжествуют. слава победителям!
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

Re: WinAvr в вопросах и ответах

Сообщение TICLIR »

Да я не о программе, я в целом. Вот если,в объявление переменной поставить "volatule" то компилятору
это говорит что переменная может измениться в любой момент, а я хочу узнать если для функций
какие нибудь квалификаторы.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Мастер Ломастер »

TICLIR писал(а):Да я не о программе, я в целом. Вот если,в объявление переменной поставить "volatule" то компилятору
это говорит что переменная может измениться в любой момент, а я хочу узнать если для функций
какие нибудь квалификаторы.

функция может игнорироваться компилятором-оптимизатором только в том случае, если она не меняет ничего в программе. в частности, если она меняет переменные, которые должны быть volatile? но не являются таковыми - компилятор может счесть, что функция лишняя. особых квалификаторов для функций не существует.
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение vitalik_1984 »

codenamehawk писал(а):,а мне надо что бы она заходила постоянно
так вызывайте ее когда нужно сделать опрос кнопок!

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

void kkoll( char oche);{
тут не нужно точки с запятой,если вы хотите,чтоб это была функция.если это функция,то нужно передать параметр oche при вызове функции

Мастер Ломастер писал(а):которые должны быть volatile? но не являются таковыми - компилятор может счесть, что функция лишняя.

Он даже когда переменная не используется предупреждает.Говорит, что переменная объявлена, но не используется.Думаете для функции не так?
В поисках истины человек развивается.
Аватара пользователя
Dako
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Сб июл 30, 2011 05:35:35

Re: WinAvr в вопросах и ответах

Сообщение Dako »

Здравствуйте! Вновь обращаюсь к вам за помощью. Пробую собрать термометр на 2-х семисегментных индикаторах, Меге8 и DS18B20. Шаг за шагом методом проб и ошибок добился отображения на индикаторе нужных цифр. Повесил датчик. И вот уткнулся в очередной тупняк, при компиляции пишет "128: error: expected declaration or statement at end of input", курсор указывает на последнюю строку программы, там где скобка закрывает тело основной программы.

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>

#define W1_PORT PORTD
#define W1_DDR DDRD
#define W1_PIN PIND
#define W1_BIT 0

volatile int i = 0 ;
volatile int digit1 ;
volatile int digit2 ;

ISR(SIG_OVERFLOW0)
{

if (i==2) i=0 ;

switch(i)
{
case 0:PORTB = digit2;PORTB |= (0<<5);PORTB |= (1<<6);break;
case 1:PORTB = digit1;PORTB |= (1<<5);PORTB |= (0<<6);break;
}

i++ ;
}

//функция определяет есть ли устройство на шине
unsigned char w1_find()
{
unsigned char device ;
W1_DDR |= 1<<W1_BIT ;//логический "0"
_delay_us(485) ;//ждем минимум 480мкс
W1_DDR &= ~(1<<W1_BIT) ;//отпускаем шину
_delay_us(65) ;//ждем минимум 60мкс и смотрим что на шине

if((W1_PIN & (1<<W1_BIT)) ==0x00)
device = 1 ;
else
device = 0 ;
_delay_us(420) ;//ждем оставшееся время до 480мкс
return device ;
}

//функция посылает команду на устройство 1-wire
void w1_sendcmd(unsigned char cmd)
{
for(unsigned char i = 0; i < 8; i++) //в цикле посылаем побитно
{
if((cmd & (1<<i)) == 1<<i) //если бит=1 посылаем 1
{
W1_DDR |= 1<<W1_BIT ;
_delay_us(2) ;
W1_DDR &= ~(1<<W1_BIT) ;
_delay_us(65) ;
}
else //иначе посылаем 0
{

W1_DDR |= 1<<W1_BIT ;
_delay_us(65) ;
W1_DDR &= ~(1<<W1_BIT) ;
_delay_us(5) ;
}
}
}

//функция читает один байт с устройства 1-wire
unsigned char w1_receive_byte()
{
unsigned char data;
for(unsigned char i = 0; i < 8; i++) //в цикле смотрим что на шине и сохраняем значение
{
W1_DDR |= 1<<W1_BIT ;
_delay_us(2) ;
W1_DDR &= ~(1<<W1_BIT) ;
_delay_us(7) ;
if((W1_PIN & (1<<W1_BIT)) == 0x00)
data &= ~(1<<i) ;
else
data |= 1<<i ;
_delay_us(50) ;//задержка до окончания тайм-слота
}
return data ;
}

//функция преобразует полученные с датчика 18b20 данные в температуру
int temp_18b20()
{
unsigned char data[2] ;
int temp = 0 ;
if(w1_find()==1) //если есть устройство на шине
{
w1_sendcmd(0xcc) ;//пропустить ROM код, мы знаем, что у нас одно устройство или передаем всем
w1_sendcmd(0x44) ;//преобразовать температуру
_delay_ms(750) ;//преобразование в 12 битном режиме занимает 750ms
w1_find() ;//снова посылаем Presence и Reset
w1_sendcmd(0xcc) ;
w1_sendcmd(0xbe) ;//передать байты ведущему(у 18b20 в первых двух содержится температура)
data[0] = w1_receive_byte() ;//читаем два байта с температурой
data[1] = w1_receive_byte() ;
//загоняем в двух байтную переменную
temp = data[1] ;
temp = temp<<8 ;
temp |= data[0] ;
//переводим в градусы
temp *= 0.0625 ;//0.0625 градуса на единицу данных
}
//возвращаем температуру
return temp ;

int main(void)
{
DDRB = 0xFF ;
PORTB = 0 ;
TIMSK = 0b00000001 ;
TCCR0 = 0b00000010 ;
int temp ;
sei() ;
while(1)
{
temp = temp_18b20() ;
if(temp > 1000) //если температура <0
{
temp = 4096 - temp ;
temp = -temp ;
}
digit1 = temp/10 ;
digit2 = temp%10 ;
}
}
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение urry »

int temp_18b20() без завершающей скобки.
Вообще-то стыдно с такой мелочью сразу на форум.
Аватара пользователя
Dako
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Сб июл 30, 2011 05:35:35

Re: WinAvr в вопросах и ответах

Сообщение Dako »

Вопрос снят - проблему нашёл! )))
odnk
Родился
Сообщения: 1
Зарегистрирован: Пт фев 10, 2012 17:29:39

Проблемы с оптимизацией кода в WINAVR

Сообщение odnk »

При установленных уровнях оптимизации Q1,Q2,Q3,Qs не работают бесконечные циклы while(1),
for(;;), а также оператор безусловного перехода goto. На уровне Q0(без оптимизации)
таких проблем нет. WINAVR работает в оболочке AVR Studio. Подскажите что делать?
Заранее благодарен

Перенёс в тему по WINAVR-у, будьте внимательны..

МитяРа..
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение IfoR »

Покажите код с этой проблемой. Помню, у меня тоже была такая проблема.

P.S. у меня (avr-gcc 4.5.3) конструкция

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

for(;;); 
при -Os транслируется в нечто вроде

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

.L11:
    rjmp .L11
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение IfoR »

Народ, помогите разобраться с ассемблерными вставками. Конкретно: не пойму как правильно указать ограничения. Вот проблемный код:

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


uint8_t bip
(uint8_t in)
// Двоично-инверсная перестановка
uint8_t r buffersize2out;

asm volatile(
      
"loop:  \n"
      "rol    inr \n"
      "ror    outr \n"
      "dec    ir \n"
      "brne    loop"
    
: [outr]"=%d" (out) : [inr]"d" (in), [ir]"d" (r) );

return 
out;


На что он мне вежливо отвечает:
/tmp/cct7sRUq.s: Assembler messages:
/tmp/cct7sRUq.s:306: Error: constant value required
/tmp/cct7sRUq.s:307: Error: constant value required
/tmp/cct7sRUq.s:308: Error: constant value required


Мне, собственно, что сделать, что бы сказать компилятору, что и in, и r могут и читаться, и записываться, но их значения меня не интересуют: в память их записывать обратно не надо, а out тоже может читаться\писаться но его значение уже нужно?
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Ответить

Вернуться в «AVR»