PIC12F675 помогите разобраться с программированием

Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

Alexandr617 писал(а):

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

for(i=0; i<8; i++) {
[...]
}
Я уже понял для чего это впихнули, это пустой цикл для задержки.

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

	[b]for (k=0; k<45000; k++);//"пустой" цикл для временной задержки[/b]
С пониманием разочарую - в оригинале у вас не пустой цикл - а именно исполнение по восемь раз тела цикла for, который, в свою очередь, сидит в бесконечном цикле while(1). В итоге имеем, что тело исполняется бесконечно хотя и типа "порциями по 8" - конструкция в данном конкретном случае бессмысленная. Пример-же которым вы аппелируете имеет одну маленькую деталь которая меняет дело весьма радикально - у этого for тело цикла пустое - и пока оно не исполнится сорок пять тысяч раз - на следующую строчку управление не перейдёт.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2042
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Сообщение botchin »

Siarzhuk, а мне кажется что ета конструкция имеет вполне яснъй смисл:

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


 TRISA = 0b00010000;//Направление работы ножек порта А.

 while(1)//Бесконечный цикл.
  for(i=0; i<8; i++)
   {
    PORTA=i;
    Delay_ms(500);
   }
Если принять TRISA = TRISIO и PORTA = CPIO - ета ошибка Alexandr617 уже понял
то въше приведеннъй код я понимаю так:

Определит CPIO0-GPIO3 Как въходъ
Въполнят всегда следующее:
Въвести на въходе с задержкой 500мс числа с 0 до 7 в HEX системе счисления

Так, что по моему, вполне смъсленная порция кода.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

botchin писал(а):Так, что по моему, вполне смъсленная порция кода.
Да, Вы правы! Слона (использование i) в цикле то я и упустил. Спасибо за поправку. Посыпаюсь пеплом по самую макушку.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Родился
Сообщения: 14
Зарегистрирован: Сб июн 27, 2015 01:08:06

Сообщение Alexandr617 »

botchin писал(а):Поставил себе HI-TECH C Compiler for PIC10/12/16 MCUs (PRO Mode) V9.71a

обе функции не трябуют #include <htc.h>
функция _delay(unsigned long ); проходит

функция __delay_us(unsigned long ); проходит требует #define _XTAL_FREQ 4000000
функция __delay_ms(unsigned long ); проходит требует #define _XTAL_FREQ 4000000

Заметь _delay() с один прочеркон, а __delay_us() i __delay_ms() с два прочеркa
Alexandr617 писал(а):Я так понял что не все компиляторы имеют delay
Я это сообщение заметил и внимательно прочитал :)

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

#include <pic.h>


#define _XTAL_FREQ 4000000

void main(void)
{
	while(1)
		_delay(100);
		__delay_us(100);
		__delay_ms(100);
}
Вот ето компилируется на все сто - HI-TECH C Compiler V9.71a
У меня HI-TECH C Compiler V9.60, и это не компилируется(__delay_ms(__два), _delay_ms(_один), delay_ms(_без), DelayMs) компилятор выдаёт выше перечисленные ошибки.
Кстати у етого компилятора в среде MPLAB довольно хорошии HELP на 344 страниц. Откръвается с Project/Hi-TECH C Manual F11
У меня он с MPLAB не открывается, выдаёт:
Ошибка формата: не PDF или файл повреждён
В язъках типа С функции бъвают встроеннъе и библиотечнъе. Delay встроенная - компилятор вставляет ее при нужде,
В даном случае она не была встроенной.
Долго лазал в интернете и наткнулся на один форум: http://forum.cxem.net/index.php?showtopic=34760
там человек выложил архив с библиотеками:
Вот задержки, работают с любым кварцем.delay routines
Изменено: Andrey_Ch8, 10 Июнь 2011 - 12:48
Содержимое архива кинул в:
X:/Program Files/HI-TECH Software/PICC/lite/9.60/include
(Здесь находятся библиокеки по всем МК(или можно сказать не библиотеки, а инструкции. Библиотеки имеют расширение *.dll))
В коде я дописал(я проверял, без тех файлов это не проходило):

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

#include <delay.c>
И задержка стала работать:

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

GPIO2 = 1;
DelayMs(500);
GPIO2 = 0;
DelayMs(500);
Только видите, здесь надо писать DelayS(), DelayMs(), DelayUs().
Siarzhuk писал(а):...у этого for тело цикла пустое - и пока оно не исполнится сорок пять тысяч раз - на следующую строчку управление не перейдёт.
Вот поэтому он и называется "пустым"(Точность такой задержки равна 0) М... В моём первом посте, тело цикла действительно не пустое, тот пример я брал с другого источника.
Здесь я уже с помощью Вас разобрался, осталось разобраться только в этом:

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

