CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

Х.З. меня кодевиженовская работа с ЕЕПРОМ устраивает в 90% задач
единственное - после работы с ЕЕПРОМ я указатель убраю с занятой области ЕЕПРОМ, т.к. у тех, кто повторял мои поделки случались повреждения данных в ЕЕПРОМ... ну, и браундетектор включаю.
остальные 10% - нестандартное использование, например постепенное сбрасывание битов для увеличения ресурса памяти счетчика наработки (8 событий записали - 1 раз стёрли) или 24 битные переменные...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Друг Кота
Сообщения: 9177
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

а нам нужна универсальная программа работы с ЕЕПРОМ... под любую IDE... от голого МК до Ардуины.
чтоб по 100 раз не переделывать.
а универсальная программа - это когда мы работаем напрямую с регистрами МК.
:tea:

далее...
только есть проблемка...
у нас две переменные типа int да ещё и со знаком...
int c=0;
int d=0;
поэтому будут записываться в епром только половинка наших переменных ))
а что делать ?
:roll:
ну самое простое изменить тип переменных...
будут char и без знака... ))

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

#include <tiny2313.h>
#include <delay.h>


int p;
unsigned char c=0; //int c=0;
unsigned char d=0; //int d=0;

//eeprom char c_eep;
void TX_c_eep(void)
{
     EEAR = 0;                     
     EEDR = c;              
     EECR |= 0b00000100;           
     EECR |= 0b00000010;           
     while(EECR & 0b00000010);     
};
void RX_c_eep(void)
{
    EEAR = 0;              
    EECR |= 0b00000001;     
    c = EEDR;          
};


//eeprom char d_eep;
void TX_d_eep(void)
{
     EEAR = 1;                     
     EEDR = d;              
     EECR |= 0b00000100;           
     EECR |= 0b00000010;           
     while(EECR & 0b00000010);     
};
void RX_d_eep(void)
{
    EEAR = 1;              
    EECR |= 0b00000001;     
    d = EEDR;          
};


interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{ 
TCNT1H=0;
TCNT1L=0;
p++;
if(p>59) {p=0;};
}


void main(void)
{


TX_c_eep(); //c_eep=c;
TX_d_eep(); //d_eep=d;
#asm("sei")


m1:
PORTD.0=0;
PORTD.1=0;
delay_ms(1000);
while (1) {
if(PIND.5==0){delay_ms(1000);break; };
if(PIND.3==0){delay_ms(300);break; };
};
p=0;
delay_ms(100);
RX_c_eep(); //c=c_eep;
delay_ms(100);
RX_d_eep(); //d=d_eep;
delay_ms(100);
PORTD.0=c;
PORTD.1=d;
while(1) {
if(PINB.0 && !PINB.1 && !PINB.2 && !PINB.3) {c=0; d=0; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(!PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=0; d=1; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=1; d=0; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(!PINB.0 && !PINB.1 && PINB.2 && !PINB.3) {c=1; d=1; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(p==30){delay_ms(300);break;};
};
delay_ms(1000);
goto m1;


}
Ну вот. Так ещё лучше))
:tea:

Добавлено after 25 minutes 42 seconds:
или нам все таки нужно типа int... как в оригинале))
можно и int.. только придётся дробить))

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

#include <tiny2313.h>
#include <delay.h>


int p;
int c=0; //unsigned char c=0;  
int d=0; //unsigned char d=0; 

//eeprom char c_eep;
void TX_c_eep(void)
{
     EEAR = 0;                     
     EEDR = (c>>8);              
     EECR |= 0b00000100;           
     EECR |= 0b00000010;           
     while(EECR & 0b00000010);     
     EEAR = 1;                     
     EEDR = c;              
     EECR |= 0b00000100;           
     EECR |= 0b00000010;           
     while(EECR & 0b00000010);     
};
void RX_c_eep(void)
{
    EEAR = 0;              
    EECR |= 0b00000001;     
    c = EEDR;          
    EEAR = 1;              
    EECR |= 0b00000001;     
    c = (c<<8)|EEDR;          
};


//eeprom char d_eep;
void TX_d_eep(void)
{
     EEAR = 2;                     
     EEDR = (d>>8);              
     EECR |= 0b00000100;           
     EECR |= 0b00000010;           
     while(EECR & 0b00000010);     
     EEAR = 3;                     
     EEDR = d;              
     EECR |= 0b00000100;           
     EECR |= 0b00000010;           
     while(EECR & 0b00000010);     
};
void RX_d_eep(void)
{
    EEAR = 2;              
    EECR |= 0b00000001;     
    d = EEDR;          
    EEAR = 3;              
    EECR |= 0b00000001;     
    d = (d<<8)|EEDR;          
};


interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{ 
TCNT1H=0;
TCNT1L=0;
p++;
if(p>59) {p=0;};
}


void main(void)
{


TX_c_eep(); //c_eep=c;
TX_d_eep(); //d_eep=d;
#asm("sei")


m1:
PORTD.0=0;
PORTD.1=0;
delay_ms(1000);
while (1) {
if(PIND.5==0){delay_ms(1000);break; };
if(PIND.3==0){delay_ms(300);break; };
};
p=0;
delay_ms(100);
RX_c_eep(); //c=c_eep;
delay_ms(100);
RX_d_eep(); //d=d_eep;
delay_ms(100);
PORTD.0=c;
PORTD.1=d;
while(1) {
if(PINB.0 && !PINB.1 && !PINB.2 && !PINB.3) {c=0; d=0; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(!PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=0; d=1; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=1; d=0; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(!PINB.0 && !PINB.1 && PINB.2 && !PINB.3) {c=1; d=1; TX_c_eep(); TX_d_eep(); delay_ms(2000);break;}; //c_eep=c; d_eep=d;
if(p==30){delay_ms(300);break;};
};
delay_ms(1000);
goto m1;


}
ну вот. теперь как в оригинале))
:tea:
прошиваем... проверяем...
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

фига-се... для каждой переменной свой набор функций... :shock:
можно ведь указатели применить, и как-его (забыл как называется) - пишешь 2 функции - одну под инт переменную, вторую под чар и в зависимости от подсунутого компилятор сам нужную вызовет. ну, на крайняк в имени функции намекнуть с чем она работает...
а про знковость вообще не понял - тут ни сравнения нет ни вообще математики... этим функциям должно быть по барабану содержимое обрабатываемых переменных
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Друг Кота
Сообщения: 9177
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

Не нужны там разные переменные в именах функций... Не нужны там указатели... и т.д.
Потому что нормальные люди пишут сразу массив с контролем целостности.
Но как я уже говорил выше... у нас не совсем обычная программа. Так сразу не поймешь))
Ты дальше ещё не видел... что там в main творится)) Магия))
:tea:
Реклама
Эиком - электронные компоненты и радиодетали
Нашел транзистор. Понюхал.
Сообщения: 193
Зарегистрирован: Ср сен 04, 2019 17:59:23
Откуда: Гомель

Сообщение Alex_ka »

[uquote="Ljubitel",url="/forum/viewtopic.php?p=4748625#p4748625"]Ничего, что таймер не инициализирован и прерывание никогда не срабатывает?[/uquote]Все работает, просто я не указывал всю программу, где выставлены прерывания и выделена 1 секунда.

Добавлено after 4 minutes 58 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=4748632#p4748632"]ну вот. теперь как в оригинале))
:tea:
прошиваем... проверяем...[/uquote]Спасибо огромное за помощь. Но уже в понедельник попробую. Всё на работе и устройство, и программатор. Отпишусь.
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 437
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4748643#p4748643"]можно ведь указатели применить, и как-его (забыл как называется) - пишешь 2 функции - одну под инт переменную, вторую под чар и в зависимости от подсунутого компилятор сам нужную вызовет.[/uquote]
Такое только в ООП работает. А тут хотят чтобы везде собиралось. Я бы действительно применил указатель и размер. Типа write_eep( &t, sizeof( t ) ) и всё. Хотя, надо бы ещё и адрес в EEPROM передавать.
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 22 апреля 2026 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.
/!\ Обновлений для STM32PowerMon и STM32PowerMon-UCPD временно не будет.
Реклама
Вымогатель припоя
Сообщения: 533
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Alex_ka писал(а):m1:
PORTD.0=0;
PORTD.1=0;
delay_ms(1000);
while (1) {
if(PIND.5==0){delay_ms(1000);break; };
if(PIND.3==0){delay_ms(300);break; };
}
p=0;
delay_ms(100);
c=c_eep;
delay_ms(100);
d=d_eep;
delay_ms(100);
PORTD.0=c;
PORTD.1=d;
while(1) {
if(PINB.0 && !PINB.1 && !PINB.2 && !PINB.3) {c=0; d=0;c_eep=c; d_eep=d;delay_ms(2000);break;}
if(!PINB.0 && PINB.1 && !PINB.2 && !PINB.3){c=0; d=1;c_eep=c; d_eep=d;delay_ms(2000);break;}
if(PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=1; d=0;c_eep=c; d_eep=d;delay_ms(2000);break;}
if(!PINB.0 && !PINB.1 && PINB.2 && !PINB.3) {c=1; d=1;c_eep=c; d_eep=d;delay_ms(2000);break;}
if(p==30){delay_ms(300);break;};
}
delay_ms(1000);
goto m1; }
}.
Первое что стоит поменять, это выкинуть гото, наверное будет достаточно переместить нижний while(1) на место метки m1:
Тут

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

