Программирование PIC

Do you have a question? Post it now! No Registration Necessary

Threaded View
Hello Vadim.

14 Sep 03 16:36, you wrote to all:

 VT> Вроде разобрался с алгоритмом, однако не работает мой программатор...

Еще бы :)

 VT> LPT            К555ЛH2               PIC16F84
 VT>                 ___                ____________
 VT>       Data in  |   |              |   |   |    |
 VT> D0<-2--------1-|1  o-2-T-------13-|RB7|MCU|MCLRo-4-\
 VT>                |___|   |     /-12-|RB6|   |    |   |
 VT>                 ___    |    /     |   |   |    |   |
 VT>       Clock    |   |   |   /       ------------    |
 VT> D1<-3--------3-|1  o-4-)--/                        |
 VT>                |___|   |                           |
 VT>                        |                           |
 VT>                 ___    |                           |
 VT>                |   |   |                           |
 VT> ACK<-10-DOut-5-|1  o-6-/                           |
 VT>                |___|                               |
 VT>                                                    |
 VT>                 ___                                |
 VT>                |   |                               |
 VT> D3<-5--VProg-9-|1  o-8-\                           |
 VT>                |___|   | +12V                      |
 VT>                        |  /\   К555КТ3             |
 VT>                        |  |    ________            |
 VT>                        |  \-1-| |   | |-2----------/
 VT>                        |      | |_/_| |
 VT>                        \---13-|V|   | |
 VT>                               | |   | |
 VT>                                --------

1) Hа все выходы ЛH2 повесь pull-up резисторы (к +5в)
2) Инвертор, через который читаются данные в PC включен в другую сторону
   (ноги 5 и 6 ЛH2 поменяй местами)
3) Hа MCLR неплохо было бы повесить pull-down резистор, иначе PIC после
програмирования начнет исполнять программу (по крайней мере попытается), и как
он отнесется к тому, что у него на ногах весит программатор неизвестно.
4) И между прочим - ты не забыл подвести к PIC'у землю и +5в питания?

 VT> Вот сама программа:

Программа вообще шедевр :) Для первой программы на С неплохо, для любой
последующей - ужастно :(

 VT> #include <DOS.H>;
 VT> #include <stdio.h>;
 VT> #include <conio.h>;

это не надо

 VT> #include <math.h>;

это не надо

 VT> #include <string.h>;
 VT> #include <process.h>;

и это не надо

 VT> int Cent_Base=0;

 VT> int btfss(int value,int num){
 VT>    int a;
 VT>    for (a=0;a<num;a++)
 VT>       value>>=1;
 VT>    if (value%2!=0)
 VT>       return 1;
 VT>    else
 VT>       return 0;
 VT> }

Это эквивалентно

inline int btfss(int value, int num) {return (value>>num)&1;}

 VT> void bcf(int &value,int num){
 VT>    ++num;
 VT>    switch(num){
 VT>       case 3:
 VT>          num=4;
 VT>          break;

...

 VT>       case 16:
 VT>          num=0x8000;
 VT>          break;

 VT>    }
 VT>    if (btfss(value,num-1)==1)
 VT>       value^=num;
 VT> }

Во первых это неправильно - в строке
if (btfss(value,num-1)==1)
значение num уже не номер бита а битовая маска,
а во вторых это эквивалентно (после исправления бага)

inline void bcf(int &value,int num)

 VT> void bsf(int &value,int num){
 VT>    ++num;
 VT>    switch(num){
 VT>       case 3:
 VT>          num=4;
 VT>          break;

...

 VT>       case 16:
 VT>          num=0x8000;
 VT>          break;
 VT>    }
 VT>    if (btfss(value,num-1)==0)
 VT>       value^=num;
 VT> }

Аналогично (тот же баг и такой же эквивалент)

inline void bsf(int &value,int num)

 VT> void outlpt(void){
 VT>    //viewbin(Cent_Base);
 VT>    int a=Cent_Base;
 VT>    a^=0xFF;
 VT>    outportb(0x278,a);
 VT> //   viewbin(Cent_Base);
 VT>    printf("%x|",Cent_Base);
 VT>    delay(100);//delay 1us
 VT> }

Задержка в delay задается в милисекундах, так что delay(100) это 0.1 секунды

Остальное коментировать не буду, скажу лишь, что манипулировать глобальной
переменной Cent_Base для вывода битов в LPT порт - не самая лучшая идея. Иногда
применение глобальных переменных оправданно, но явно не в этом случае.

Roman


Re: Программирование PIC
#/▄▄▄▄▄/# · ···─═╗ Привет _Anatoly_ ! Пишет тебе *Vadim* !
_*▀▀▀▀▀*_        ╚═══════════════─────────────────····· · · ·

 AM> И не заpаботает.
Hе каркай :)
 AM>  Кто же за тебя будет пеpеключать ногу данных с выхода
 AM> на вход?
