На очередном видеоуроке мы научимся регулировать скорость вращения нашего двигателя при помощи МК PIC.
Разберёмся чуть подробнее с нашей ручной газа. Рассмотрим реальное положение дел.
В крайнем левом положении, которое должно соответствовать мощности 0%, напряжение на бегунке переменного резистора не равно 0В. Допустим, около 0,1В. Значит, наш АЦП намеряет около 2-4ИЕ. Записав эти данные в регистр OCR2, мы видим с вами на осциллографе тонкие иголки.
Поворачивая переменный резистор, мы увеличиваем напряжение на бегунке переменного резистора и как следствие на входе АЦП. Измеренное значение записываем в регистр OCR2, тем самым увеличивая заполнение.
Достигнув крайнего правого положения, которое соответствует мощности 100%, напряжение на бегунке, в идеале, должно равняться 5В. На самом деле оно или немногим меньше, к примеру 4,91В или больше, к примеру 5,09.
В первом случае АЦП намеряет немногим меньше максимума, что-то около 251ИЕ. На осциллограмме мы видим длинный импульс и коротенькие паузы в виде иголок.
Во втором АЦП выдаст максимум 255ИЕ, несмотря на то, что напряжение в реальности больше. Загрузив это значение в регистр OCR2, на выходе получаем сплошной уровень +5В без переключений.
Настраивая периферию МК, я привык детально комментировать регистры, такой подход занимает много строк. Шапка программы разрастается. В предыдущем уроке инициализация периферии заняла 34 строки. В нашем уроке это уже 232 строки. Да и функций становится больше и больше. Лично мне трудно ориентироваться в таком длинном коде.
Спасение я нашёл в заголовочных файлах. Содержимое этих файлов автоматически добавляется препроцессором в исходный текст в том месте, где располагается директива include.
Файловая структура программы теперь выглядит следующим образом: основной код содержится в main.c, все строки инициализации периферии вынесены в файл initHard.c, в initHard.h размещены объявления функций содержащихся в initHard.c.
Итак разберём программу…
Ручку газа подключаем к АЦП – pin13, RC2/CPP1. Выход ШИМ последовательности наблюдаем на pin2, RA0/AN0.
Настроим соответствующие линии порта…
TRISCbits.TRISC2 = 0; //Настраиваем RC2/CCP1 на вывод, ручка газа TRISAbits.TRISA0 = 1; //Настраиваем RA0/AN0 на ввод, АЦП
Для того, чтобы запустить модуль CCP в режиме ШИМ, необходимо включить таймер 2. Настроим его…
В соответствии с даташитом выбираем частоту ШИМ последовательности 1,22кГц.
//T2CKPS1:T2CKPS0: Timer2 Clock Prescale Select bits //00= Prescaler is 1 //01= Prescaler is 4 //1x= Prescaler is 16 T2CKPS0 = 0; T2CKPS1 = 1;
Включаем таймер.
//TMR2ON: Timer2 On bit //1= Timer2 is on //0= Timer2 is off TMR2ON = 1;
Запускаем модуль CCP1 в режиме ШИМ.
//CCPxM3:CCPxM0: CCP1 Mode Select bits //… //11xx=PWM mode CCP1M0 = 0; CCP1M1 = 0; CCP1M2 = 1; CCP1M3 = 1;
Загружаем в регистр периода таймера 2 значение, соответствующее частоте 1,22кГц.
PR2 = 255; //Установка периода 1,22кГц
Напоследок настроим АЦП. Выберем левое выравнивание результата.
//ADFM: A/D Result Format Select bit //1= Right justified. 6 Most Significant bits of ADRESH are read as С0Т. //0= Left justified. 6 Least Significant bits of ADRESL are read as С0Т. ADFM = 0;
Выберем аналоговую линию.
//PCFG3:PCFG0: A/D Port Configuration Control bits //Mode 1110: AN5-AN1 is digital, AN0 is analog PCFG0 = 0; PCFG1 = 1; PCFG2 = 1; PCFG3 = 1;
Включим модуль АЦП.
//ADON: A/D On bit //1= A/D converter module is operating //0= A/D converter module is shut-off ADON = 1;
Рассмотрим основной код. С заголовком вы уже знакомы.
#define _XTAL_FREQ 20000000 //Указываем тактовую частоту процессора #include //Содержит в себе макроопределения, в частности __CONFIG #include "pic16f876a.h" //Файл определения имён регистров, портов... #include "initHard.h" //Содержит в себе определение процедур инициализации периферии __CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF);
Теперь основная процедура main. Инициализируем периферию.
//Инициализация периферии... initPORTs(); //Инициализация портов initTIMERs(); //Инициализация таймеров initCCPs(); //Инициализация CCP-модулей initADC(); //Инициализация АЦП
Далее, в бесконечном цикле выполняем три действия: запускаем преобразование, ждём окончания цикла преобразования, загружаем значение скважности в CCP модуль
//Бесконечный цикл while(1) { GO_DONE = 1; //Запуск преобразования АЦП __delay_us(100); //Пауза перед следующим измерением CCPR1L = ADRESH; //Загружаем значение скважности }
ПРОЕКТ С ИСХОДНЫМ КОДОМ И СИМУЛЯЦИЯ В PROTEUS во вложении.
Прикрепленные файлы:
- microchip.rar (83 Кб)
Комментарии (0) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация