<< Назад к оглавлению
ВНИМАНИЕ! ЭТО УСТАРЕВШАЯ СТАТЬЯ! НОВАЯ ЗДЕСЬ
Для нашей следующей программы понадобится компилятор Си. Его можно скачать в оглавлении. Так же понадобится файл линковщика для нашего контроллера. На всякий случай выкладываю его сюда.
pic18f2550
без бутлоадера Ссылка
с HID бутлоадером Ссылка
pic18f4550
без бутлоадера Ссылка
с HID бутлоадером Ссылка
Файл линковщика .lkr говорит компилятору, какие библиотеки подключать и как использовать память контроллера. Например, если мы используем описанный в прошлом уроке бутлоадер, то мы должны подключить файл lkr с HID бутлоадером, и он сообщит компилятору, что программа должна располагаться после бутлоадера - с адреса 0x1000.
Итак, создаем проект в MPLAB
Это делается примерно так же как во втором уроке, только выбираем проект C и добавляем файл линковщика
Файл линковщика говорит о том, как мы собираемся использовать память контроллера. Поэтому и отличаются эти файлы, если мы используем бутлоадер или нет.
Далее привожу код программы. Это аналог программе, написанной в уроке 2.
#include <p18f2550.h> #pragma config WDT = OFF // #pragma config FOSC=INTOSCIO_EC // Выбран внутренний генератор #pragma config MCLRE = OFF // отключаем сигнал сброса #define REMAPPED_RESET_VECTOR_ADDRESS 0x1000 #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008 #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018 void main (void); #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS void _reset (void) { main(); } #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS void Remapped_High_ISR (void) { _asm NOP _endasm } #pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS void Remapped_Low_ISR (void) { _asm NOP _endasm } #pragma code page void delay(void) { long i; for (i=0;i<100000;i++); } void main (void) { TRISA = 0; PORTA = 0; while (1) { PORTAbits.RA2 = 1; delay(); PORTAbits.RA2 = 0; delay(); } ; } |
Все обозначения вроде портов и встроенных устройств можно найти в файле p18f2550.h или p18f4550.h.
директива #include <p18f2550.h> подключает заголовки для контроллера
#pragma config - Это опять же выбор конфигурационных битов для контроллера. См урок №2.
#define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
Эти три похожие строки говорят нам, что программа будет начинаться с адреса 0x1000, высокоприоритетное прерывание - с 0x1008 низкоприоритетное - с 0x1018.
Это сделано с одной целью - для того, чтобы программа могла быть прошита с помощью бутлоадера. Как было написано в предыдущем уроке, бутлоадер занимает ячейки до адреса 0x1000 и следовательно наша программа должна начинаться после его кода.
Ну и все прерывания бутлоадер будет отправлять по алресу 0x1008 и 0x1018
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void)
{
main();
}
Вот эти строки говорят, что следующий код будет начинаться именно с указанного адреса. В данном случая директива #pragma работает как команда ассемблера .ORG - то есть просит компилятор записать следующий код с определенной ячейки памяти. Вообще программа начнется с функции _reset. Потому что она идет первая по порядку. адрес 0x1000. Но после нее следуют еще прерывания. Поэтому когда происходит сброс контроллера, эта функция просто "перепрыгивает" код прерываний и запускает код за ними.
Но можно задать расположение программы в памяти еще с помощью скрипта линковшика. Посмотрите на эту строку.
#pragma code page
Это обозначает, что дальше будет программа записана в ту область, которая размечена в файле *lkr, как page
void delay(void)
{
long i;
for (i=0;i<100000;i++);
}
Вот это задается функция задержки. Она просто мотает переменную i до 100000 и ничего при этом не делает.
Вызывается функция следующей командой
delay();
void Remapped_High_ISR (void)
{
_asm NOP _endasm
}
Эта функция - прерывание. В нашем случае она ничего не делает. Но вы можете добавить код обработки прерываний сюда.
_asm
_endasm
Это позволяет использовать код ассемблера внутри программы на С