#include <pic.h>
//PIC12F675
#include <htc.h>
#include <delay.c>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000
#endif

#define diod1 GPIO0 //Светодиод #1.
#define diod2 GPIO1 //Светодиод #2.
#define diod3 GPIO2 //Светодиод #3(Вкл. при нажатии кнопки #2).
#define knopka1 GPIO5 //Кнопка #1.
#define knopka2 GPIO3 //Кнопка #2.

__CONFIG (INTIO & UNPROTECT & BOREN & MCLRDIS & PWRTEN & WDTDIS);

unsigned int i;

 void ZX1(void)      //Подготовка МК.
  {
   TRISIO =0b111000; //Направление работы ножек порта(1-вход, 0-выход)
   CMCON = 0x07;     //Отключение компараторов.
   GPIO = 0b000000;  //Очищаем порт.
   WPU5 = 1;         //Подтягивающий резистор(1-вкл., 0-откл.).
  }

//Начало программы.
void main(void)
 {
   ZX1();            //Вызов функции подготовки МК.
    while(1)         //Бесконечный цикл.
      {
        if(knopka1=1)          //Если кнопка нажата(вторая нога МК).
           {
             diod1 = 1;        //Включить светодиод #1.
             DelayMs(10);      //Задержка 0,01сек.
             diod2 = 0;        //Выключить светодиод #2.
           }
          else                 //Если кнопка не нажата.
           {
             diod1 = 0;        //Выключить светодиод #1.
             diod2 = 1;        //Включить светодиод #2.
             DelayMs(10);      //Задержка 0,01сек.
           }
        if(knopka2=1)          //Если кнопка нажата.
           {
             diod3 = 1;        //Включить светодиод #3.
           }
          else                 //Если кнопка не нажата.
           {
             diod3 = 0;        //Выключить светодиод #3.
           }
//       DelayMs(10);       //Задержка 0,01сек.
      }
 }
1. Почему два оператора if в безконечном цикле while(1) вместе нормально не работают(Запускается только один из операторов, второго как будто и нет)?

2. Почему при удалении или перестановки в другое место задержек, в первом операторе, светодиоды не включаются в постоянную работу(Начинают моргать с огромной частотой, но переключаются стабильно)?

3. Почему при установке задержки в конце цикла while(1) начинают два оператора работать, но светодиоды в двух операторах моргают независимо от того как ты в них поставишь задержки?
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2042
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Сообщение botchin »

Про delay - примем что на насточщии етап проблем нет.
Alexandr617 писал(а): #define knopka2 GPIO3 //Кнопка #2.
.....
TRISIO =0b111000; //Направление работы ножек порта(1-вход, 0-выход)
Въ назначили GPIO3, но у нее нет подтяжка, Должно бъть какое-то сопротивление к +. Отсюда и глюки в теле цикла, особо во второй его части (второй if ())

Я бъ часть в while(1) сделал бъ так:

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

while(1)
{	diod1 = knopka1;     //или вкл или въкл. в зависимости от кнопка1
	diod2 = !diod1;        //обратное на диод1

	diod3 = knopka2;     //или вкл или въкл. в зависимости от кнопка2
        DelayMs(10);           //всегда въполняется

}
if-ъ по моему всегда въполняются, только въ не успеваете отметит, что они въполняются. Пока не будем говорить про дребезга кнопки.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

Alexandr617 писал(а): [...]
if(knopka1=1) //Если кнопка нажата(вторая нога МК).
[...]
if(knopka2=1) //Если кнопка нажата.
[...]
А компилятор вас не предупреждает в этих местах о подозрительном присваивании? ЕМНИП результатом операции присваивания будет 1 - т.е. под обе ветки управление будет заходить на каждой итерации. Оператор сравнения в С выглядит по-другому. ;)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2042
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Сообщение botchin »

Абсолютно верно!!!!

Явно то что с 85-89 года не работал на С сказъвается.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Родился
Сообщения: 14
Зарегистрирован: Сб июн 27, 2015 01:08:06

Сообщение Alexandr617 »

botchin писал(а):Про delay - примем что на насточщии етап проблем нет.
Так точно! Здесь проблем уже нет! :))
Alexandr617 писал(а): #define knopka2 GPIO3 //Кнопка #2.
.....
TRISIO =0b111000; //Направление работы ножек порта(1-вход, 0-выход)
Въ назначили GPIO3, но у нее нет подтяжка, Должно бъть какое-то сопротивление к +. Отсюда и глюки в теле цикла, особо во второй его части (второй if ())
Для начала, я решил перекинуть вторую кнопку на GPIO4 и включил подтягивающий резистор:

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

 #define knopka2 GPIO4 //Кнопка #2.
          ,,,,,,,,,,,,,,,