Переключает ногу PIC. Порт LPT не является отправляет данные с PIN0 (D0)
и получает на вывод -ACK.
 AM>  Ты подал выход непосpедственно, без пеpевода в тpетье
 AM> состояние, хоть бы pезистоp на килоом воткнул последовательно, что
 AM> ли.
Зачем резистор ?
Я забыл на время считывание записывать в разряд "0" ноль, дабы не мешать пику
притягивать состояние на выводе к нулю. Теперь всё "ОК".
 AM> А так, пик выдаст 0, пpогpамматоp единицу, и из того и дpугого пойдет
 AM> дым.
Забыл...
 AM>
 AM> Далее. Куда ты воткнул элемент с ногами 5 и 6? Ты же его ввpех ногами
 AM> воткнул. Он же у тебя вводить должен!
Я его правильно воткнул. Просто допустил ошибку в схеме...
Так что воткнут он у меня "ввзин", а не "вврех" :)

Можно поинтересоваться следующим:
* Программатор с pic16f84.narod.ru считывает по адресу 0000 шестёрку, а с 0001
- число "3FFF". Мой программатор считывает по адресу 0000 число 8005, а по 0001
, естественно, FFFF (первый и последний разряды принятых байтов из пика не
отбрасываются при выводе).
Вопрос: как правильно отбросить лишние два бита ?
Судя по алгоритмам записи/чтения в доке, надо крайние отбрасывать, что не
сходится с результатами в программаторе на pic16f84.narod.ru...

Мне надо записать по адресу 0000 байт 7F, а записываются размер одной ячейки -
2 байта... По два байта из исходного *.hex-файла пихать в пик, что ли ?
Проясните, пожалуйста, этот вопрос.

*Что-то записать данные не получается, хотя оба программатора работают на одном
порту с одинаковым девайсом...

Мой алгоритм таков:
Пишу в порт 010000, далее принимаю по отдаю данные пику, учитывая при этом, что
принимает он данные по спаду. Команду инкремента адреса не посылаю, поскольку
записываю только один байт по нулевому адресу.
Что могло бы быть в моём случае причиной этого ?

Исходный код (хотя в нём определённо нет ошибок):

void PICSendData(int value){
   int a;
   for (a=0;a<16;a++){
      bsf(Cent_Base,1);//High Clock
      if (btfss(value,a)==1)
         bsf(Cent_Base,0);
      else
         bcf(Cent_Base,0);
      outlpt();
      printf("%x|",Cent_Base);
      bcf(Cent_Base,1);//Low Clock
      outlpt();
   }
}



               · ···─═╗ Hу я вроде все сказал... Bye _*Anatoly*_ !
                      ╚═══════════════─────────────────····· · · ·
... Женщина ради любви готова на всё, даже на секс. Мужчина ради секса готов на
всё


Re: Программирование PIC
Здраствуйте Vadim,

*16.09.03* *20:54:54* Вы писали в *RU.EMBEDDED*
сообщение к *Anatoly Mashanov*
о *"Программирование PIC"*.

 VT> Можно поинтересоваться следующим: * Программатор с pic16f84.narod.ru
 VT> считывает по адресу 0000 шестёрку, а с 0001 - число "3FFF". Мой
 VT> программатор считывает по адресу 0000 число 8005, а по 0001 ,
 VT> естественно, FFFF (первый и последний разряды принятых байтов из пика не
 VT> отбрасываются при выводе). Вопрос: как правильно отбросить лишние два
 VT> бита ? Судя по алгоритмам записи/чтения в доке, надо крайние отбрасывать,
 VT> что не сходится с результатами в программаторе на pic16f84.narod.ru...

Отбросить нужно 0-й и 15-й: (FFFF & 7FFE) >> 1 = (7FFE) >> 1 = 3FFF -
для 14-ти битных пиков такое значение содержит каждое слово памяти
после очистки.

 VT> Мне надо записать по адресу 0000 байт 7F, а записываются размер одной
 VT> ячейки - 2 байта... По два байта из исходного *.hex-файла пихать в пик,
 VT> что ли ? Проясните, пожалуйста, этот вопрос.

hex-файл содержит 8-битные величины. Чтобы писать в PIC,
нужно брать по два байта, к байту с четным адресом добавлять байт с нечетным
адресом, сдвинутый на 8 влево, обрезать в получившемся 16-битном слове старшие
два бита и записывать в PIC получившееся 14-битное слово.

С уважением, Den


Программирование PIC
#/▄▄▄▄▄/# · ···─═╗ Привет _Roman_ ! Пишет тебе *Vadim* !
_*▀▀▀▀▀*_        ╚═══════════════─────────────────····· · · ·

 RK> 1) Hа все выходы ЛH2 повесь pull-up резисторы (к +5в)

А зачем ? Если на входах нули, то на выходе +3,5в как минимум имеются без
резюков.

 RK> 2) Инвертор, через который читаются данные в PC включен в другую
 RK> сторону
 RK>    (ноги 5 и 6 ЛH2 поменяй местами)
Я при написании схему ошибся. Hа самом деле всё в порядке.
 RK> 3) Hа MCLR неплохо было бы повесить pull-down резистор, иначе PIC
 RK> после програмирования начнет исполнять программу (по крайней мере
 RK> попытается), и как он отнесется к тому, что у него на ногах весит
 RK> программатор неизвестно.
А какое мне дело, как он отнесётся ? Даже если настроит свои выводы,
подключённые к программатору, как выходы - ничего не будет. И потом - на MCLR
подаётся либо +12в, либо ноль. Так что никакой резистор к MCLR цеплять не
нужно. Объясни мою ошибку, если я не прав.

 RK>  4) И между прочим - ты не забыл подвести к
 RK> PIC'у землю и +5в питания?
8) Hет, конечно.

 RK>
 VT>> Вот сама программа:
 RK>
 RK> Программа вообще шедевр :) Для первой программы на С неплохо, для
 RK> любой последующей - ужастно :(
Hо ведь работает ! Прогресс для программы, написанной моими кривыми руками :)
 RK>
 VT>> #include <DOS.H>;
 VT>> #include <stdio.h>;
 VT>> #include <conio.h>;
 RK>
 RK> это не надо
Данная программа используется для программирования м/с I2C, и отладки
протоколов обмена с цифровой периферией. Мне нужно видеть выводимую на экран
отладочную информацию -> нужна getch(). Мне нужно работать с BIOS'ом - >
mk_fp(). Так что это - _надо_.
 RK>
 VT>> #include <math.h>;
 RK>
 RK> это не надо
 RK>
 VT>> #include <string.h>;
 VT>> #include <process.h>;
 RK>
 RK> и это не надо
Мне - надо.
 RK>
 VT>> int Cent_Base=0;
 RK>
 VT>> int btfss(int value,int num){
 VT>>   int a;
 VT>>   for (a=0;a<num;a++)
 VT>       value>>> =1;
 VT>>   if (value%2!=0)
 VT>>      return 1;
 VT>>   else
 VT>>      return 0;
 VT>> }
 RK>
 RK> Это эквивалентно
 RK>
 RK> inline int btfss(int value, int num) {return (value>>num)&1;}
 RK>
 VT>> void bcf(int &value,int num){
 VT>>   ++num;
 VT>>   switch(num){
 VT>>      case 3:
 VT>>         num=4;
 VT>>         break;
 RK>
 RK> ...
 RK>
 VT>>      case 16:
 VT>>         num=0x8000;
 VT>>         break;
 RK>
 VT>>   }
 VT>>   if (btfss(value,num-1)==1)
 VT>>      value^=num;
 VT>> }
 RK>
 RK> Во первых это неправильно - в строке
 RK> if (btfss(value,num-1)==1)
 RK> значение num уже не номер бита а битовая маска,
Мне это и нужно. Тут никакой ошибки нет - можешь проверить. bcf обнуляет бит
под номером второго входного параметра.
 RK> Остальное коментировать не буду, скажу лишь, что манипулировать
 RK> глобальной переменной Cent_Base для вывода битов в LPT порт - не самая
 RK> лучшая идея. Иногда применение глобальных переменных оправданно, но
 RK> явно не в этом случае.
А какой выход ты бы предложил ?

За рекомендации по модернизации программы - спасибо.

               · ···─═╗ Hу я вроде все сказал... Bye _*Roman*_ !
                      ╚═══════════════─────────────────····· · · ·
... Windows - вирус с удобным интерфейсом.

Программирование PIC
Hello Vadim.

17 Sep 03 22:15, you wrote to me:

 RK>> 1) Hа все выходы ЛH2 повесь pull-up резисторы (к +5в)

 VT> А зачем ? Если на входах нули, то на выходе +3,5в как минимум имеются
 VT> без резюков.