while (1) {
if(PIND.5==0){delay_ms(1000);break; };
if(PIND.3==0){delay_ms(300);break; };
}
еще можно понять назначение ;break;

Но после break; ниже и других таких-же if(PINB.0 && !PINB.1 && !PINB.2 && !PINB.3) {c=0; d=0;c_eep=c; d_eep=d;delay_ms(2000);break;}
программа выйдет из while (1) и выполнение программы завершится, на самом деле проц пойдет выполнять команды до конца памяти и есть там все стерто, перейдет в начало программы.

Писать в еепром, да еще и в цикле, если данные не поменялись, неправильная идея, ресурс еепром хотя и большой, но он имеет свои границы.
Если не приходит в голову, как это сделать используйте работу с еепром с update.
Встроенные функции для работы с еепром работают и нет необходимости их заменять.

Найдите рабочий протеус (ищите 8.13) и запустите в нем пошаговую отладку.
Поймете как ведет себя ваша программа и что надо поправить.
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

тоже думаю что достаточно создать 2 функции: чтение и запись (с проверкой несоответствия), работающие по параметрам, параметры задефайнить и подставлять по мере надобности.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Вымогатель припоя
Сообщения: 533
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Если выскакивать из цикла по гото, то хз как поведет себя программа.
Друг Кота
Сообщения: 9177
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

Терпеть не могу дефайны... Код становится не читаемый.
В даташите нет никаких дефайнов.

goto лучше любых циклов. Быстрый безусловный переход в любое место программы. Я бы все заменил на goto.

Если выйти из goto то программа просто завершится и мк выключится))
Иногда такое тоже нужно. Например при включении питания мк надо включить лампочку и завершить программу... до следующего включения мк.

А вот писать епром в цикле действительно не лучшая идея.
У епро всего то гарантируется 100.000 циклов записи.
Это очень мало...
И т.д.
:tea:
OKF
Это не хвост, это антенна
Сообщения: 1407
Зарегистрирован: Вт июн 07, 2011 08:03:18

Сообщение OKF »

[uquote="roman.com",url="/forum/viewtopic.php?p=4748889#p4748889"]Терпеть не могу дефайны... Код становится не читаемый.
goto лучше любых циклов. Быстрый безусловный переход в любое место программы. Я бы все заменил на goto.
Если выйти из goto то программа просто завершится и мк выключится))
Иногда такое тоже нужно. Например при включении питания мк надо включить лампочку и завершить программу... до следующего включения мк.
И т.д.[/uquote]
Что ни фраза, то в цитатник! Рома, жги ещё.
Нашел транзистор. Понюхал.
Сообщения: 193
Зарегистрирован: Ср сен 04, 2019 17:59:23
Откуда: Гомель

Сообщение Alex_ka »

Попробовал на железе нифига. При первоначальном включении на РD0 и РD1 нули, а стоит ввести любое другое состояние портов "В", к примеру чтобы было две единицы на портах D0 и D1, то D0 становится единица,а D1 ноль и не меняется больше никак как не меняй состояния портов "В", покуда не отрубишь питание. Питание отрубил и все точно так заново. Железо ведет себя так, как и в первоначальном варианте, что я выложил. Что за ерунда, что не так, где все же ошибка. Протеус 8.13 у меня давно стоит. Только не знаю как там пошагово смотреть. Да и вряд ли там он что то поможет.
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

Нафиг ГоТо! из-за него легко компилятор так озадачить, что в лучшем случае код раздует, но чаще в результате или сразу ничего не заработает или будут непонятные глюки, наигрался, хватит... Пусть в ассемблере остаётся.
Из цикла есть более цивилизованные способы выхода - брейк, например
А вот дефайны я какраз уважаю :) с ними можно сделать код и компактнее и понятнее и гибче, жаль в кодевижене у блока, раскрывающего дефайны относительно скудный потенциал...
(мне, например, модифицируемых переменных - счётчиков не хватает)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Мучитель микросхем
Аватара пользователя
Сообщения: 437
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4749493#p4749493"]Пусть в ассемблере остаётся.[/uquote]
В ассемблере он тоже не нужен. Там джампы есть.
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 22 апреля 2026 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.
/!\ Обновлений для STM32PowerMon и STM32PowerMon-UCPD временно не будет.
Друг Кота
Сообщения: 9177
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

OKF писал(а):Рома, жги ещё.
я рад что все нравится ))
:)
Ivanoff-iv писал(а):Нафиг ГоТо!
ты что ! ГоТо это мощь ! ))
8)
проверил условие... если нет то сразу перешёл куда надо ))
часто в начало программы...