TRISIO =0b111000; //Направление работы ножек порта(1-вход, 0-выход)
          ,,,,,,,,,,,,,,,
   WPU4 = 1;         //Подтягивающий резистор(1-вкл., 0-откл.).
Подтягивающий резистор не помог, проблема осталась та же.
Я бъ часть в while(1) сделал бъ так:

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

while(1)
{	diod1 = knopka1;     //или вкл или въкл. в зависимости от кнопка1
	diod2 = !diod1;        //обратное на диод1

	diod3 = knopka2;     //или вкл или въкл. в зависимости от кнопка2
        DelayMs(10);           //всегда въполняется

}
Потом я решил постепенно ставить код как Вы предложили. Для начала я убрал второй оператор:

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

//Начало программы.
void main(void)
 {
   ZX1();           //Вызов функции подготовки МК.
    while(1)        //Бесконечный цикл.
      {
       diod3 = knopka2;
        if(knopka1==1) //Если кнопка нажата(вторая нога МК).
           {
             diod1 = 1;       //Включить светодиод #1.
             DelayMs(10);     //Задержка 0,01сек.
             diod2 = 0;       //Выключить светодиод #2.
           }
          else      //Если кнопка не нажата.
           {
             diod1 = 0;        //Выключить светодиод #1.
             diod2 = 1;        //Включить светодиод #2.
             DelayMs(10);      //Задержка 0,01сек.
           }

//     diod3 = knopka2; //Светодиод #3 вкл. при нажатии кнопки #2.
//     DelayMs(10);      //Задержка 0,01сек.
      }
 } 
Знаете, что интересно? Также светодиод №3 не включается, хоть ставь diod3 = knopka2; после первого оператора или до него, с задержкой или без, ничего не изменяется.
Потом полностью собрал как Вы предложили, всё откомпилировалось но и при этом всё перестало работать:

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

//Начало программы.
void main(void)
 {
   ZX1();           //Вызов функции подготовки МК.
    while(1)        //Бесконечный цикл.
      {
        diod1 = knopka1; //Светодиод #1 вкл. если кнопка #1 нажата(вторая нога МК).
//      DelayMs(10);     //Задержка 0,01сек.
        diod2 = !diod1;  //Обратное на светодиод #1.
//      DelayMs(10);     //Задержка 0,01сек.
        diod3 = knopka2; //Светодиод #3 вкл. при нажатии кнопка #2.
//      DelayMs(10);     //Задержка 0,01сек.
      }
 }
Если ставлю задержку после diod3 = knopka2; ничего не работает, если после diod2 = !diod1; напряжение идёт с GPIO1 то есть включается второй диод и постоянно горит, при этом на кнопки не реагирует. Если ставим задержку после diod1 = knopka1; стабильно включается и выключается первый диод , второй и третий молчат и не реагируют на кнопки.
Без задержек начинается светомузыка :) вовсю моргает второй светодиод, а при нажатии на первую кнопку к нему подключается, и первый светодиод и они поочерёдно начинают моргать. При этом третий светодиод не реагирует на кнопки, я думал может я где-то что-то напортачил в «Подготовка МК» или в макросе. Решил для теста выставить (GPIO = 0b000100;) чтобы подать с GPIO2 напряжение на светодиод, но он так и не загорелся.
if-ъ по моему всегда въполняются, только въ не успеваете отметит, что они въполняются.
Мне кажется это маловероятно, ибо "подготовка МК" вынесена за пределы бесконечного цикла. Значит порт не должен сбрасываться, а при нажатии на кнопку светодиод включается и пока не отпустишь кнопку светодиод не выключится. Потому что мы в GPIO2 записуем "1" и пока мы не отпустим кнопку GPIO2 не может измениться на "0". А я могу держать кнопку, сколько захочу, я бы в любом случае увидел, что светодиод загорелся.
Пока не будем говорить про дребезга кнопки.
Можно поподробнее?
Siarzhuk писал(а):
Alexandr617 писал(а):[...]
if(knopka1=1) //Если кнопка нажата(вторая нога МК).
[...]
if(knopka2=1) //Если кнопка нажата.
[...]
А компилятор вас не предупреждает в этих местах о подозрительном присваивании?
Та нет, не предупреждает, молчит как партизан! :)
ЕМНИП результатом операции присваивания будет 1 - т.е. под обе ветки управление будет заходить на каждой итерации. Оператор сравнения в С выглядит по-другому.
Раньше работал с паскалем, а Си довольно похож(по крайней мере я глобальной разницы еще не увидел) Кроме "Begin" и "End" хочется как раньше поставить в место "{" и "}"! :)) Оператор сравнения в паскале просто «=», а в Си «==»(если равенство) и отличие в неравенстве в Си «!=», а в паскале «<>». Остальные операторы сравнения вроде такие же.
В Си работаю меньше недели, пока привыкнешь...

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

