Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы_по_Семисалову[1].DOC
Скачиваний:
32
Добавлен:
25.09.2019
Размер:
7.69 Mб
Скачать

2.3.7. Пример программирования модуля ацп.

Описание задачи.

Измерить силу тока в цепи якоря двигателя постоянного тока. Допустимая сила тока по паспорту двигателя составляет 10А.

1. Схема эксперимента:

В качестве датчика тока используем стандартный шунт Rш, рассчитанный на максимальный ток 10А и выдающий при этом токе напряжение на выходе U вых. = 0,75mV.

Схема подключения в этом случае имеет вид:

Т екст программы:

#define XTAL_FREQ 4MHZ

#define byte unsigned char

#define word unsigned int

#include <pic.h>

#include <stdio.h>

__CONFIG(HS & WDTDIS & PWRTEN & LVPDIS & DUNPROT & WRTEN);

void main() {

TRISA = 0x01; // RA0 на выход

ADCON0 = 0x41; // настройка АЦП

ADCON1 = 0X80

OPTION = 0x08; // настройка TMR0

TOIF = 0; // сброс флага TMR0

TMR0 = 0x13; // пуск TMR0

for(; !TOIF ;) { } // ожидание срабатывания таймера

ADIF = 0; // сброс флага АЦП

GO/-DONE = 1; // пуск АЦП

for (;!ADIF ;) { } // ожидание преобразования АЦП

TXREG = ADRESH; // передача в USART старшего байта АЦП

TXREG = ADRESL; // передача в USART младшего байта АЦП

} // конец main

Примечание. Настройку модуля USART см. в соответствующем разделе.

  1. Таймер tmr0.

Данный таймер имеет следующие основные функциональные возможности:

- 8-разрядный таймер-счетчик,

- возможность чтения и записи текущего состояния счетчика,

- 8-разрядный программируемый предделитель входных импульсов,

- внутренний или внешний источник тактовых входных импульсов,

- выбор активного фронта входных импульсов,

- возможность формирования запроса на прерывание при переполнении счетчика.

Блок-схема таймера TMR0 показана на рис 1.8.

Настройка таймера TMR0 осуществляется с помощью регистра OPTION-REG (адрес 81h или 181h). Распределение разрядов и обозначение сигналов регистра приведены в таблице 16.

Таблица 16.

Номер разряда

7

6

5

4

3

2

1

0

Обозначение сигнала

-

-

TOCS

TOSE

PSA

PS2

PS1

PS0

Назначение сигналов:

TOCS – выбор тактового сигнала для таймера TMR0:

1- внешний тактовый сигнал с вывода RA4,

0- внутренний тактовый сигнал CLKOUT ,

TOSE – выбор фронта входного сигнала для таймера:

1 – приращение счетчика таймера по заднему фронту входного сигнала,

0 – то же по переднему фронту,

PSA – выбор способа использования предделителя:

1 – предделитель включен перед сторожевым таймером – WDT,

0 – предделитель включен перед таймером TMR0,

PS2:PS0 – установка коэффициента деления предделителя: см. таблицу 5

Принцип работы таймера типовой для большинства таймеров. Вначале производится настройка таймера в соответствии с вышеизложенным. Поскольку счетчик таймера работает на сложение, в регистр TMR0 записывается дополнительный код требуемого времени:

N = FF – t * Т,

где: t – интервал времени в сек, Т – период входного тактового сигнала . Период входного сигнала определяется как величина обратная частоте входного сигнала. Входной сигнал формируется либо внутренним генератором: F = Fosc / 4, либо внешним генератором через вход RA4 (см. таблицу 4)

После переполнения счетчика (регистр TMR0) формируется сигнал готовности таймера – установка в 1 сигнала TOIF (регистр INTCON <2>), который является также сигналом требования прерывания. Само же прерывание может быть разрешено установкой в 1 сигнала TOIE (регистр INTCON <5>). После обработки прерывания сигнал требования прерывания TOIF должен быть программно сброшен в 0. Следующий интервал времени будет получен при повторной записи в регистр TMR0.

Примечания:

  1. После записи в регистр TMR0 первые два машинных цикла запрещается подача входных импульсов в счетчик таймера, что вызовет задержку начала формирования интервала времени.

  2. Запись в регистр TMR0 сбрасывает предделитель не изменяя его режим работы.

Пример программирования работы таймера TMR0 на языке СИ.

Данный таймер можно использовать в качестве элемента задержки в контроллерах электроавтоматики станков с ЧПУ. Дополним приведенный выше фрагмент электроавтоматики условием отключения Кп после задержки в 500 мсек. с помощью таймера TMR0. Для простоты будем использовать внутренний генератор тактовых импульсов частотой 4 МГц, откуда тактовая частота равна: Fclk = Fosc /4 = 1МГц, а период соответственно Тclk = 1 мксек.

Время срабатывания таймера рассчитывается из условия:

t = nn * Tclk,

где nn – число импульсов, пришедших в счетчик таймера.

Tclk – период входных импульсов таймера.

Так как счетчик таймера TMR0 работает на суммирование, то в него записывается дополнительный код:

mm = FF – nn,

поэтому максимальный период срабатывания таймера (при mm =0) будет равен:

Тмах = 256 х Tclk = 256 мксек., где:

256 – максимальная емкость 8-ми разрядного регистра TMR0,

Для получения большей задержки перед таймером включается предделитель (см. бит PSA <3> в регистре OPTION-REG). Этот прием позволит еще увеличить время задержки в 256 раз:

Тмах = 256 * 256 = 65536 мксек

Однако и этого приема недостаточно для получения требуемой задержки, поэтому увеличим задержку за счет формирования нескольких циклов срабатывания таймера:

К = 500 000 / 65536 = 7,629 .

Поскольку число циклов может быть только целым, принимаем К = 8.

Тогда максимально возможное число импульсов будет равно:

Mmax = 65536 * 8 = 524288

поэтому разность 24288 компенсируем за счет уменьшения задержки на самом таймере с учетом предделителя:

mm = 24288 / 256 = 94,875, принимаем : mm = 95 , или в шестнадцатиричной системе счисления: mm = 5D. Данное число будем записывать в регистр TMR0 таймера.

Программа работы фрагмента электроавтоматики (см. раздел 1.6) совместно с задержкой в 500 мсек будет имет вид:

#define XTAL_FREQ 4MHZ //Частота тактового генератора 4 MHZ

#define byte unsigned char

#define word unsigned int

#include <pic.h>

#include <stdio.h>

__CONFIG(HS & WDTDIS & PWRTEN & LVPDIS & DUNPROT & WRTEN);

void main() {

char chet = 0x00; //сброс счетчика числа циклов таймера

TRISB = 0xff; // порт В на вход

TRISC = 0x00; // порт С на выход

OPTION = 0x07; // предделитель перед таймером TMR0,

// коэффициент деления предделителя 1:256

for(;;) { // цикл всей программы

for (;!RC0 ;) {

RC0 = (RB0&&RB1&&RB2&&RB4) || (RB0&&RB2&&!RB3&&RB4;

} // решение булевых уравнений фрагмента

TOIF = 0; // сброс флага TMR0 - начальный

for (chet = 0x00; chet < 0x08; chet ++ ) { //счет циклов таймера

T0IF = 0; // сброс флага таймера в цикле

TMR0 = 0x5D; //пуск таймера TMR0

for (; !TOIF ;) { // цикл таймера TMR0

}

RC0 = 0; // отключение Кп

}

} // конец main