Свежие обсуждения
Микроконтроллеры

Ликбез по С для микроконтроллеров PIC

1 5 64

RE Zandy
По поводу изучения си для контроллеров,есть такая статейка известная называеться "си без си",вот тут
http://www.caxapa.ru/story/bill_1.html

 

dosikus: Ну и в си ты можешь на прямую к регистру обратиться
Не, ну спасибо конечно за ценную инфу. Приму к сведению. Только вот как именно? Примерчик бы сразу.

 

И как же обращаться к регистрам PIC в Си? По их адресам только? Самому прописывать каждый регистр через #define? Или как ещё можно, попроще?

 

picmaniac: И как же обращаться к регистрам PIC в Си?

А какие проблемы? Пишешь:


#include <pic.h>

и обращаешься:


void rs_init(void)
{
TRISA0 = OUTPUT;

SPBRG = DIVIDER;
TXSTA = 0x24;
RCSTA = 0x90;

RC6 = 1;
RC7 = 1;
TRISC6 = OUTPUT;
TRISC7 = INPUT;
}

Это для ht-picc, возможно для другого Си надо включить другой заголовочный файл.

 

Да в том-то и дело, что в .h я их и не увидел. Щас в примерах посмотрю.
Что-то подозрение у меня есть, что всё там через функции реализовано.

 

2 picmaniac
В CCS PICC действительно все через функции или макросы реализовано, лично для меня после хайтековского компилера довольно непривычно выглядят выражения типа set_tris_a(value), в хайтековском это пишется как TRISA=value; а если нужен побитовый доступ то TRISAn= или RAn= Автор книги CCS PIC Source Code Book пишет что пользоваться такими выражениями как set_tris_a(value), GETTIMER0() и т.д. нежелательно. Автор написал заголовочные файлы для нескольких видов МК, в том числе для 16F628. Можно пользоваться ними. Если нужна книга с исходниками, могу намылить она в раене 2х мегабайт весит.

 

Книга есть. Значит, действительно через функции... Но напрямую тоже можно, через адреса. Тогда интересно, а как обращаться напрямую к тем регистрам, что в банках 1, 2 и 3 ?

И ещё одно пожелание. Расскажите об указателях, о разыменовании и т.п. Я хоть и прочёл внимательно стр.121 и далее, хоть и понял вроде, и всё же хотелось бы подробнее. Когда эти хитрости бывают полезны? На что следует обратить внимание?

 

Насчет обращения к регистрам в других банках: компилятор это делает сам. Я загрузил в МПЛАБ пример из ПИК Си Соурс Бук FLASH_1.c и посмотрел дизассемблер. Видимо при значении адреса более чем размер банка, он сам переключает банки. Наверное именно для этого и нужна директива #device, чтоб знать с какого адреса банк переключать (может я и не прав и она не для этого или не только для этого).А в хайтековском это выглядит так: static volatile bank1 bit TRISB4 @ ((unsigned)&TRISB*8)+4; слово bank1 дает понять колмпилеру что при обращении к TRISB4 нужно установить 1 банк.
По поводу указателей.... Вопрос когда лучше использовать указатель посетил и меня) Завтра ко мне друг программер должен приехать, будет пытаться мне разьяснять именно этот вопрос) Если сам вьеду с удовольствием поделюсь=)

 

Итак, указатели.
Тема довольно сложная, и не является той темой, с которой стоит начать при изучении Си.
Указатель, это переменная содержащая адрес другой переменной(или константы). Как и все переменные его нужно обьявлять. Обьявляется он следующим образом:
int* pointer; //int значит что указатель указывает на ячейку памяти в которой содержится значение типа int, звездочка значит что в этой переменной будет храниться адрес а не значение.
Указатель необходимо инициализировать значением сразу после обьявления, иначе он будет непонятно на что указывать. Делается это следующим образом:
char variable=25; // обьявили переменную
char* pointer=&variable;// обьявили указатель (значение по указаном адресу должно быть типа char), и присвоили указателю адрес переменной variable. знак & в данном случае является операцией взятия адреса а не логическим И. Когда что значит этот знак компилер разбирается сам.
Теперь о разыменовании.
char AnotherVar=*pointer; Оператор разыменования * перед переменной pointer может рассматриваться как "значение хранящееся по адресу". Вся операция присваивания будет значить "получить значение хранящееся по адресу, записанном в pointer и присвоить его переменной AnotherVar".
Если на пальцах:
У нас есть переменная char variable=25 по адресу 0x20. В ней значение 25. char* pointer - у нас появилась переменная указатель по адресу 0x21. pointer=&variable - ячейка по адресу 0х21 инициализируется значением 0х20 (адресом переменной variable), на АСМе это будет выглядеть так: movlw 0x20 movwf 0x21
AnotherVar=*pointer - это выражение приведет к косвенной адресации. В регистр косвенной адресации FSR запишется значение переменной pointer, затем прочитаeт INDF и считанное значение занесет в переменную AnotherVar.
Если что не понятно спросите, ибо этот пост можно растянуть листа на 3=)
Если это все понятно и я зря писал, то можно рассмотреть примерчики с указателями и посмотреть что мы выигрываем.
Сам еще ни разу указателями в МК не пользовался, поскольку увлекся я мелкопроцессорами месяца 2-3 назад.Учусь еще. Все вышеописанное, за ночь вычитано из книжек и проверено на паре функций. Так что строго не судите если что.

 

Я начинал изучать Си по книжке "Андрей Богатырев. Руководство по программированию (на языке Си)". Очень доходчиво на простом языке, в том числе и про указатели. Ну а потом "Керниган, Ричи. Язык C"- считается классикой.
Хотя сейчас пишу прграммы на уровне первых 20-30 страниц Богатырёва , пока хватает за глаза, Карнигана почитываю для повышения эрудиции. Книжки есть здесь http://lord-n.narod.ru/walla.html