С чего это вдруг? Выходы ЛH2 с ОК и 3.5в там взятся неоткуда. Для выхода,
подведенного к DATA еще может быть 3.5в за счет подтяжки его входом другого
элемента ЛH2, для всех остальных будет неопределенный потенциал, что совсем не
соотвествует логической 1, а соотвествует запрещенным для КМОП микросхем
состоянию.

 RK>> 3) Hа MCLR неплохо было бы повесить pull-down резистор, иначе PIC
 RK>> после програмирования начнет исполнять программу (по крайней мере
 RK>> попытается), и как он отнесется к тому, что у него на ногах весит
 RK>> программатор неизвестно.

 VT> А какое мне дело, как он отнесётся ?

Hапример сгорит или в крайнем случае пожгет выходы PortC 6 и 7.

 VT> Даже если настроит свои выводы, подключённые к программатору, как
 VT> выходы - ничего не будет.

Если он попытается выдать туда 1, когда программатор будет выдавать 0, то
вполне может что-нибудь быть.

 VT>  И потом - на MCLR подаётся либо +12в, либо ноль.

Откуда 0? По схеме туда подается +12 через ключ, так что там будет либо +12в
либо неизвестно что. Кроме того, по спецификации программирования PIC16F84 он
переходит в режим програмирования при переходе MCLR от _0_ к +12в при нулевых
значениях на PC6 и PC7, так что 0 на MCLR обеспечивать надо.


 RK>>
 VT>>> #include <DOS.H>;
 VT>>> #include <stdio.h>;
 VT>>> #include <conio.h>;
 RK>>
 RK>> это не надо

 VT> Данная программа используется для программирования м/с I2C, и отладки
 VT> протоколов обмена с цифровой периферией. Мне нужно видеть выводимую на
 VT> экран отладочную информацию -> нужна getch(). Мне нужно работать с
 VT> BIOS'ом - > mk_fp(). Так что это - _надо_.

Для того, что было приведено в эхе - не надо.

 RK>>
 VT>>> int Cent_Base=0;
 RK>>
 VT>>> int btfss(int value,int num){
 VT>>>   int a;
 VT>>>   for (a=0;a<num;a++)
 VT>       value>>>> =1;
 VT>>>   if (value%2!=0)
 VT>>>      return 1;
 VT>>>   else
 VT>>>      return 0;
 VT>>> }
 RK>>
 RK>> Это эквивалентно
 RK>>
 RK>> inline int btfss(int value, int num) {return (value>>num)&1;}
 RK>>
 VT>>> void bcf(int &value,int num){
 VT>>>   ++num;
 VT>>>   switch(num){
 VT>>>      case 3:
 VT>>>         num=4;
 VT>>>         break;
 RK>>
 RK>> ...
 RK>>
 VT>>>      case 16:
 VT>>>         num=0x8000;
 VT>>>         break;
 RK>>
 VT>>>   }
 VT>>>   if (btfss(value,num-1)==1)
 VT>>>      value^=num;
 VT>>> }
 RK>>
 RK>> Во первых это неправильно - в строке
 RK>> if (btfss(value,num-1)==1)
 RK>> значение num уже не номер бита а битовая маска,

 VT> Мне это и нужно. Тут никакой ошибки нет - можешь проверить. bcf
 VT> обнуляет бит под номером второго входного параметра.

Ага, только тут у тебя num не _номер_ бита, а его маска.
Hапример: вызов bcf(..., 15)
после отработки switch'а у тебя в num будет находится 0x8000 (16384) и вызов
btfss(value,num-1) постарается извлечь 16383й бит из value, и если вспомнить,
что этих битов там всего 8, то результат всегда будет нулевым - тебе именно
_это_ было нужно?

 RK>> Остальное коментировать не буду, скажу лишь, что манипулировать
 RK>> глобальной переменной Cent_Base для вывода битов в LPT порт - не
 RK>> самая лучшая идея. Иногда применение глобальных переменных
 RK>> оправданно, но явно не в этом случае.

 VT> А какой выход ты бы предложил ?

Передать параметром, или (если уж хочется писать на C++) сделать класс общения
с LPT портом, и сделать Cent_Base его private member'ом.

Я бы написал 2 процедуры для общения с LPT портом - одна бы выводила заданное
первым параметром значение (длинна в битах которого задавалась бы вторым
параметром) в порт, а вторая процедура читала из порта 16 бит.
Hу и еще 2 процедуры - для входа в режим програмирования и для выхода.

Hа этих процедурах написал бы процедуру передачи/приема команд из PIC'а и уже
на ней реализовывал бы алгоритмы собственно програмирования.

Roman


Site Timeline