Думал об этом варианте, а не подскажете как сделать указатель на EEPROM? Для общего развития пригодитсяМастер Ломастер писал(а): определить в программе указатель, присвоить ему нужный адрес, и работать с ним, как с указателем (т.е. адресом) вашей переменной - в этом случае все значительно проще, имхо.
WinAvr в вопросах и ответах
- Реклама
в WinAVR нет специального типа указателя для работы с EEPROM, просто объявите указатель и все.
битва с дураками проиграна, победители торжествуют. слава победителям!
а вот как объявить указатель, не силен в языках программирования.Мастер Ломастер писал(а):в WinAVR нет специального типа указателя для работы с EEPROM, просто объявите указатель и все.
Дык, а как компилятор узнает что мы хотим указать на еепром?)
Просто указатель если объявить и присвоить ему какое-то значение он будет указывать на ОЗУ, как я понимаю
Просто указатель если объявить и присвоить ему какое-то значение он будет указывать на ОЗУ, как я понимаю
с EEPROM вы должны работать при помощи функций типа eeprom_read_byte() или eeprom_write_byte() (посмотрите в документации - есть много функций для работы с байтами, словами, блоками и т.п.). все эти функции в качестве параметра получают указатель, который внутри себя трактуют как указатель в EEPROM. в вашей программе это просто указатель.BCluster писал(а):Дык, а как компилятор узнает что мы хотим указать на еепром?)
Просто указатель если объявить и присвоить ему какое-то значение он будет указывать на ОЗУ, как я понимаю
shurikss123 писал(а):а вот как объявить указатель, не силен в языках программирования.Мастер Ломастер писал(а):в WinAVR нет специального типа указателя для работы с EEPROM, просто объявите указатель и все.
Код: Выделить всё
unsigned char *pchar; // указатель на байт без знака
int *pint; // указатель на int
pchar = (void*)12; // указатель будет указывать на 12-ю ячейку памятибитва с дураками проиграна, победители торжествуют. слава победителям!
- Реклама
Спасибо, я не знал об этих функциях. Я на кодвижне писал для авр, черт бы его подрал )
Ну в таком случае можно вообще передавать в параметре этих функций адрес непосредственно - захотел 20 ячейку прочесть - передал eeprom_read_byte(20);
Ну в таком случае можно вообще передавать в параметре этих функций адрес непосредственно - захотел 20 ячейку прочесть - передал eeprom_read_byte(20);
но лучше делать чуть иначеBCluster писал(а):Ну в таком случае можно вообще передавать в параметре этих функций адрес непосредственно - захотел 20 ячейку прочесть - передал eeprom_read_byte(20);
Код: Выделить всё
eeprom_read_byte((void*)20);битва с дураками проиграна, победители торжествуют. слава победителям!
Да, я просто не знаю специфики компилятора, наверняка будет вонингМастер Ломастер писал(а):иначе компилятор будет возмущаться
- Сообщения: 541
- Зарегистрирован: Вт фев 09, 2010 17:52:26
Пример для работы с еепром.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) высчитываем длину блока данных
Прочитать записанное
Код: Выделить всё
eeprom_read_block(&t_0_ram, &t_0_rom, sizeof(t_0_ram));
- Сообщения: 134
- Зарегистрирован: Вс авг 01, 2010 16:05:25
Доброе время суток. Нужен совет,есть функция вот отрывок
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",а мне надо что бы она заходила постоянно
ведь там она опрашивает кнопки. Вот как бы мне заставить компилятор что бы он позволил
программе заходить постаянно в эту функцию.
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",а мне надо что бы она заходила постоянно
ведь там она опрашивает кнопки. Вот как бы мне заставить компилятор что бы он позволил
программе заходить постаянно в эту функцию.
ничего не понятно - дайте весь код.
битва с дураками проиграна, победители торжествуют. слава победителям!
- Сообщения: 134
- Зарегистрирован: Вс авг 01, 2010 16:05:25
Да я не о программе, я в целом. Вот если,в объявление переменной поставить "volatule" то компилятору
это говорит что переменная может измениться в любой момент, а я хочу узнать если для функций
какие нибудь квалификаторы.
это говорит что переменная может измениться в любой момент, а я хочу узнать если для функций
какие нибудь квалификаторы.
функция может игнорироваться компилятором-оптимизатором только в том случае, если она не меняет ничего в программе. в частности, если она меняет переменные, которые должны быть volatile? но не являются таковыми - компилятор может счесть, что функция лишняя. особых квалификаторов для функций не существует.TICLIR писал(а):Да я не о программе, я в целом. Вот если,в объявление переменной поставить "volatule" то компилятору
это говорит что переменная может измениться в любой момент, а я хочу узнать если для функций
какие нибудь квалификаторы.
битва с дураками проиграна, победители торжествуют. слава победителям!
так вызывайте ее когда нужно сделать опрос кнопок!codenamehawk писал(а):,а мне надо что бы она заходила постоянно
Код: Выделить всё
void kkoll( char oche);{Мастер Ломастер писал(а):которые должны быть volatile? но не являются таковыми - компилятор может счесть, что функция лишняя.
Он даже когда переменная не используется предупреждает.Говорит, что переменная объявлена, но не используется.Думаете для функции не так?
В поисках истины человек развивается.
- Сообщения: 39
- Зарегистрирован: Сб июл 30, 2011 05:35:35
Здравствуйте! Вновь обращаюсь к вам за помощью. Пробую собрать термометр на 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 ;
}
}
#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 ;
}
}
int temp_18b20() без завершающей скобки.
Вообще-то стыдно с такой мелочью сразу на форум.
Вообще-то стыдно с такой мелочью сразу на форум.
- Сообщения: 39
- Зарегистрирован: Сб июл 30, 2011 05:35:35
- Сообщения: 1
- Зарегистрирован: Пт фев 10, 2012 17:29:39
При установленных уровнях оптимизации Q1,Q2,Q3,Qs не работают бесконечные циклы while(1),
for(;;), а также оператор безусловного перехода goto. На уровне Q0(без оптимизации)
таких проблем нет. WINAVR работает в оболочке AVR Studio. Подскажите что делать?
Заранее благодарен
Перенёс в тему по WINAVR-у, будьте внимательны..
МитяРа..
for(;;), а также оператор безусловного перехода goto. На уровне Q0(без оптимизации)
таких проблем нет. WINAVR работает в оболочке AVR Studio. Подскажите что делать?
Заранее благодарен
Перенёс в тему по WINAVR-у, будьте внимательны..
МитяРа..
Покажите код с этой проблемой. Помню, у меня тоже была такая проблема.
P.S. у меня (avr-gcc 4.5.3) конструкция при -Os транслируется в нечто вроде
P.S. у меня (avr-gcc 4.5.3) конструкция
Код: Выделить всё
for(;;); Код: Выделить всё
.L11:
rjmp .L11Народ, помогите разобраться с ассемблерными вставками. Конкретно: не пойму как правильно указать ограничения. Вот проблемный код:
На что он мне вежливо отвечает:
Код: Выделить всё
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;
} Мне, собственно, что сделать, что бы сказать компилятору, что и in, и r могут и читаться, и записываться, но их значения меня не интересуют: в память их записывать обратно не надо, а 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




