Почетный модератор
11165 / 4124 / 410
Регистрация: 12.06.2008
Сообщений: 11,942
|
|||||||||||
1 | |||||||||||
Cамоучители по программированию PIC15.09.2010, 15:17. Просмотров 35233. Ответов 9
Решил я поделиться наработками своих программ для PIC контроллеров. Хотя тут я выкладываю примеры для работы с PIC18F2550, но эти примеры подойдут для любого контроллера (конечно, если хватит выводов и скорости для конкретных задач). Проблемы могут быть только с другими компиляторами (например, для PIC16 нет компилятора MCC... там обычно используют HT-PICC).
Всё что будет сказано в этой теме не претендует на правильность подходов и идеальную оптимальность. Это просто работает и может помочь другим разобраться в аналогичной проблеме. Использование LCD Я использую символьный ЖКИ MTC-16205D (2 строки, 16 столбцов). В даташите пишут, что он может работать от 2.7 до 5.5 вольт. Имеется 16 выводов:1 - земля 2 - питание 3 - контрастность 4 - RS - режим работы (если задать 0, значит мы передаём команды, если задать 1, значит мы передаём данные) 5 - R/W - чтение/запись (если задать 0, значит мы записываем в ЖКИ, если 1, значит читаем). Лично я его намертво подключаю к земле... мне нечего читать из индикатора... я туда только записываю. 6 - E (по этому выводу мы будем передавать тактовые импульсы) 7-14 - DB0-DB7 (по этим выводам передаются сами данные/команды) 15,16 - питание для подсветки... в моём ЖКИ подсветки нет, поэтому я эти выводы не использую. Несколько слов про контрастность... я использую делитель, что бы задать на 3 вывод низкое напряжение. Но можно этот вывод просто посадить на землю. В этом случае фон будет немного темноватым, но надписи будет видно. Про выводы DB0-DB7... изначально ЖКИ запускается в 8-битовом режиме. Т.е. для обмена информации нужно использовать 8 линий данных. Но не всегда есть такое количество свободных выводов у PIC контроллера. Но к счастью этот ЖКИ (и многие, но не все) умеет работать в 4-битном режиме... в результате каждый бит передаётся за два раза. Вот такой режим мы и будем использовать. Для этого выводы 7-10 (DB0-DB3) сажаем на землю, а во время работы надо будет подать специальную команду, что бы перевести его в 4-битный режим. Работать будем только с выводами DB4-DB7. Для написания программы для PIC контроллера я использую компилятор MPLAB C Compiler for PIC18 MCUs... или просто MCC18 (он платный, но есть бесплатная урезанная Standard-Eval Version). Вот так выглядит исходник, который я использую:
Первым делом, когда подключите этот файл, то укажите правильные #define: LCD_PIN_RS - к какому выводу PIC'а подключен 4-й вывод ЖКИ (вывод RS) LCD_PIN_RS_TRIS - тоже самое, но только TRIS (что бы можно было указать, что вывод используется на передачу) LCD_PIN_E - к какому выводу подключен 6-й вывод ЖКИ (E) LCD_PIN_E_TRIS - аналогично как и для LCD_PIN_RS_TRIS LCD_COL_NUM - сколько столбцов имеет ЖКИ Delay230ns - задержка не менее 230 нс (наносекунд) Delay39us - задержка не менее 39 мкс (микросекунд) Delay43us - задержка не менее 43 мкс (микросекунд) Delay1530us - задержка не менее 1530 мкс (микросекунд) У меня задержки рассчитаны для тактовой частоты 48 МГц (12 MIPS)... если частота работы вашего PIC'а отличается, то вам нужно пересчитать задержки под свою скорость. Если вы подключили 4 линии данных (DB4-DB7) не на RB0-RB3, а на какие-то другие выводы, то вам ещё надо будет подредактировать функцию LCD_Send_Tetrad(), т.к. сейчас она работает только с этими выводами. Немного про назначение функций: LCD_Init(); Инициализация ЖКИ. При этом он переходит в 4-битный режим, устанавливает режим работы с 2 строками, выбирает движение курсора слева направо. Но помимо этого нужно указать TRISB (в данном примере) на передачу для четырёх воводов DB4-DB7. Например TRISB=0; void LCD_Clear_Display(); Очистить содержимое. Должно работать, но лично я не пользуюсь. Я в функции LCD_WriteXY() всегда передаю needfill=1 void LCD_GotoXY(const unsigned char row,const unsigned char col); Установить курсор на определённую позицию. row - это номер строки (нумеруется начиная с нуля), col - номер столбца (тоже нумеруется начиная с нуля). Обратите внимание, что в LCD_Init() отображение курсора отключено... т.е. он не будет отображаться. void LCD_Print_Char(unsigned char c); Нарисовать символ в том месте, где стоит курсор. При этом курсор сдвинется вправо на одну позицию. void LCD_WriteXY(const unsigned char row,const unsigned char col,unsigned char *s,const unsigned char needfill); Вывести строку на ЖКИ row - номер строки (нумеруется начиная с нуля) col - номер стролбца, откуда будет начинаться строка (нумеруется начиная с нуля) s - указатель на саму строку... строка должна заканчиваться на символ '\0' needfill - если его значение отлично от нуля, то оставшаяся часть строки будет заполнена пробелами до самого конца. Можно передавать как латинские буквы, так и русские (в кодировке cp1251)... для этого используется массив LCD_Chars. Эта функция запоминает каждую строку в массиве LCD_cache и не станет выводить её на ЖКИ, если там и так эта строка. Это сделано для предотвращения мерцания, когда непрерывно выводится одна и та же строка. void LCD_Tick(); Строб. Даёт понять ЖКИ, что ему отправлены данные и их нужно принять. До тех пор, пока не будет выполнен LCD_Tick(), ЖКИ не будет игнорировать все данные, которые мы ему выставляем на выводах. void LCD_Send_Tetrad(unsigned char data); Отправить тетраду (4 бита) данных в ЖКИ. Т.е значения data могут быть от 0 до 15. void LCD_Send_Byte(unsigned char data); Отправить байт в ЖКИ. Тут нам не надо думать о том, что байт надо разбивать пополам... этим займётся сама функция. Пример использования:
Вот так выглядит сам ЖКИ: Краткое описание на этот ЖКИ: MTC-16205D.pdf Более полное описание от производителя MTC-S16205DFYHSAY.pdf Описание на контроллер HD44780U, на основе которого сделан этот (и многие другие) ЖКИ: HD44780U.pdf
9
|
|
15.09.2010, 15:17 | |
Вопросы по программированию PIC на Си (так и не получилось р Какая книга по программированию обьясняет все с математикой и подробно излагает все темы?По программированию? PIC 16F84A Дизассемблер PIC |
|
Почетный модератор
11165 / 4124 / 410
Регистрация: 12.06.2008
Сообщений: 11,942
|
||||||||||||||||
16.09.2010, 14:28 [ТС] | 2 | |||||||||||||||
Обмен данными по шине I2C на примере часов DS1307 Существует много внешних устройств, управление которыми осуществляется по шине I2C (она же IIC). У многих PIC контроллеров есть аппаратная поддержка этой шины. Но я не подумав о будущем, занял эти выводы под другие нужды (под LCD, о котором писал выше... на PIC18F2550 аппаратный I2C находится на RB0, RB1). Тут я хочу рассказать, как можно программно работать с шиной I2C.Немного теории I2C - это двухпроводная шина, которая предназначена для работы внутри устройств (на сколько я знаю, изначально разработана фирмой Philips для работы внутри телевизоров). И хотя я слышал, что некоторые люди используют её для связи на десятки метров, всё же это не желательно. Шина состоит из двух проводов: SDA (линия данных) и SCL (тактовые импульсы). Обе линии притянуты к питанию (в нашем случае к 5 вольтам) резисторами по 5 кОм каждый. На одной шине может находится одно ведущее (master) устройство (в нашем случае PIC контроллер) и много ведомых (slave) устройств (можно адресовать до 128 устройств)... в данном случае будет только одно ведомое устройство - RTC (Real-Time Clock (часы реального времени)) DS1307. Шина I2C может работать на двух скоростях: 100 кГц и 400 кГц. Но так как DS1307 поддерживает только 100 кГц, то все задержки у меня стоят в расчёте на эту скорость. Как происходит обмен данными В состоянии покоя выводы PIC'а настроены на приём... при этом резисторы притягивают обе линии к логической единице. Что бы начать обмен данными, ведуще устройство вначале передаёт "СТАРТ". Для этого SCL остаётся нетронутым (притянутый к единице), а SDA при этом переводится на передачу и устанавливается в ноль. Удерживаем всё в таком состоянии не менее 4 мкс и устанавливаем в ноль ещё и SCL. Через 4 мкс после этого ведущее устройство может передавать адрес устройства, с которым хочет общаться. Данные (в том числе и адрес ведомого устройства) передаются по 8 бит. Для этого ведущий устанавливает SDA в ноль или отпускает его, что он стал единицей. После чего на 4 мкс отпускает SCL. И через 4.7 мкс опять прижимает его к нулю. И так для каждого бита. Биты передаются начиная со старшего. После каждого переданного байта, ведомое устройство передаёт один бит подтверждения. Для этого тоже нужно будет "дёрнуть" один раз SCL. Если ведущий читает данные из ведомого, то ведущий тоже должен посылать подтверждение. Но только не для последнего байта. Если ведущий не хочет больше получать данные, то он уже не посылает подтверждение, а посылает сигнал "СТОП". После обмена данными ведущее устройство посылает сигнал "СТОП". Для этого устанавливает SDA в ноль (SCL и так в нуле). Удерживает так 4.7 мкс, после чего отпускает SCL (при этом резистор притягивает его к единице) и ещё через 4.7 мкс отпускает и SDA. Про адресацию Сразу после сигнала "СТАРТ" ведущее устройство передаёт один байт адреса устройства, с которым хочет общаться. Например, для DS1307 этот адрес задан жёстко: 1101000x. Старшие 7 бит - это и есть адрес, а младший бит - это направление. Если мы его передадим как ноль, это значит, что мы будем записывать в устройство. Если это будет единица, значит устройство будет передавать данные. Ещё важное замечание Байты читаются и записываются последовательно. Сигнал "СТОП" не означает, что указатель сбрасывается в ноль. Что бы сбросить указатель, нужно обратиться к устройству для записи и передать один нулевой байт. Т.е. если мы обратились к устройству для записи, то следующий байт - это будет указатель на ячейку памяти, начиная с которой мы хотим записывать данные. Если мы связываемся с устройством для чтения, то мы не передаём никаких данных (только адрес)... поэтому устройство будет передавать данные начиная с последней позиции. В общем, что бы читать начиная с самого начала, нам нужно вначале связаться с устройством для записи (младший бит=0 ), передать байт 0x00, передать СТОП, а после этого уже опять передаём СТАРТ, адрес для чтения (младший бит=1 ) и уже читаем данные. Вот как это расписано в даташите: Записываем в устройство: Читаем из устройства О самих часах DS1307 К микросхеме подключается обычный часовой кварц на 32 кГц (я его выпаял из старой материнской платы от первого пентиума). Так же есть возможность подключать батарейку на 3 вольта (я взял её из той же самой материнской платы вместе с удобной пластмассовой фигнёй, в которую эта батарейка вставляется). Батарейка обеспечивает работу часов даже при выключенном питании. Можно её вообще не подключать, но тогда при каждом выключении питания придётся заново устанавливать дату и время. В режиме работы от батарейки в микросхеме работают только сами часы... принимать или передавать данные она в при этом не сможет (да и если +5 В нету, то и некому эти данные передавать). Когда выключено питание, то часы тянут с батарейки не больше 500 нА... это очень маленький ток. Поэтому батарейки хватит на несколько лет. Так же у этой микросхемы есть 7 вывод SQW/OUT... можно настроить, что бы микросхема "дёргала" этим выводом с частотой 1 Гц, 4 кГц, 8 кГц или 32 кГц. Это можно использовать, например, для внешнего прерывания для PIC'а. Но я этот вывод не использую (в основном из-за нехватки свободных выводов у PIC'а). Описание на DS1307 DS1307.pdf У микросхемы есть 8 регистров (7 для времени и даты и один для настроек вывода SQW/OUT). Числа хранятся в этих регистрах в причудливом виде: в младшей тетраде (4 бита) хранятся единицы, а в старшей - десятки. Старший бит в секундах (нулевой регистр) - это запуск часов. Если этот бит установлен в 1, то часы не будут идти. Что бы запустить часы, этот бит надо установить в ноль. Время может быть либо в 12-часовом варианте, либо в 24-часовом... я везде ориентируюсь на 24-часовой. DS1307 не умеет сам рассчитывать день недели. Он умеет только его увеличивать до 7, после чего сбрасывает в 1. Поэтому я рассчитываю день недели программным путём. Значение года может быть от 0 до 99. Значит, 2000 придётся прибавлять самим. Вот сам исходник:
I2C_SDA - вывод, к которому подключен SDA I2C_SDA_TRIS - TRIS для этого вывода I2C_SCL - вывод, к которому подключен SDA I2C_SCL_TRIS - TRIS для этого вывода И не забудьте пересчитать задержки, т.к. у меня всё настроено на PIC18F2550, у которого тактовая частота 48 МГц (12 MIPS). Кстати, функции с задержками я храню в отдельном подключаемом файле delay_time.h
Теперь о самих функциях... void CalcDoW() Эта функция рассчитывает текущий день недели. 1=понедельник, 2=вторник... и т.д. Эта функция ничего не возвращает, а работает с глобальной переменной datetime. Функция сама вызывается внутри RTC_SetDateTime(). I2C_SendStart() Передать "СТАРТ" на шину I2C. I2C_SendStop() Передать "СТОП" на шину I2C. I2C_SendByte(unsigned char d) Отправить байт на шину. Если всё прошло нормально и ведомое устройство ответило битом подтверждения, то вернёт 0. Если подтверждения не было, то вернёт 1. I2C_ReadByte(char last) Прочитать байт из шины I2C. Параметр last указывает, последний ли это байт или нет. Если после этого мы будем ещё читать, то last должен быть равен 0. В этом случае, PIC будет посылать бит подтверждения после принятия байта. Если last не равен нулю, значит мы больше не будем ничего читать и подтверждение не посылаем. Функция возвращает байт, который был получен с шины. RTC_GetDateTime() Функция для работы с DS1307. Эта функция получает дату и время и помещает их в глобальную переменную datetime. Возвращает 0, если всё прошло нормально. Если шина занята и никак не освобождается, то возвращает 1. Если не пришло подтверждение от часов, то возвращает 2. RTC_SetDateTime() Функция для работы с DS1307. Эта функция записывает дату и время из переменной datetime в часы. В случае успеха возвращает 0. Перед вызовом этой функции нужно установить всё внутри datetime, кроме dow (день недели). dow будет рассчитан сам с помощью функции CalcDoW(). Пример использования:
Вот так выглядит сама микросхема с кварцем (слева) и батарейка (справа)
10
|
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 6
|
|
27.03.2013, 11:14 | 3 |
День добрый,господа. Подскажите какие-нибудь разумные самоучители по ПИКам. И если кто знает,где можно скачать продолжение самоучителя Корабельникова Е.А.(именно продолжение,а не практикум и абонемент)может у кого есть?
0
|
27.03.2013, 15:59 | 4 |
1- закрепленная тема по микроконтроллерам и ПЛИС в разделе электроники содержит также литературу по PIC
2- абонемент придуман сотоварищами Корабельникова не просто так 3- дополнить можно парой книжек (Кениг. Полное руководство по PIC-микроконтроллерам, Катцен. PIC-микроконтроллеры. Все что вам необходимо знать) 4- также не забываем русский сателлит сайта Микрочипа + PIC24.RU
0
|
97 / 92 / 0
Регистрация: 24.04.2010
Сообщений: 275
|
|
27.03.2013, 16:03 | 5 |
Лично я не могу читать Корабельникова, столько воды налил, какое терпение нужно иметь читая его. И это не только мое мнение.
Сид Кадцен PIC микроконтролеры все что необходимо знать , книга 2 - это классика по пикам. Далее книга по 18 пикам http://forcoder.ru/other/prime... mblera-950 Ну и книги по PIC24 Луи Джасио и Магда. А лучше читать в оригинале, т.к. эти все книги переводы.
0
|
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 6
|
|
28.03.2013, 04:51 | 6 |
согласен с russo turisto. Корабельников много воды льёт, но зато доходчиво объясняет суть вещей(самоучитель и должен быть таким). А тот же Сид Катцен, не спорю, на голову выше, но он больше похож на справочник для опытных бойцов. Для въезда в пики с нуля в самый раз Корабельников.
Тов. raxp, а почему абонемент придуман не просто так?Что это значит?
0
|
97 / 92 / 0
Регистрация: 24.04.2010
Сообщений: 275
|
|
30.03.2013, 18:53 | 7 |
Попалось высказывание про Корабельникова на мелкочипе, интересно почитать мнение dosikusa
0
|
raxp
|
30.03.2013, 19:07
#8
|
Не по теме: ...ну, на казусе то же самое.
0
|
6 / 6 / 0
Регистрация: 21.06.2010
Сообщений: 21
|
|
02.04.2013, 18:14 | 9 |
"согласен с russo turisto. Корабельников много воды льёт".... Кому не нравится, тот и не читает. Мне не нравятся статьи о заготовке древесины в 18-ом веке.....
0
|
6556 / 2652 / 364
Регистрация: 17.02.2013
Сообщений: 3,884
|
|
10.11.2016, 23:02 | 10 |
Если бы он еще ТУ воду лил.
Существуют также переходы с условием (условные переходы), то есть, с задействованием так называемого стека. ... Начинающим, в первую очередь, необходимо обратить внимание на команду безусловного перехода GOTO. Сначала нужно освоить ее, а потом переходить к изучению команды условного перехода CALL. (С)Корабельников И так на протяжении всей книги. Чего я натерпелся, знает только один Господь Бог: помощи никакой и пришлось рассчитывать только на свои силы. - это Корабельников изучал микроконтроллеры. В итоге такого самостоятельного изучения и варки в собственном соку некоторые понятия в голове у Корабельникова встали криво. Подозреваю, что в процессе чтения книжки по КР580. Ибо только в этой архитектуре (ах, да еще в Z80) есть условные вызовы подпрограмм и возвраты из них. И это была бы не беда, что криво, но он своей книгой начал навоз из своей головы перегружать в головы других. И это уже плохо.
0
|
10.11.2016, 23:02 | |
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь. Сервопривод на PIC-е... Assembler PIC Micro C for PIC MicroPascal for PIC Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |