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

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) {value&=~(1<<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) {value|=1<<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

Reply to
Roman Khvatov
Loading thread data ...

#/▄▄▄▄▄/# · ···─═╗ Привет _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*_ ! ╚═══════════════─────────────────····· · · · ... Женщина ради любви готова на всё, даже на секс. Мужчина ради секса готов на всё
Reply to
Vadim Tzirulnicov

#/▄▄▄▄▄/# · ···─═╗ Привет _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 - вирус с удобным интерфейсом.
Reply to
Vadim Tzirulnicov

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

Reply to
Roman Khvatov

Здраствуйте 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

Reply to
Den Y. Borisov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.