[...]
 if(knopka1==1) //Если кнопка нажата(вторая нога МК).
[...]
 if(knopka2==1) //Если кнопка нажата.
[...]
Так лучше? :)) Блин, но всё равно также всё и осталось, светомузыка по первому оператору, а второй не работает! :(

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

//Начало программы.
void main(void)
 {
   ZX1();           //Вызов функции подготовки МК.
    while(1)        //Бесконечный цикл.
      {
        if(knopka1==1) //Если кнопка нажата(вторая нога МК).
           {
             diod1 = 1;       //Включить светодиод #1.
             DelayMs(10);     //Задержка 0,01сек.
             diod2 = 0;       //Выключить светодиод #2.
           }
          else      //Если кнопка не нажата.
           {
             diod1 = 0;        //Выключить светодиод #1.
             diod2 = 1;        //Включить светодиод #2.
             DelayMs(10);      //Задержка 0,01сек.
           }
        if(knopka2==1) //Если кнопка нажата(Третья нога МК(GPIO4)).
           {
             diod3 = 0;
//             diod3 = 1;       //Включить светодиод #3.
//             DelayMs(10);     //Задержка 0,01сек.
           }
          else      //Если кнопка не нажата.
           {
             diod3 = 1;
//             diod3 = 0;        //Выключить светодиод #3.
//             DelayMs(10);      //Задержка 0,01сек.
           }

//     diod3 = knopka2; //Светодиод #3 вкл. при нажатии кнопки #2.
//     DelayMs(10);      //Задержка 0,01сек.
      }
}
Интересное наблюдение! Как я раньше говорил без задержек во втором операторе и в конце бесконечного цикла, первый оператор работает стабильно, без светомузыки всё переключается как надо, а второй оператор не работает! (Это было предисловие к рассказу о своём наблюдении! :) ) Так вот, если поставить задержку во втором операторе для выполнения действия при неверном условии после diod3 = 0;, первый оператор это чувствует и светодиоды начинают моргать (при этом всё стабильно переключается!). Я вот и подумал, а второй оператор вообще выполняет действия при неверном условии?! Вот я и решил поставить светодиод на включение при отжатой кнопке #2! Но он не включился, хоть нажимай, хоть не нажимай кнопки, второй оператор молчит.
Есть еще одно наблюдение! Если задержку поставить перед diod3 = 1; во втором операторе (в не верном условии), то при отжатой кнопке №1 светодиод №2 горит постоянно (как и должно быть), НО при нажатии кнопки №1 светодиод №1 моргает!

Почему происходит такой цирк?! Может дело не в операторах, а в конфигурации МК? Можете посмотреть верно я там всё поставил?

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

__CONFIG (INTIO & UNPROTECT & BOREN & MCLRDIS & PWRTEN & WDTDIS);
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

Alexandr617 писал(а):Та нет, не предупреждает, молчит как партизан! :)
В печь его. ©
Alexandr617 писал(а):

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

[...]
 if(knopka1==1) //Если кнопка нажата(вторая нога МК).
[...]
 if(knopka2==1) //Если кнопка нажата.
