РАДИОСХЕМЫ



РАДИОФОРУМЫ


СХЕМЫ И СТАТЬИ



  • Страница 1 из 1
  • 1
Архив - только для чтения
Форум радиолюбителей » СХЕМЫ » МИКРОСХЕМЫ » Помогите с кодом на C
Помогите с кодом на C
Вс, 05.07.2015, 20:38 | Сообщение # 1        
adamchuk2012
аватар
  Постов: 14   ОК 
Всем привет. Делаю первое устройство на атмеге 8 сижу верстаю код. вот в чём затык. есть две ножки опрашивемых при выполнении цикла. одна должна запускать другая останавливать (прерывать даже если не закончен цикл) вот код /*
parostruika
*/

#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
void preset (){
DDRB = 0xFF;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xFF;
}

int main(void)
{ preset() ;
{PORTB = 0b00000001; //влючаю нагрев
while(PC0==0) // пока на датчике верхнего уровня нет воды
if (PINC&(1<<PC1)) // если на датчике нижнего нет воды то ( pinc0- датчик верхнего уровня, pinc1-датчик нижнего уровня)
{ PORTB = 0b00000010 ;// выключаю нагрев, пищу 10 сек
_delay_ms(10000) ;
PORTB = 0b00000100;// прекратил пищать включил сброс пара
_delay_ms(10000);
PORTB = 0b00001100;// сбрасываю пар и заправляюсь одновременно
_delay_ms(10000000);}
else PORTB = 0b00000001; // включаю нагрев
}


}
Вс, 05.07.2015, 21:09 | Сообщение # 2        
Витинари
аватар
  Постов: 1503   Друзья 
adamchuk2012, в программировании в целом опыт есть? У контроллеров имеются некоторые тонкости.
1. Зачем настройки портов выведены в отдельную функцию preset()?
2. Главная функция есть, но где основной цикл while(1)? Именно он заставляет программу выполняться снова и снова, а не стопориться после первого раза.
int main(void)
{ preset() ;
{PORTB = 0b00000001; //влючаю нагрев

откуда здесь взялась фигурная скобка, если ей ничего не предшествует? ПО-видимому, это и есть рудиментный остаток от бесследно пропавшего цикла.

while(PC0==0) // пока на датчике верхнего уровня нет воды
...
после оператора цикла нет фигурных скобок.

Вообще, не стоит забывать про фигурные скобки. Даже если по логике их можно смело опустить, лучше не пренебрегать ими. Компиляторы - штука тонкая, и ничто не мешает их разработчикам порадовать программистов очередным маразмом с собственными стандартами Си, придуманными по велению задней левой пятки. И тогда может оказаться, что эти самые пропущенные скобки сыграют злую шутку при сборке или оптимизации кода. На пиках, в частности, неоднократно сталкивался с таким - явный говнокод с элементами индусского программирования может работать лучше, чем красивый и правильный (а все потому, что нерегулируемая оптимизация все равно перекроит его во славу Шеогората).

Попробуй так:
Код
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRB = 0xFF;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xFF;
while(1)
{
PORTB = 0b00000001; //влючаю нагрев
if(!PC0) // лучше избегать цикла в цикле; пока на датчике верхнего уровня нет воды
{
if (PINC&(1<<PC1)) // если на датчике нижнего нет воды то ( pinc0- датчик верхнего уровня, pinc1-датчик нижнего уровня)
{
PORTB = 0b00000010 ;// выключаю нагрев, пищу 10 сек
_delay_ms(10000) ;
PORTB = 0b00000100;// прекратил пищать включил сброс пара
_delay_ms(10000);
PORTB = 0b00001100;// сбрасываю пар и заправляюсь одновременно
_delay_ms(10000000);
}
else{PORTB = 0b00000001;} // включаю нагрев
}
}
}
Вс, 05.07.2015, 21:43 | Сообщение # 3        
adamchuk2012
аватар
  Постов: 14   ОК 
тоже не работает как надо. цикл прерывается когда нижний датчик в воде. а нужно верхним останавливать. Программист я начинающий. поэтому и косячу. но научиться охота большая
Вс, 05.07.2015, 21:49 | Сообщение # 4        
msmmmm2
аватар
  Постов: 166   ОК 
Цитата Витинари ()
нерегулируемая оптимизация все равно перекроит его во славу Шеогората

А как же volatile? И оптимизация с указанной переменной по барабану. Проверял, сравнивал код ассемблера с "volatile" и без. На PIC-ах.
Вс, 05.07.2015, 21:57 | Сообщение # 5        
adamchuk2012
аватар
  Постов: 14   ОК 
msmmmm, что вы имели в виду?
Вс, 05.07.2015, 22:17 | Сообщение # 6        
msmmmm2
аватар
  Постов: 166   ОК 
Это к Витинари, но, если интересно... Компилятор очень сложно, многоступенчато и витиевато делает свою работу - превращает текст на С в машинный код, при чем так, как ему кажется эффективно. Например, если раз 5 подряд написать присвоение одного и того же числа переменной, в машинном коде (даю 99%) будет одно присвоение, что мы можем увидеть, проанализировав листинг дизассемблирования. Если раз 20 подряд линейно опросить порт, компилятор организует цикл, а нам нужен именно очень быстрый опрос. В циклах меняются местами проверка условия и тело (с умом, программа работает нормально), вследствие чего имеем работающую программу, но, например, разное время выполнения первого и последующих проходов цикла, что может быть важно в очень скоростных программах. Везде в таких случаях нужно перед объявлением переменной ставить ключевое слово volatile, которое указывает компилятору, что все, что касается данной переменной нужно компилировать "как есть", не оптимизируя.

Добавлено (05.07.2015, 23:17)
---------------------------------------------
А вообще, если заморачиваться оптимизацией, лучше писать на ассемблере, там программист царь, а не премьер-министр (тоже начальство, но могут и послать biggrin ).

Вс, 05.07.2015, 22:21 | Сообщение # 7        
adamchuk2012
аватар
  Постов: 14   ОК 
msmmmm, а с кодом мне помочь разобраться могёте?
я вам тож как нить помогу...
Вс, 05.07.2015, 22:27 | Сообщение # 8        
msmmmm2
аватар
  Постов: 166   ОК 
Если поклонники атмел не отзовутся - помогу. Но, я больше по пикам выступаю biggrin .
С - почти тот же, но архитектура разная. Иногда играюсь...
Вс, 05.07.2015, 22:34 | Сообщение # 9        
adamchuk2012
аватар
  Постов: 14   ОК 
не отзываются.пока.
а времени маловато. штуковина нужная должна получиться.
Вс, 05.07.2015, 22:50 | Сообщение # 10        
Витинари
аватар
  Постов: 1503   Друзья 
msmmmm, а вот с условиями, особенно если ветвлений много, оптимизатор такое может накрутить, что мало не покажется.
И я уже писал как-то, что CCS вытворяет с оператором "/" - около 400 байт на одно только деление! Для 628a это аж 20% памяти. Та же функция, написанная вручную, занимает всего 40 Б.

adamchuk2012, на пике оно бы проще вышло. И дешевле в разы - какой-нить 629-й преспокойно справился бы с такой задачей.
Вс, 05.07.2015, 22:55 | Сообщение # 11        
adamchuk2012
аватар
  Постов: 14   ОК 
ребят. я впервые сел за это дело. пожалуйста помогите разобраться. у меня нет возможности на пике делать. их после осваивать буду. я заплатить готов
Пн, 06.07.2015, 11:04 | Сообщение # 12        
msmmmm2
аватар
  Постов: 166   ОК 
if (PINC&(1<<PC1))
{
выполняется, если на PC1 - "1"
}

Да и зачем так сложно, если пины не перебираются - задай условие железно
if (PC1==0){} или if (PC1!=0){} смотри, что у тебя по логике.

Помнишь анекдот про еврея, который просил у бога выигрыша в лотерею, а билетик не покупал? Ты выложи задачу так: входы - нога такая-то это датчик ВУ, наличие воды - "1"; выходы - нога такая-то, уровень "1" - вкл. Условие (пример): пока воды нет, нагрев не включать; если НУ = 1, вкл нагрев и контролировать НУ (для аварийного отключения) и ВУ. Если ВУ = 1, откл нагрев, вкл пищалку на 10с, ....

Если так поставишь задачу, то сам все и сделаешь, да и помогут быстрее, потому что будет понятно, чего хочешь. Это называется "составление математической модели" - 90% работы программиста. Закодить правильно поставленную задачу - легко решаемая задача даже для неопытных.
Пн, 06.07.2015, 17:30 | Сообщение # 13        
adamchuk2012
аватар
  Постов: 14   ОК 
ага. ну давайте попробуем. PC0- датчик верхнего уровня, PC1- датчик нижнего уровня, PB1- НАГРЕВ, PB2- ЗВУК, PB3- СБРОС ПАРА, PB4- ДОЛИВ ВОДЫ.
Логика. если PC0=0 и PC1=0 то- нагрев воды( PB1=1, PB2=0, PB3=0, PB4=0)
PC0=1 и PC1=0 то- нагрев воды( PB1=1, PB2=0, PB3=0, PB4=0)
PC0=1 и PC1=1 то- отключить нагрев воды -(PB1=0), пописчать- PB2=1 10 сек, сбросить пар PB3=1 минуту, сбрасывать пар и доливать воду PB3=1 PB4=1 пока оба датчика вода заполнит оба датчика PC0=0 и PC1=0, и после опять включить нагрев PB1=1. Вот собственно и всё. и как раз проблема с последним.
мои циклы глючат когда я задаю им к проверке оба датчика. то есть прекратить лить воду тогда когда и первый второй в воде.

Добавлено (06.07.2015, 18:30)
---------------------------------------------
забыл добавить. 1 на датчиках- воды нет. 0 на датчиках- вода есть.

Пн, 06.07.2015, 20:51 | Сообщение # 14        
msmmmm2
аватар
  Постов: 166   ОК 
Попробуй так, писал в текстовом редакторе, не тестил:

#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRB = 0xFF;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xFF;
while(1)
{
switch (PINC & 3)
{
case 0: PORTB = 0b00000010;break; //PB1=1
case 1: PORTB = 0b00000010;break; //PB1=1
case 2: PORTB = 0b00000000;break; // неисправность: НУ нет, ВУ - есть, все откл
case 3:
{PORTB = 0b00000100 ; // выключаю нагрев, пищу 10 сек PB2=1
_delay_ms(10000) ; // 10c
PORTB = 0b00001000; // прекратил пищать включил сброс пара PB3=1
_delay_ms(60000); // 60c
PORTB = 0b00011000; // PB3=1 PB4=1
while ((PINC & 3) != 0){}; // пока оба входа не =0 стоим, тупим
};
}
}
}
Пн, 06.07.2015, 23:37 | Сообщение # 15        
djsanya123
аватар
  Постов: 1072   Друзья 
adamchuk2012, нарисуй схемку, напишу код
Вт, 07.07.2015, 18:29 | Сообщение # 16        
msmmmm2
аватар
  Постов: 166   ОК 
Все, код в сообщении #14 подправил, в протеусе работает.
Форум радиолюбителей » СХЕМЫ » МИКРОСХЕМЫ » Помогите с кодом на C
  • Страница 1 из 1
  • 1
Поиск:

Внимание! Форум переехал на Tehnodium.ru



© 2010-2022 "Радиосхемы". All Rights Reserved  Почта  PDA