ошибки записи EEPROM в AtTiny13 при моделировании в Proteus

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Здравствуйте всем! И заранее спасибо тем, кто откликнется!

Столкнулся с такой проблемой. В Tiny13 можно менять тактовую частоту АЛУ и остальных устройств за счет предделителя. По умолчанию Стоит частота 9,6 Мгц с предделением на 8. Простая программа записи (стирания) байта в EEPROM при коэффициенте деления предделителя до 16 (включительно) работает в Proteus нормально. А вот с делением более 16 при моделировании выдает ошибку, что запись не произошла, т.к. бит разрешения записи был аппаратно сброшен до начала самой записи (ну, или как-то так). И после этого остальная часть программы начинает работать не корректно. У меня возникли сомнения по поводу того, на реальной AtTiny есть ли такой баг (или это вовсе не баг?) или же это проблемы с Proteus (а может, в моих кривых руках)? Я так понимаю, тактирование EEPROM осуществляется также после предделителя или на прямую от тактового генератора? По схеме в даташите на нее идут сигналы и оттуда, и оттуда.... Совсем растерялся. Проверить на реальной схеме не имею возможности. Буду благодарен за любую помощь в данном вопросе.

на СИ код выглядит так:

#define DATA 55

//Установка предделителя
CLKPR=0x80;
CLKPR=0x08; // от 0 до 4 работает нормально, больше 4 выдает ошибку при моделировании

//запись в EPROM
while (EECR.EEPE=1);
EECR.EEPM0=0; //режим
EECR.EEPM1=1; //только записи
EEAR=0; // ну, или любой другой адрес
EEDR=DATA;
#asm("cli") // если прерываний нет - мона не писать
EECR.EEMPE=1;
EECR.EEPE=1;
#asm("sei") // если прерываний нет - мона не писать

{
далее пошел другой код
}
Реклама
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

посмотрим в ДШ:

System Clock and Clock Option:
в квадратик "Flash and EEPROM" заведено тактирование от clkFLASH и от RC.
clkFLASH: The Flash clock controls operation of the Flash interface. The Flash clock is usually active simultaneously with the CPU clock. - вроде, про EEPROM ничего не сказано.

EEPROM Data Memory:
When EEMPE has been written to one by software, hardware clears the bit to zero after four clock cycles.
...
The calibrated Oscillator is used to time the EEPROM accesses. Make sure the Oscillator frequency is within the requirements described in Oscillator Calibration Register – OSCCAL on page 23.
т.е. RC используется для доступа к EEPROM.
EEMPE расположен в регистрах ввода/вывода в SRAM Data Memory, а не в EEPROM, и эта защита (4 цикла после установки бита) используется и в других регистрах и служит для защиты при программном сбое, следовательно здесь, скорее всего, имеет место 4 цикла CPU.

Ваш код правильный. С большой вероятностью - это глюк протеуса - сбрасывать бит регистра EECR ввода/вывода через 4 такта RC. При делении на 16 нет ошибки, т.к. установлено деление RC/8: CLKDIV8=0.
Запись в CLKPR протеус отрабатывает правильно - тормозит выполнение основного кода.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

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

И исходя из Ваших пояснений получается, что EEPROM всегда работает на максимальной частоте?
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

Наверно не на максимальной. RC может работать на 9.6 или 4.8.
Еще нашел, что CKDIV8=0 - все-равно, что CLKPS=3. Т.е. протеус однозначно неадекватно себя ведет.
Сейчас проверил на реальной tiny13. Код такой:

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

CLKPR = (1<<CLKPCE); 
CLKPR = 5; // делитель на 32
DDRB = 0xFF;

while (EECR&(1<<EEPE)) ;
EECR = 0; 
EEARL = 0; 
EEDR = 0xAA;
EECR |= 1<<EEMPE;
EECR |= 1<<EEPE;

while (EECR&(1<<EEPE)); // если бит не сбросится (не прошла запись) - мы здесь зависнем
EEARL = 0; 
EEDR = 0; // на всякий случай :)
EECR |= 1<<EERE;

if(EEDR == 0xAA) PORTB = 1; // если значение совпало - зажигаем 1-й светодиод
else PORTB = 2; // не совпало (почему???) - второй светодиод

while(1);
Ну как и следовало ожидать - зажегся первый. Проверял с CKDIV8 = 1 и 0;
Так что еще один глюк протеуса, поздравляю!
(Модераторам: А не создать ли прилепленную тему про его глюки. а то у меня три уже есть, плюс этот)
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Вот за проверку на реальной микрухе большое спасибо и сердечный Вам плюс!

А по поводу внутреннего RC думаю, что вряд ли там стоят два генератора. Скорее всего стоит один (от которого напрямую и запитана EEPROM) и дополнительно стоит триггер, подключаемый через логический элемент посредством программирования fuse-битов. За счет него и происходит деление частоты на 2, идущей далее на предделитель и тактирование остальной периферии.
Реклама
Ответить

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