[...]
Так лучше? :)) Блин, но всё равно также всё и осталось, светомузыка по первому оператору, а второй не работает! :(
Согласно классиков - "читать чужой исходник - это тяжкий труд" © ARV - а тут предлагается собрать паззл из кусков непонятной степени актуальности, размазанных по теме - малоприятное упражнение, согласитесь. Может имеет смысл актуальный С-ишник приаттачивать, или выкладывать где-нибудь? А кнопки у вас на размыкание работают?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Друг Кота
Аватара пользователя
Сообщения: 25613
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

Читать с начала очень лениво... Но есть смутное подозрение, что аффтар пал смертью храбрых на полях борьбы с RMW...
Побитный вывод в порты младших ПИКов вещь весьма рискованная, поскольку помимо целевого бита происходит ПЕРЕЗАПИСЬ ВСЕХ ОСТАЛЬНЫХ с ПИНА в защелку ВЫХОДА...
:tea:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2042
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Сообщение botchin »

Сегодня я опять вспомнил почену стал работать на ASM-е.

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

   TRISIO =0b00111111; //Направление работы ножек порта(1-вход, 0-выход)
Вот ето ставить в TRISIO только 0x0F. два старших бита (4и 5) никак нельзя определить как входъ. Пробовал и на ASM

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

	#asm
	BSF 0x03,5      ;status, rp0
	CLRF 0x9f        ;ANSEL
	movlw 3fh
	MOVWF 0x85,f  ;TRISIO
	bsf	0x85,4     ;TRISIO,4
	bsf	0x85,5     ;TRISIO,5

	BCF 0x03,5      ;STATUS,RP0
	#endasm
- тоже самое.
Пробовал и с дригим контролерем - резултать такой же.

Можеть бъть Hi-TECH не поставлен как надо или еще что-то.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Спойлер
botchin писал(а):Про delay - примем что на насточщии етап проблем нет.
Так точно! Здесь проблем уже нет! :))
Alexandr617 писал(а): #define knopka2 GPIO3 //Кнопка #2.
.....
TRISIO =0b111000; //Направление работы ножек порта(1-вход, 0-выход)
Въ назначили GPIO3, но у нее нет подтяжка, Должно бъть какое-то сопротивление к +. Отсюда и глюки в теле цикла, особо во второй его части (второй if ())
Для начала, я решил перекинуть вторую кнопку на GPIO4 и включил подтягивающий резистор:

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

 #define knopka2 GPIO4 //Кнопка #2.
          ,,,,,,,,,,,,,,,
TRISIO =0b111000; //Направление работы ножек порта(1-вход, 0-выход)
          ,,,,,,,,,,,,,,,
   WPU4 = 1;         //Подтягивающий резистор(1-вкл., 0-откл.).
Подтягивающий резистор не помог, проблема осталась та же.
Я бъ часть в while(1) сделал бъ так:

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

while(1)
{	diod1 = knopka1;     //или вкл или въкл. в зависимости от кнопка1
	diod2 = !diod1;        //обратное на диод1

	diod3 = knopka2;     //или вкл или въкл. в зависимости от кнопка2
        DelayMs(10);           //всегда въполняется

}
Потом я решил постепенно ставить код как Вы предложили. Для начала я убрал второй оператор:

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

//Начало программы.
void main(void)
 {
   ZX1();           //Вызов функции подготовки МК.
    while(1)        //Бесконечный цикл.
      {
       diod3 = knopka2;
        if(knopka1==1) //Если кнопка нажата(вторая нога МК).
           {
             diod1 = 1;       //Включить светодиод #1.
             DelayMs(10);     //Задержка 0,01сек.
             diod2 = 0;       //Выключить светодиод #2.
           }
          else      //Если кнопка не нажата.
           {
             diod1 = 0;        //Выключить светодиод #1.
             diod2 = 1;        //Включить светодиод #2.
             DelayMs(10);      //Задержка 0,01сек.
           }

//     diod3 = knopka2; //Светодиод #3 вкл. при нажатии кнопки #2.
//     DelayMs(10);      //Задержка 0,01сек.
      }
 } 
Знаете, что интересно? Также светодиод №3 не включается, хоть ставь diod3 = knopka2; после первого оператора или до него, с задержкой или без, ничего не изменяется.
Потом полностью собрал как Вы предложили, всё откомпилировалось но и при этом всё перестало работать:

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

//Начало программы.
void main(void)
 {
   ZX1();           //Вызов функции подготовки МК.
    while(1)        //Бесконечный цикл.
      {
        diod1 = knopka1; //Светодиод #1 вкл. если кнопка #1 нажата(вторая нога МК).
//      DelayMs(10);     //Задержка 0,01сек.
        diod2 = !diod1;  //Обратное на светодиод #1.
//      DelayMs(10);     //Задержка 0,01сек.
        diod3 = knopka2; //Светодиод #3 вкл. при нажатии кнопка #2.
//      DelayMs(10);     //Задержка 0,01сек.
      }
 }
