Pull to refresh

Программирование микроконтроллеров PIC16/PIC18 на языке C. Статья вторая. Базовые сведения о платформе. Первая программа

Reading time 4 min
Views 126K
Если в первой статье все получилось хорошо — мы получили базовую программную обстановку для продолжения обучения.

Едем дальше.

Как я говорил ранее, пока что объяснять буду на базе МК PIC16F628A.
Обязательно качаем документацию на него. Рекомендую для поиска — alldatasheet.com
DataSheet — главный документ при разработке на базе МК.
Рекомендую распечатывать основные таблицы и разделы для удобства пользования.

Открываем ДШ.

Наиболее важные сведения о кристалле:
— максимальная рабочая частота — 20МГц;
— 2048х14 бит флеш-ПЗУ;
— 224 байта статической ОЗУ;
— 128 байт энергонезависимой ПЗУ;
— 16 доступных выводов;
— модуль приемо-передатчика;
— 3 таймера.

Данный кристалл — представитель так называемого среднего (Mid-range) семейства МК PIC.

Вкратце расскажу о том, что обязательно нужно понимать.



Память данных устройства разделена на 4 банка.
Банки содержат регистры специального назначения(SFR) и регистры общего назначения(GPR).
SFR — используются для управления устройством и его модулями.
Регистры обшего назначения представлены в виде статической ОЗУ, где мы можем хранить свои переменные.
Специальные регистры занимают по 32 начальные позиции в каждом банке.
В ДШ на страницах 18-21 показаны все регистры специального назначения. Распечатайте их — пригодится и не раз.

Это довольно таки объемная тема, и пропускать ее никак нельзя.
А с другой стороны нудноватая и неинтересная.
Пробуйте переосилить себя и прочитать об организации памяти и регистрах специального назначения в ДШ и у Шпака(упоминал в первой статье).

Порты ввода/вывода.

У данного устройства два порта: PORTA и PORTB.
Каждый вывод порта может использоваться непосредственно как простой вывод либо как вывод прочих модулей МК.
В самом начале ДШ вы должны были заметить что каждый вывод помимо основного названия, к примеру RB1, содержит еще и другое наименование RX и DT.
Вот здесь RX и есть второстепенная функция вывода — как вход приемо-передатчика.
Но пока мы не будем трогать периферийные модули устройства.

Каждый вывод порта может функционировать как вход или как выход.
Например, если нам нужно зажечь светодиод то вывод, к которому он подключен мы конфигурируем как выход, и выставляем на нем соответствующий уровень.
А вот если нам нужно подключить кнопку к порту и считывать факт нажатия, то здесь уже необходимо конфигурировать этот вывод как вход.
Конфигурация вход/выход осуществляется с помощью регистров TRIS.
Если в соответствующий бит регистра TRIS записать 1 то этот вывод станет входом, если 0 — выходом(видимо в связи с схожестью 1 и Input, а 0 и Output)
К примеру:
TRISA = 0; // Все выводы порта А - выходы
TRISB = 0xff; // Все выводы порта B - входы
TRISA5 = 1; // 5 вывод порта А - вход. Кстати не у всех компиляторов можно обращаться к каждому выводу непосредственно

Имена регистров можно посмотреть в папке «Папка HT-PICC\include» для соответствующего контроллера.

Для установления определенного уровня на выводе используем регистр PORT.
К примеру:
PORTA = 0; // Все выводы порта А с низким уровнем
PORTB = 0xff; // Все выводы порта B с высоким уровнем
RB5 = 1; // На пятом выводе порта B высокий уровень

Так. Достигаем момента когда неоходимо сделать отступление собственно по языку C.
Наверное напишу здесь небольшой пример. Скомпилируем. Запустим в Proteus, а о базовом языке C напишу в следующей статье.

Напишем небольшую программку. Помигаем светодиодом.
Пользуемся ранее созданным проектом, либо создаем новый, по схеме из первой статьи.

Для начала подключим файл заголовков.

#include <pic.h>

Мы не выбираем конкретную модель, а указываем pic.h. Если открыть его то увидим скрипт выбора конкретного файла исходя из выбранного устройства при создании проекта.

Далее нам нужно инициализировать наши порты.
Создаем основную функцию программы:
void main(void)
{
while(1);
}

Пишем в ее начале:
TRISA = 0; // Порт А - все выводы выходы
PORTA = 0; // с логическим нулем
TRISB = 0; // Порт B - все выводы выходы
PORTB = 0; // С логическим нулем

Пойдем в «Папка HT-PICC\samples\delay».
Скопируем оттуда delay.c и delay.h и вставим их в папку проекта.

Добавим строку в начале:
#include «delay.c»
Мы будем использовать функцию DelayMs(x) для создания паузы между переключениями светодиода.

Допустим светодиод подключен к RB0.
Для его переключения будет использоваться логическое исключающее «ИЛИ»:
RB0 ^= 1;

В итоге код принимает вид:

#include <pic.h>
#include "delay.c"

void main(void)
{
TRISA = 0;
PORTA = 0;
TRISB = 0;
PORTB = 0;

while(1)
{
DelayMs(250); // Сделаем паузу в полсекунды
DelayMs(250);
RB0 ^= 1; // инвертируем вывод
}
}

image

Прошивка готова.
Теперь настроим конфигурационные биты.
Жмем Configure -> Configuration bits.
Снимаем галку «Configuration Bits set in code», так как в коде мы ничего не выставляли.

Видим несколько пунктов.
Выставляем как на скрине.
Oscillator — HS — в качестве тактового генератора будет использоваться высокочастотный кварцевый резонатор.
WatchDog Timer — Off, если включить, то микроконтроллер будет периодически сбрасываться во избежание каких-либо зависаний. Нам такая возможность пока не нужна.
Power Up Timer — Enabled, МК будет находится в состоянии сброса, пока напряжение питания не достигнет необходимого порогового уровня.
Brown Out Detect — On, сброс МК, если произошло падение питающего напряжения ниже определенного уровня.
Low Voltage Program — Disabled, запрещаем использовать низковольтное внутрисхемное программирование МК. Здесь уже зависит от Вашего программатора.
Data EE Read Protect — Off, разрешаем чтение данных и EEPROM памяти МК.
Code Protect — Off, отключаем защиту кода в МК. Если выставить On — то невозможно будет считать программу из МК. Нам пока такая возможность не нужна.

image

Еще раз жмем F10.
Закрываем.

Прогоним программу в Proteus.
Запускаем Proteus ISIS.
Находясь в разделе Component mode жмем Pick from libraries и, пользуясь поиском, добавляем на форму компоненты:
— PIC16F628A;
— LED-RED;
— RES;

Два раза кликаем на каждом из них и выставляем параметры.
Для МК — выбираем файл прошивки *.hex из папки нашего проекта, и выставляем частоту 4МГц.
Для LED-RED выбираем Model type — Digital.
Для резистора выбираем сопротивление в 300 Ом.
Добавляем на форму Ground в разделе Terminals mode и соединияем как на скрине.
image
Жмем Play — светодиод должен мигать.

В следующей статье плотно пройдусь по языку C.
Вслед за ней будет статья по периферии контроллера и примеры кода для нее.
И за ней планирую рассказать о USB и PIC 18.
Вот такой план пока:-)
Tags:
Hubs:
+42
Comments 16
Comments Comments 16

Articles