ГоТо пришёл из ассемблера... это аналог джампа.
:tea:
Alex_ka писал(а):Попробовал на железе нифига.
значит проблема не в епром... а дальше.
для начала надо проверить кнопки.
настройки кнопок в программе не показаны.
:tea:
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

Используя ГоТо вместо стандартных команд выхода ты, как минимум, не сможешь использовать оптимизацию на полную мощь, потому что этой командой создаёшь нестандартный код, который компилятор плохо оптимизирует (ну не может создатель компилятора предусмотреть всё)
а можешь и стек сорвать - попробуй выскочиь не из цикла, а из подпрограммы...
Я не говорю, что я ГоТо не использую, использую... но очень осторожно и считаю, что если его пришлось применить - значит моего профессионализма не хватило для того, чтобы изящно обойтись без него.

Добавлено after 2 minutes 30 seconds:
например создал микроРТОС - там этих ГоТо :facepalm: но без них не получается... :oops:
Но я их аккуратно в дефайны завернул - это немного снижает риск неправильного их применения
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Нашел транзистор. Понюхал.
Сообщения: 193
Зарегистрирован: Ср сен 04, 2019 17:59:23
Откуда: Гомель

Сообщение Alex_ka »

[uquote="roman.com",url="/forum/viewtopic.php?p=4749512#p4749512"]значит проблема не в епром... а дальше.
для начала надо проверить кнопки.
настройки кнопок в программе не показаны.
:tea:[/uquote]там кнопок нет, там управление на порт "В" подаётся с микросхемы DTMF НТ9170. т. е с телефонного аппарата, в тональном наборе приходит комбинация цифр и меняет состояние на порту "В".
Друг Кота
Сообщения: 9177
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

нету кнопок...
ну так ничего не мешает подключить 4 кнопки для проверки...
PINB.0 && !PINB.1 && !PINB.2 && !PINB.3
:idea: :idea: :idea: :idea:
если бы ещё понимать что мы вообще делаем... и зачем... было бы проще))
:tea:
Нашел транзистор. Понюхал.
Сообщения: 193
Зарегистрирован: Ср сен 04, 2019 17:59:23
Откуда: Гомель

Сообщение Alex_ka »

Спасибо всем. Разобрался с вашей помощью.
Вывел из цикла и прописал. Сделал вот так. Все работает без проблем.
........................
if(!PINB.0 && !PINB.1 && !PINB.2 && !PINB.3) {c=0; d=0;;break;}; // от DTMF 1
if(!PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=0; d=1;;break;}; // от DTMF 2
if(PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=1; d=0;;break;}; // от DTMF 3
if(!PINB.0 && !PINB.1 && PINB.2 && !PINB.3) {c=1; d=1; break;}; // от DTMF 4
if(p==33){delay_ms(300);break;goto m2;};
}
delay_ms(100);
TX_c_eep();
delay_ms(100);
TX_d_eep();
delay_ms(100);
.........

Добавлено after 7 minutes 14 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=4749716#p4749716"]если бы ещё понимать что мы вообще делаем... и зачем... было бы проще))
:tea:[/uquote]Это замена программы при ремонте PBX-PD1 (схема здесь есть на форуме, вылаживал когда то), когда бьёт контроллер, чтобы громкость устанавливать с аппарата программно можно было.У нас их очень много установлено и автодозвон не используется, так как на номере АТС запрограммирована переадресация. Чисто переговорное устройство.
Вымогатель припоя
Сообщения: 533
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Alex_ka писал(а):if(!PINB.0 && !PINB.1 && !PINB.2 && !PINB.3) {c=0; d=0;;break;}; // от DTMF 1
if(!PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=0; d=1;;break;}; // от DTMF 2
if(PINB.0 && PINB.1 && !PINB.2 && !PINB.3) {c=1; d=0;;break;}; // от DTMF 3
if(!PINB.0 && !PINB.1 && PINB.2 && !PINB.3) {c=1; d=1; break;}; // от DTMF 4
Это иногда приводит к пропуску.
Если сложится так, что PINB.2 поменяется после третьего if, перед четвертым if, ни одно условие не сработает.

Введите четыре переменные типа unsigned char и считайте в них состояние пинов, тогда пропуска не будет гарантированно.

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

 unsigned char in_PINB0, in_PINB1, in_PINB2, in_PINB3;

in_PINB0 = PINB.0;
in_PINB1 = PINB.1;
in_PINB2 = PINB.2;
in_PINB3 = PINB.3;

if(!in_PINB0 && !in_PINB1 && !in_PINB2 && !in_PINB3) {c=0; d=0;;break;}; // от DTMF 1
...
Ответить

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