Если ставлю задержку после diod3 = knopka2; ничего не работает, если после diod2 = !diod1; напряжение идёт с GPIO1 то есть включается второй диод и постоянно горит, при этом на кнопки не реагирует. Если ставим задержку после diod1 = knopka1; стабильно включается и выключается первый диод , второй и третий молчат и не реагируют на кнопки.
Без задержек начинается светомузыка :) вовсю моргает второй светодиод, а при нажатии на первую кнопку к нему подключается, и первый светодиод и они поочерёдно начинают моргать. При этом третий светодиод не реагирует на кнопки, я думал может я где-то что-то напортачил в «Подготовка МК» или в макросе. Решил для теста выставить (GPIO = 0b000100;) чтобы подать с GPIO2 напряжение на светодиод, но он так и не загорелся.
if-ъ по моему всегда въполняются, только въ не успеваете отметит, что они въполняются.
Мне кажется это маловероятно, ибо "подготовка МК" вынесена за пределы бесконечного цикла. Значит порт не должен сбрасываться, а при нажатии на кнопку светодиод включается и пока не отпустишь кнопку светодиод не выключится. Потому что мы в GPIO2 записуем "1" и пока мы не отпустим кнопку GPIO2 не может измениться на "0". А я могу держать кнопку, сколько захочу, я бы в любом случае увидел, что светодиод загорелся.
Пока не будем говорить про дребезга кнопки.
Можно поподробнее?
Siarzhuk писал(а):
Alexandr617 писал(а):[...]
if(knopka1=1) //Если кнопка нажата(вторая нога МК).
[...]
if(knopka2=1) //Если кнопка нажата.
[...]
А компилятор вас не предупреждает в этих местах о подозрительном присваивании?
Та нет, не предупреждает, молчит как партизан! :)
ЕМНИП результатом операции присваивания будет 1 - т.е. под обе ветки управление будет заходить на каждой итерации. Оператор сравнения в С выглядит по-другому.
Раньше работал с паскалем, а Си довольно похож(по крайней мере я глобальной разницы еще не увидел) Кроме "Begin" и "End" хочется как раньше поставить в место "{" и "}"! :)) Оператор сравнения в паскале просто «=», а в Си «==»(если равенство) и отличие в неравенстве в Си «!=», а в паскале «<>». Остальные операторы сравнения вроде такие же.
В Си работаю меньше недели, пока привыкнешь...

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

[...]
 if(knopka1==1) //Если кнопка нажата(вторая нога МК).
[...]
 if(knopka2==1) //Если кнопка нажата.
[...]
Так лучше? :)) Блин, но всё равно также всё и осталось, светомузыка по первому оператору, а второй не работает! :(

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

//Начало программы.
void main(void)
 {
   ZX1();           //Вызов функции подготовки МК.
    while(1)        //Бесконечный цикл.
      {
        if(knopka1==1) //Если кнопка нажата(вторая нога МК).
           {
             diod1 = 1;       //Включить светодиод #1.
             DelayMs(10);     //Задержка 0,01сек.
             diod2 = 0;       //Выключить светодиод #2.
           }
          else      //Если кнопка не нажата.
           {
             diod1 = 0;        //Выключить светодиод #1.
             diod2 = 1;        //Включить светодиод #2.
             DelayMs(10);      //Задержка 0,01сек.
           }
        if(knopka2==1) //Если кнопка нажата(Третья нога МК(GPIO4)).
           {
             diod3 = 0;
//             diod3 = 1;       //Включить светодиод #3.
//             DelayMs(10);     //Задержка 0,01сек.
           }
          else      //Если кнопка не нажата.
           {
             diod3 = 1;
//             diod3 = 0;        //Выключить светодиод #3.
//             DelayMs(10);      //Задержка 0,01сек.
           }

//     diod3 = knopka2; //Светодиод #3 вкл. при нажатии кнопки #2.
//     DelayMs(10);      //Задержка 0,01сек.
      }
}
Интересное наблюдение! Как я раньше говорил без задержек во втором операторе и в конце бесконечного цикла, первый оператор работает стабильно, без светомузыки всё переключается как надо, а второй оператор не работает! (Это было предисловие к рассказу о своём наблюдении! :) ) Так вот, если поставить задержку во втором операторе для выполнения действия при неверном условии после diod3 = 0;, первый оператор это чувствует и светодиоды начинают моргать (при этом всё стабильно переключается!). Я вот и подумал, а второй оператор вообще выполняет действия при неверном условии?! Вот я и решил поставить светодиод на включение при отжатой кнопке #2! Но он не включился, хоть нажимай, хоть не нажимай кнопки, второй оператор молчит.
Есть еще одно наблюдение! Если задержку поставить перед diod3 = 1; во втором операторе (в не верном условии), то при отжатой кнопке №1 светодиод №2 горит постоянно (как и должно быть), НО при нажатии кнопки №1 светодиод №1 моргает!

Почему происходит такой цирк?! Может дело не в операторах, а в конфигурации МК? Можете посмотреть верно я там всё поставил?

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

__CONFIG (INTIO & UNPROTECT & BOREN & MCLRDIS & PWRTEN & WDTDIS);
Опять методы тыка :facepalm: Они не прокатывают в программировании.
Нужно чётко знать что ты делаешь и пишешь. Иначе успеха не видать...
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2042
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Сообщение botchin »

