Изучение микроконтроллера PIC18F452

Изучение микроконтроллера PIC18F452

В этой статье мы изучим возможность микроконтроллера  (в частности pic18f452) в плане использования АЦП (adc) , внешних прерываний (external interrupt).

Источник АЦП в PIC18F45xx — Аналого-Цифровое преобразование » PRO-диод (pro-diod.ru)

Статья основана на источнике указанном выше и переработана для МК типа PIC18FXX2, согласно даташиту и отладкой в макетке и MPLAB X 8 на программаторе PICKIT 3v3

Вот схема макета в Proteus

Собранная схема на макетной плате

Описание принципа работы прошивки

  1. При нажатии кнопок 1-3 происходит внешнее прерывание контроллера INT0-INT2
  2. В обработчиках этих прерываний производится запуск преобразования АЦП (аналого-цифровой преобразователь)
  3. Происходит прерывание АЦП, где в его обработчике вычисляется значение его регистров старшего и младшего ADRESH и ADRESL.  Но так как выравнивание результата влево, т.е. используем 8-ми битный режим АЦП (вместо 10 битного). Результат попадает в старший регистр ADRESL, откуда за счет глобальной переменной попадает в основную программу и выводится его битовый код в порт D в виде 8 –ми светодиодов. См. схему и прошивку/исходник.

Ниже код исходника pic18f452.c

/* Взято из источника :  https://pro-diod.ru/programms/pic-micro/acp-v-pic18f45xx-analogo-cifrovoe-preobrazovanie.html?ysclid=m050mtxq8j421044859

*Author: SHRB 01.10.2024 адаптировано для pic18f452, согласно мануала

*/

#include <xc.h> // можно подключить и #include <pic18f452.h>

#include "config_bits.h"

// #include "config_sett.h"

#define _XTAL_FREQ = 14000000 // частота 14 Мгц

unsigned char adresult0 = 0; // переменная для результата младший регистр ADRESL

unsigned char adresult1 = 0; // переменная для результата старший регистр ADRESH

void main()

{

// ---  это можно переместить в файл config_sett.h --- ///

TRISD = 0X00; // D настройка порта на выход - светодиоды

TRISB = 0X01; // B настройка порта на вход - кнопки

/* настройки для АЦП */

TRISAbits.RA0 = 1; // использование AN0/RA0 как вход

ADCON0bits.CHS  = 0b00000000; //  AN0/RA0 как вход для АЦП

ADCON1bits.PCFG = 0b00001001; // опорное напряжение на VDD (+5D), и VSS (GND) -

ADCON0bits.ADCS = 0b00000010; // делитель частоты FOSC/64 = 14000000 / 64 = 218.750 кГц

ADCON1bits.ADFM = 0; // левое выравнивание результата в регистрах

ADCON0bits.ADON = 1; // запуск модуля АЦП

// Настройка внешних прерываний

INTCONbits.INT0IE = 1; // разрешить прерывание INT0

INTCONbits.INT0IF = 0; // сброс флага прерывания INT0, у этого высокий приоритет всегда

INTCON3bits.INT1IE = 1; // разрешить прерывание INT1

INTCON3bits.INT1IP = 0; // приоритет прерывание INT1 - низкий

INTCON3bits.INT1IF = 0; // сброс флага прерывания INT1

INTCON3bits.INT2IE = 1; // разрешить прерывание INT2

INTCON3bits.INT2IP = 0; // приоритет прерывание INT2 - низкий

INTCON3bits.INT2IF = 0; // сброс флага прерывания INT2

// Настройка фронтов прерываний

INTCON2bits.INTEDG0 = 1; // по восходящему фронту  INT0

INTCON2bits.INTEDG1 = 1; // по восходящему фронту INT1

INTCON2bits.INTEDG2 = 1; // по восходящему фронту  INT2

// Настройки прерываний для АЦП

PIE1bits.ADIE     = 1; // разрешить прерывание АЦП

PIR1bits.ADIF     = 0; // сброс флага прерывания АЦП

IPR1bits.ADIP     = 0; // приоритет прерывания для АЦП низкий

// Общие настройки прерываний

INTCONbits.PEIE = 1; // разрешить периферийные прерывания

INTCONbits.GIE = 1; // разрешить глобальные прерывания

RCONbits.IPEN = 1;  // разрешить приоритетные прерывания

// ---  это можно переместить в файл config_sett.h --- ///

while(1) //главный цикл

{

   LATD = 0X00;        // сброс порта D

   LATD = adresult1;  // запись значения с АЦП в порт - светодиоды

}

}

// обработчики прерываний

__interrupt(high_priority) void inter_1 (void) // прерывания высокого приоритета

{

//--- INT0 ----------------------------------------------

if(INTCONbits.INT0IF == 1) // прерывание INT0

{   

INTCONbits.INT0IF = 0; // сброс флага

ADCON0bits.GO = 1;  // запуск преобразования АЦП

}   

}

__interrupt(low_priority) void high_isr(void) // прерывания низкого приоритета

{
if (PIR1bits.ADIF && PIE1bits.ADIE) {

    PIR1bits.ADIF = 0; // сброс флага

    adresult0 = ADRESL;  // результат АЦП

    adresult1 = ADRESH;   

    } // if (PIR1bits.ADIF && PIE1bits.ADIE)

//--- INT1 ----------------------------------------------

if(INTCON3bits.INT1IF == 1) // прерывание INT1

{      

INTCON3bits.INT1IF = 0; // сброс флага

ADCON0bits.GO = 1; // запуск преобразования АЦП

}

//--- INT2 ----------------------------------------------

if(INTCON3bits.INT2IF == 1)  // прерывание INT2

{     

INTCON3bits.INT2IF = 0; // сброс флага

ADCON0bits.GO = 1; // запуск преобразования АЦП

}

} // high_priority END

Ссылка на проект в Proteus 8

Ссылка на исходники

Ссылка на прошивку

Можно конечно файл сделать типа h еще.

Например , config_sett.h – в него скопировать все настройки АЦП, прерываний, а его прописать в главном с-файле в виде строки #include "config_sett.h"

В файле #include "config_bits.h", тоже подключенном в с-файле находятся настройки битов (конфигурация битов)

Как видно из фотографий, программирование производилось программатором PicKit 3, а отладка в среде MPLAB.

Удачных повторений и исследований, Умельцы! :)

 

Категория: Программирование | Добавил: shirko_rom (18.01.2025) E W
Просмотров: 141 | Теги: Замок на ключе-таблетке, Простой замок для сейфа, Электрозамок iButton | Рейтинг: 0.0/0
Всего комментариев: 0
avatar