среда, 10 июля 2013 г.

Урок 4. Простая программа на C

<< Назад к оглавлению

ВНИМАНИЕ! ЭТО УСТАРЕВШАЯ СТАТЬЯ! НОВАЯ ЗДЕСЬ

Для нашей следующей программы понадобится компилятор Си. Его можно скачать в оглавлении. Так же понадобится файл линковщика для нашего контроллера. На всякий случай выкладываю его сюда.
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
Это позволяет использовать код ассемблера внутри программы на С

Файлы проекта:
 кода на С ссылка
https://yadi.sk/d/OeZ6mXRHVMZcF

Комментариев нет:

Отправить комментарий