После переинсталяции - работает. Плохо, что не помню откуда скачал Hi-TECH-a. Сейчась скачал с ftp://ftp.microchip.com/
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Родился
Сообщения: 14
Зарегистрирован: Сб июн 27, 2015 01:08:06

Сообщение Alexandr617 »

Использовал код как посоветовал уважаемый товарищ botchin (с мелкими поправками).
После долгого изучения даташита, я разобрался, из-за чего не работал второй оператор в моём варианте и вторая кнопка в варианте botchin. Всё дело в настройке аналогового входа и:
КРАМ писал(а):... помимо целевого бита происходит ПЕРЕЗАПИСЬ ВСЕХ ОСТАЛЬНЫХ с ПИНА в защелку ВЫХОДА...
регистр TRIS управляет направлением данных на выводе. Если бит TRIS установлен в «1» (напоминает In — вход), то соответствующий канал порта ввода/вывода работает как вход, а если бит TRIS сброшен в «0» (напоминает Out — выход), то соответствующий канал порта ввода/вывода работает как выход.
-- регистр PORT — защелка данных выводимых на порт ввода/вывода;
-- при чтении регистра PORT возвращается состояние ВЫВОДОВ порта;
-- при записи в регистр PORT производится запись в ЗАЩЕЛКИ;
изменение состояния порта производится по принципу «чтение-модификация-запись». Даже при изменении состояния одного вывода операция «чтение-модификация-запись» производится над всем портом.

Источник: http://picdevices.ru/eksperimentyi/osto ... helki.html

Получается, если я правильно понял, когда я что-то включал/выключал я весь порт (GPIO) сбрасывал в «0», вот и получалась светомузыка.
Сейчас всё стабильно переключается и включается без светомузыки.

Вот текущий актуальный код:
Спойлер

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

#include <pic.h>
//PIC12F675
#include <htc.h>
#include <delay.c>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000
#endif
#define diod1 TRIS0 //Светодиод #1.
#define diod2 TRIS1 //Светодиод #2.
#define diod3 TRIS2 //Светодиод #3(Вкл. при нажатии кнопки #2).
#define knopka1 GPIO5 //Кнопка #1.
#define knopka2 GPIO4 //Кнопка #2.
__CONFIG (INTIO & UNPROTECT & BOREN & MCLRDIS & PWRTEN & WDTDIS);

 void ZX1(void)      //Подготовка МК.
  {
   TRISIO = 0b111000;//Направление работы ножек порта(1-вход, 0-выход).
   CMCON = 0x07;     //Отключение компараторов.
   GPIO = 0b000111;  //Очищаем порт(0-приём напряж., 1-подача напряж.).
   WPU4 = 1;         //Подтягивающий резистор(1-вкл., 0-откл.).
   WPU5 = 1;         //Подтягивающий резистор(1-вкл., 0-откл.).
   ANSEL = 0b000101; //Настройка аналогового входа.
  }
void main(void)//Начало программы.
 {
   ZX1();      //Вызов функции подготовки МК.
   while(1)    //Бесконечный цикл.
     {
       diod1 =! knopka1; //Светодиод #1 вкл. при нажатии кнопки #1.
       diod2 =! diod1;   //Светодиод #2 вкл при отключении светодиода #1.
       diod3 =! knopka2; //Светодиод #3 вкл. при нажатии кнопки #2.
       DelayMs(10);      //Задержка 0,010 сек.
     }
}
Аlex писал(а):Опять методы тыка Они не прокатывают в программировании.
Нужно чётко знать что ты делаешь и пишешь. Иначе успеха не видать...
Я с Вами полностью согласен! Ибо сам программировал приложения для ПК, просто здесь заметил не понятное изменение в поведения МК при перестановках задержек. Вот начался метод тыка.
КРАМ писал(а):Читать с начала очень лениво...
Понимаю, но я пытаюсь подробно изложить все текущие проблемы и подробно описать всю проделанную работу.
botchin писал(а):Вот ето ставить в TRISIO только 0x0F. два старших бита (4и 5) никак нельзя определить как входъ. Пробовал и на ASM
В данный момент вроде бы они нормально вдвоём работают на вход.

Хотелось бы, чтобы Вы как опытные и знающиеся в этом деле люди, посмотрели и сказали правильно ли в исходнике всё организованно.


Теперь я буду внимательно изучать даташиты к МК, ибо без них никак…

