Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
radist108
1 / 1 / 0
Регистрация: 24.04.2012
Сообщений: 101
1

Инкремент адреса при записи данных в EEPROM

12.01.2017, 22:04. Просмотров 874. Ответов 11
Метки нет (Все метки)

Приветствую всех!
Какое есть решение для такой задачи: есть три кнопки. Нажимаю в произвольном порядке. И при каждом нажатии на какую-либо из кнопок у меня последовательно заполняются ячейки EEPROM. При этом каждой кнопке соответствует своя константа. Ниже болванка кода. adress++ к сожалению, не работает

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Подключаем внешние библиотеки
#include <avr/io.h> //подключение стандартной библиотеки ввода/вывода
#define F_CPU 16000000UL //определение тактовой частоты микроконтроллера для корректной работы функций задержки
#include <util/delay.h> //подключение библиотеки для генерации задержек
#include <avr/eeprom.h> //подключение библиотеки работы с EEPROM
 
unsigned char data; // Переменная хранения данных
uint8_t EEMEM adress; // Переменная хранения адреса
 
int main(void)
{
    /***Настройка портов ввода-вывода***/
    PORTC = 0x00; //
    DDRC |= (1 << PC2)|(1 << PC1)|(1 << PC0); // Выход на светодиоды
 
    DDRD |= (0 << PD2)|(0 << PD1)|(0 << PD0); // Входы для кнопок
    PORTD |= (1 << PD2)|(1 << PD1)|(1 << PD0); // подключаем внутренние нагрузочные резисторы
    
    adress = 0x0000; // 0000..01FF (0..511) (для ATmega168)
 
    while(1) // бесконечный цикл
    {   // Запись
        if ((PIND&(1 << PD0)) == 0) //  Проверяем: если состояние PD0 лог.«0» то кнопка нажата
        
        {
        _delay_ms(300); 
        eeprom_write_byte(&adress, (uint8_t) 0xAA); //запись байта data по адресу adress
        adress++;// инкремент адреса
        }   
        
        if ((PIND&(1 << PD1)) == 0) //  Проверяем: если состояние PD1 лог.«0» то кнопка нажата
        
        {
        _delay_ms(300); 
        eeprom_write_byte(&adress, (uint8_t) 0xBB); //запись байта data по адресу adress
        adress++;// инкремент адреса
        }
        
        if ((PIND&(1 << PD2)) == 0) //  Проверяем: если состояние PD1 лог.«0» то кнопка нажата
            
        {
        _delay_ms(300); 
        eeprom_write_byte(&adress, (uint8_t) 0xCC); //запись байта data по адресу adress
        adress++;// инкремент адреса
        }
        
    }
}
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.01.2017, 22:04
Ответы с готовыми решениями:

Работа с EEPROM (логика записи данных, чтение и защита)
Здравствуйте, подскажите алгоритм или код чтения и записи в EEPROM с равномерным истиранием ячеек,...

[РЕШЕНО] Проблемы записи EEPROM
Коллеги! Доброго времени суток! Кто может подтвердить наличие/отсутствие т.н. «мертвой зоны» в...

Инкремент адреса
При инкрементировании адреса насколько понимаю просто переходим на следующую ячейку памяти без...

Инкремент адреса внутри функции с воздействием на внешнюю переменную
Есть код #include &lt;stdio.h&gt; void func(char *str) { ++str; } int main(void)

c каком адреса ничинается EEPROM
что то нигде, в том числе в ДЩ не нашел какой первый и последний адрес EEPROM для Atmega8 --...

11
pyzhman
1152 / 510 / 74
Регистрация: 15.05.2012
Сообщений: 2,901
13.01.2017, 09:57 2
Особо не вникал. В глаза бросилось:
C
1
2
3
uint8_t EEMEM adress; // Переменная хранения адреса
...
adress = 0x0000; // 0000..01FF (0..511) (для ATmega168)[/quote]
0
Kukuxumushu
3073 / 661 / 122
Регистрация: 13.06.2015
Сообщений: 2,311
Завершенные тесты: 2
13.01.2017, 11:57 3
Во-1 у вас переменная adress сама определена в EEPROM, поэтому сама должна занимать там какой-то адрес (определяемый компилятором), который обязательно затрётся при нажатии кнопок. Во-2, переменная adress должна иметь размер 2 байта.
0
Евгений В
887 / 649 / 131
Регистрация: 01.03.2010
Сообщений: 1,236
13.01.2017, 22:54 4
Цитата Сообщение от radist108 Посмотреть сообщение
DDRD |= (0 << PD2)|(0 << PD1)|(0 << PD0); // Входы для кнопок
Господа, немного не в тему, но что значат выражения типа |(0 << PD2) и т.п? Разве они могут изменить бит?

Я тут новичок. Не судите строго.
Я пробовал сделать так
C
1
2
  DDRA=0b01111111;
  DDRA |= (0 << PA2)|(0 << PA1)|(0 << PA0);
В DDRA как было число 127 так и осталось. В чем суть тогда?
0
13.01.2017, 22:54
pyzhman
1152 / 510 / 74
Регистрация: 15.05.2012
Сообщений: 2,901
14.01.2017, 07:54 5
Нет, конечно, бит такая операция не поменяет. Суть в том, что "- Зачем так сделал? - Все делают, и я сделал...".
0
Евгений В
887 / 649 / 131
Регистрация: 01.03.2010
Сообщений: 1,236
14.01.2017, 21:46 6
Цитата Сообщение от pyzhman Посмотреть сообщение
Все делают, и я сделал...".
А почему все так делают? Я так и не получил ответа. Не первый раз вижу такой код.

