Table of Contents
Кросс-система программирования для процессора PIC 17c4X
Состав системы:
- Компилятор языка Си
- Ассемблер
- Дизассемблер
- Симулятор процессора
- Служебная библиотека
Симулятор
Вызов:
sim17 [-d] file.hex
Флаг “-d” включает отладочную печать. Многократное повторение флага увеличивает подробность диагностической печати.
Симулятор имитирует работу реального процессора PIC 17c4X, упрощая отладку программного обеспечения. Особенности:
- Биты статуса DC и OV отсутствуют.
- Нет sleep и watchdog таймеров.
- Моделируется работа таймера 0.
- Моделируется работа асинхронного порта.
В файле hello.s находится пример тестовой программы для проверки симулятора. Для запуска необходимо оттранслировать файл командой “as17 hello.s” и запустить симулятор командой “sim17 hello.hex”.
Дизассемблер
Вызов:
dis17 file.hex
Дизассемблер печатает содержимое бинарного файла в виде команд ассемблера. Формат выдачи:
<адрес>: <байт1> <байт2> <команда> <аргументы>
Ассемблер
Вызов:
as17 [-O] [-o outfile.hex] [-l libdir] infile.s ...
Ассемблер транслирует набор входных файлов в выходной бинарный файл. Используется мнемоника команд процессора в стиле автокода “Madlen” ЭВМ БЭСМ-6. Таблицы соответствия традиционной мнемонике фирмы Microchip приведены в отдельном файле.
Флаг -O включает оптимизацию: устранение недостижимых команд и избыточных пересылок аккумулятора.
Флаг -l подключает каталог с библиотечными функциями. По умолчанию подключен каталог /usr/local/lib/pic17.
Подробнее ассемблер описан здесь.
Компилятор Си
Вызов:
cc17 file.c
После компиляции образуется файл “file.s” на языке ассемблера.
Входной язык компилятора сильно упрощен.
1) Нет конструкций struct, union и typedef. Нет операций с плавающей точкой.
2) Функции могут иметь не больше двух аргументов. Общий размер аргументов не может превышать 4 байт.
3) Размер long равен 4 байтам, short - 2 байта, char и int - 1 байт. Простой указатель имеет размер 1 байт, far-указатель - 2 байта.
4) Тип указателя на указатель эквивалентен (char*) для простых указателей и (short*) для far-указателей.
5) Все функции должны быть объявлены до использования. Список аргументов в объявлении функции не реализован.
6) Язык расширен операциями над отдельными битами. Например:
if (a.1) b.4 = 1;
Для битов разрешены четыре операции:
- Установка в ноль (a.N = 0);
- Установка в единицу (a.N = 1);
- Инверсия (a.N ^= 1);
- Проверка (if (a.N) or if (! a.N)).
7) Можно указывать адрес для размещения переменной или функции в памяти, например:
short PROD @ 0x18; void startup () @ 0 { ... }
Функция startup() будет размещена в памяти команд по адресу 0, переменная PROD займет в памяти данных адрес 18h.
Библиотека
mul22 | Multiply unsigned short by short |
divcorr1 | Divide by constant correction routine |
divcorr2 | Divide by constant correction routine, two-byte numbers |
divmod11 | Unsigned divide/remainder |
divmod11p | Unsigned divide/remainder INDF0/WREG |
divmod21 | Unsigned short-by-char divide/remainder |
divmod22 | Unsigned short-by-short divide/remainder |
divmod42 | Unsigned long-by-short divide/remainder |
divmod44 | Unsigned long-by-long divide/remainder |
eq22 | Compare “==” unsigned short |
eq44 | Compare “==” unsigned long |
gt21 | Compare unsigned short “>” unsigned char |
gt22 | Compare “>” unsigned short |
gt41 | Compare unsigned long “>” unsigned char |
gt44 | Compare “>” unsigned long |
lt21 | Compare unsigned short “<” unsigned char |
lt22 | Compare “<” unsigned short |
lt41 | Compare unsigned long “<” unsigned char |
lt44 | Compare “<” unsigned long |
ls1 | Left unsigned byte shift |
ls1p | Left unsigned byte shift by pointer(INDF0«WREG) |
ls2 | Left unsigned short shift |
ls4 | Left unsigned long shift |
rs1 | Right unsigned byte shift |
rs1p | Right unsigned byte shift by pointer (INDF0»WREG) |
rs2 | Right unsigned short shift |
rs4 | Right unsigned long shift |
_peek | Read a byte by pointer from data page 1 |
_poke | Store a byte by pointer to data page 1 |
Пример
#include "pic17c43.h" #define KHZ 16384 /* Oscillator. */ #define BAUD 115200 /* Baud rate for RS-232 port. */ void init (); void main (); void putchar (); void print (); void _startup () @ 0 { awake (); init (); print ("Hello, World!\r\n"); while (! TRMT) awake (); asm ("halt"); } void init () { BSR = 0; /* Intialize the serial port. */ TXSTA = 0; SPBRG = ((KHZ * 1000 / BAUD) + 32) / 64 - 1; SPEN = 1; TXEN = 1; } void print (char far *s) { char c; for (;;) { c = *s++; if (! c) return; putchar (c); } } void putchar (char c) { again: awake (); if (! TRMT) goto again; TXREG = c; }