P.S. после изменения GPIO(0,1,2) на TRIS(0,1,2), вторая и третья нога МК(GPIO5 и GPIO4) стали очень чувствительные(срабатывали на палец находящийся в 5-ти миллиметрах от них). При этом нормально не осуществлялось переключение светодиодов и включение соответственно, пришли на помощь два резистора по 10КОм. Установлены со второй на восьмую и с третьей на восьмую ногу МК, после этого всё стало стабильно переключаться и включаться.
В архиве исходник, проект Proteus-a 7 и hex.
Вложения
2015-07-04_010355.jpg
(138.07 КБ) 543 скачивания
2015-07-04_010344.jpg
(138.18 КБ) 538 скачиваний
2015-07-04_010331.jpg
(137.67 КБ) 547 скачиваний
2015-07-04_010412.jpg
(133.7 КБ) 411 скачиваний
Led_ON.rar
(403.04 КБ) 192 скачивания
Друг Кота
Аватара пользователя
Сообщения: 25613
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

Alexandr617 писал(а):
КРАМ писал(а):Читать с начала очень лениво...
Понимаю, но я пытаюсь подробно изложить все текущие проблемы и подробно описать всю проделанную работу.


Хотелось бы, чтобы Вы как опытные и знающиеся в этом деле люди, посмотрели и сказали правильно ли в исходнике всё организованно.


Теперь я буду внимательно изучать даташиты к МК, ибо без них никак…
Не сочтите за нравоучения, уважаемый, - чисто мнение.
Моя фраза про лень на самом деле является эвфемизмом. Так обычно говорят, когда написано много, сумбурно и без попытки ОСМЫСЛИТЬ ПРОБЛЕМУ.
Но Бог с ней, с попыткой. Мой совет носит только практический, рациональный характер.
Если Вы желаете получить помощь, то нужно так подготовить текст вопроса, чтобы те, кто МОГУТ Вам помочь, НАШЛИ ТО, ЧТО ВАМ ПОМОЖЕТ в течении времени, которым эти люди располагают.
Для этого нужно не писать все подряд, думая, что это облегчит им задачу, а САМОСТОЯТЕЛЬНО СТРУКТУРИРОВАТЬ ПРОБЛЕМЫ.
Разделить их на части и КОНСПЕКТИВНО, ПО ПУНКТАМ изложить.
Есть такое обоснованное мнение, что в 80% случаев такая работа по подготовке вопроса:
1. даст ответ на этот вопрос
2. позволит понять ответ, который Вам дадут.
Еще раз извините за моралите, надеюсь, Вы меня поняли правильно.
Родился
Сообщения: 14
Зарегистрирован: Сб июн 27, 2015 01:08:06

Сообщение Alexandr617 »

Уважаемый КРАМ, я Вас понял и приму выше сказанное к сведению.
Родился
Сообщения: 14
Зарегистрирован: Сб июн 27, 2015 01:08:06

Сообщение Alexandr617 »

Здравствуйте, уважаемые пользователи форума "РадиоКот“!

Вот у меня появился новый вопрос. Как организовать запись определённого десятичного числа в Flash или EEPROM память этого МК(с возможностью его считать) во время его работы?

В даташите пример на АСМ, но я так и не понял как это организовать на СИ.

Буду очень благодарен за помощ.
Друг Кота
Аватара пользователя
Сообщения: 25613
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

В десятичной форме число может быть записано только на бумаге, либо выведено на индикатор в той или иной графической форме.
Десятичное представление чисел подразумевает десять значений каждого разряда.
В память МК число можно записать либо в двоичной форме, либо двоично-десятичной. Последняя занимает 4 двоичных разряда на каждый представляемый десятичный разряд. То есть двухразрядное десятичное число будет занимать один байт (два 4-х разрядных ниббла).
Обычно во флеш двоично-десятичные числа не записывают, удобнее каждый раз при выводе на индикатор преобразовывать двоичную форму в двоично-десятичную, а все операции делать только в двоичной форме.
Родился
Сообщения: 14
Зарегистрирован: Сб июн 27, 2015 01:08:06

Сообщение Alexandr617 »

У меня есть числовое значение n, которое в зависимости от настройки МК равняется числу от 1-го до 6-ти. И это значение мне нужно сохранить в энергонезависимую память, чтобы настройки прибора при его вкл.\выкл. не сбивались.
В pic16... я так понял запись в EEPROM делается так:

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

EEprom_Write(i,i);//Запись в EEPROM.
,,,
EEPROM_Read(i);//Чтение с EEPROM.
А для этого МК я не могу понять как правильно записать значение в память. Что использовать EECON1, EEDATA, WR, RD, WREN, WRERR.

Не хватает литературы с доступным для понимания материалом(
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Alexandr617, поставьте XC8 компилятор, и половина вопросов и проблем исчезнут. На него, также, есть неплохая документация, устанавливающаяся в папку компилятора.
Ответить

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