В Студии так бит не поменять, но может в каком то другом компиляторе можно?
0
ValeryS
Модератор
7783 / 5786 / 754
Регистрация: 14.02.2011
Сообщений: 19,791
Завершенные тесты: 1
15.01.2017, 07:28 7
Цитата Сообщение от Евгений В Посмотреть сообщение
В Студии так бит не поменять,
так нигде не поменять
как мне ответил однажды Воланд на такой же вопрос, сейчас ответ не могу найти, все дело в удобстве и переносимости.
например настроить Usart
C++
1
...= 0<<Tx | 1<<Rx
определяя Tx Rx можно не запоминать какой бит отвечает, а подставляя 0 или 1 можно задействовать/не задействовать передатчик или приемник
Подход имеет право на жизнь другое дело что бездумно им пользоваться не стоит
1
Евгений В
887 / 649 / 131
Регистрация: 01.03.2010
Сообщений: 1,236
15.01.2017, 07:56 8
Цитата Сообщение от ValeryS Посмотреть сообщение
Подход имеет право на жизнь другое дело что бездумно им пользоваться не стоит
Цитата Сообщение от ValeryS Посмотреть сообщение
...= 0<<Tx | 1<<Rx
Когда стоит просто знак равно, тогда понять можно, зачем. Биты будут установлены с обнулением всех остальных.
0<<Tx будет и как нуль и как памятка.

Добавлено через 1 минуту
Цитата Сообщение от radist108 Посмотреть сообщение
DDRD |= (0 << PD2)|(0 << PD1)|(0 << PD0); // Входы для кнопок
Получается, что у ТС это выражение бесполезное? И даже вредное. Будешь думать что там нули, а на деле может быть 1.

ТС, без обид
0
ValeryS
Модератор
7783 / 5786 / 754
Регистрация: 14.02.2011
Сообщений: 19,791
Завершенные тесты: 1
15.01.2017, 08:10 9
Цитата Сообщение от Евгений В Посмотреть сообщение
Получается, что у ТС это выражение бесполезное?
да
Цитата Сообщение от Евгений В Посмотреть сообщение
И даже вредное. Будешь думать что там нули,
а вот здесь нет нужно знать что 0 ничего не меняет

сам такой записью не пользуюсь, посему аргументировано защитить её не смогу
до сих пор считаю, что правильней здесь использовать битовые поля и объединения
1
Ethereal
7353 / 2194 / 299
Регистрация: 17.02.2013
Сообщений: 3,239
17.01.2017, 15:32 10
Цитата Сообщение от Евгений В Посмотреть сообщение
Сообщение от radist108
DDRD |= (0 << PD2)|(0 << PD1)|(0 << PD0); // Входы для кнопок
Господа, немного не в тему, но что значат выражения типа |(0 << PD2) и т.п? Разве они могут изменить бит?
Да читается это так :
Ну и что-же я буду выставлять в регистре DDRD ?
Бит PD2 выставлять не буду, бит PD1 выставлять не буду и бит PD0 выставлять не буду.
Вот чего я буду ! Ничего не буду !
0
Евгений В
887 / 649 / 131
Регистрация: 01.03.2010
Сообщений: 1,236
17.01.2017, 20:25 11
Цитата Сообщение от Ethereal Посмотреть сообщение
Вот чего я буду ! Ничего не буду !
А зачем тогда писать это выражение?
Я с вами не спорю. Учусь. Поэтому хочу понять. Зачем?
0
Voland_
1669 / 1057 / 100
Регистрация: 04.01.2010
Сообщений: 3,581
18.01.2017, 10:11 12
Цитата Сообщение от Евгений В Посмотреть сообщение
Я с вами не спорю. Учусь. Поэтому хочу понять. Зачем?
...такое выражение было скопипастено из каких-то примеров, где присходила инициализация пинов или регистров управления периферией.
То есть, допустим, вам надо инитить UART, чтобы работал TX, но RX не работал (к примеру, просто для объяснений):
Вы пишете:
C
1
UART_CTRL = (1 << UART_TX_EN ) | ( 0 << UART_RX_EN );
Такая запись позволяет разработчику быстро увидеть в коде знакомые названия битов, и установлены они в регистре или нет. То есть мне тут понятно - TX включается, RX - не включается. Когда и если понадобится включить RX - я просто найду эту строчку и поменяю всего-лишь "0" на "1" и все, мне не нужно для этого лезть в дефайны USORT'a и выискивать как называется соответствующий бит управления.

Но в вашем примере, когда вы делаете что-то типа "USORT_CTRL |= (0 << USORT_RX_EN ) - просто бредовая строчка. Вы как бы показываете, что "и хотели бы" включить RX, но не включили. В итоге скорее всего компилятор ее просто выкинет из кода (если USORT_RX_EN - это не имя переменной или константы в памяти, например).
Поэтому, (это имхо) записть типа "PERIPH_CTRL = (1 << BIT1) | (0 << BIT2)... " актуальна только в операциях присваивания, без арифметики. А запись типа "PERIPH_CTRL |= ( 1 << BITn)" обязана иметь в себе только единички. Равно как и "PERIPH_CTRL &= ~(1 << BITn)" для инверсии. Но в этом случае надо следить за типом единицы, чтобы компилятор правильно переносил бит, в случае, если PERIPH_CTRL по какой-то причине больше битности шины. В этом случае может так случиться, что, скажем "1<<24" = 0, потому что "1" имела тип uint16_t по умолчанию.
2
18.01.2017, 10:11
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.01.2017, 10:11

Сохранение данных в EEPROM при пропадании питания
Здравствуйте. В моей поделке появилась нужда сохранять переменную (координату) при выключении...

Ошибка записи eeprom
Есть микруха памяти eeprom ST 95640. Надо считать, поправить, и обратно залить. Собрал Понипрог....

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru