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

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

Сообщение BCluster »

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

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

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

Сообщение shurikss123 »

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

Сообщение BCluster »

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

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

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

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

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

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

Сообщение BCluster »

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

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

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

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

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

Сообщение BCluster »

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

Сообщение 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)); 
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

Сообщение 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
Откуда: Цветочный город

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

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

Сообщение TICLIR »

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

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

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

Сообщение vitalik_1984 »

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

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

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

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

Сообщение 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 ;
}
}
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

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

Сообщение Dako »

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

Сообщение odnk »

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

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

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

Сообщение IfoR »

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

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

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

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

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

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

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

Сообщение IfoR »

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

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

uint8_t bip(uint8_t in)
{ // Двоично-инверсная перестановка
uint8_t r = buffersize2, out;

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»