13.3.3. Определение параметров сигнала ШИМ

(Руководство разработчика по микроконтроллерам семейства HCS08)

Определение временных параметров сигнала ШИМ может быть реализовано с использованием одного из каналов таймера в режиме захвата. Однако в Примере 13.5 мы покажем альтернативный метод. Счетчик модуля таймера TMP будет использован для временной развёртки. Текущие значения счётчика считываются и запоминаются программой в моменты, соответствующие нарастающему и спадающему фронтам. Модуль KBI осуществляет захват фронтов и генерирует запросы на прерывание.

Рис.13.5. Прерывания по фронтам ШИМ-сигнала.

Следует отметить, что коэффициент счета счётчика выбран равным 4096 лишь потому, что функция измерения была позаимствована из Примера 13.6 «Управление скоростью вращения двигателя постоянного тока». В этом примере используется МК MC9S08QG8. Модуль таймера TMP в его составе используется для измерения параметров сигналов фазоимпульсной модуляции (ФИМ, англоязычная аббревиатура PPM — Pulse Position Modulation), и также формирует ШИМ-сигналы.

Если счётчик TMP переполняется в процессе измерения, т.е. изменяет свой код с 4095 на 0, то рабочая программа должна сначала вычесть его последнее значение last_tpm из 4096 и только потом прибавить текущее значение счетчика. Это реализуется следующим образом:

if(last_tpm>temp)//Еслипредшествующеезначениесчетчикабольшетекущего,
//рассчитатьдлительностьимпульса
{
pulse_width=(4096-last_tpm)+temp;
)
Else//Еслипредшествующеезначениесчетчикаменьшетекущего,
{//рассчитатьдлительностьимпульса
pulse_width=temp-last_tpm;

Каждый раз после захвата модулем KBI фронта сигнала выставляется флаг new_sample. Основная программа отслеживает этот флаг, и по факту его появления рассчитывает среднюю длительность импульса, усредняя восемь последних измерений. Результат усреднения записывается в переменную average_width.

Выходное реле включается при длительности импульса более 1.8мс и выключается при длительности менее 1.3мс.

Пример 13.5. Формирование ФИМ-сигнала

/*
КонтроллердляформированияФИМ-сигналанаосновеMC9S08QG8
АвторFаbioPereira(12/17/07)
Joinville-SC-Brasil
www.sctec.com.br
PTA0–выходФИМ
PTA2–выходреле
TPM:-измерениедлительностиимпульса(прерыванияпозахвату)
*/
#defineRELAYPTAD_PTAD2
#include
#include"derivative.h"
#include"hcs08.h"
volatileunsignedintpulse_width,average_width,sum_width;
volatileunsignedcharnew_sample;
#defineMY_NVFTRIM(*(constchar*__far)0x0000FFAE)
#defineMY_NVICSTRM(*(constchar*__far)0x0000FFAF)
//прерыванияпомодулюзахватаKBI
voidinterruptVectorNumber_Vkeyboard1kbi_isr(void)
{
staticunsignedintlast_tpm;
unsignedinttemp;
KBISC_KBACK=1;//Сбросфлагапрерывания
if(KBIES)//Проверкананарастающийфронт
{
last_tpm=TPMCNT;//СохранитьзначениясчетчикаTMP
KBIES=0;//Следующийфронт-спадающий
}
else//Проверканаспадающийфронт
{
temp=TPMCNT;//ЧтениетекущегозначениясчетчикаTMP
if(last_tpm>temp)//Еслипоследнеезначениесчетчикабольшетекущего,
{//рассчитатьдлительностьимпульса
pulse_width=(4096-last_tpm)+temp;
}
else//Еслипоследнеезначениесчетчикаменьшетекущего,
{//рассчитатьдлительностьимпульса
pulse_width=temp-last_tpm;
}
KBIES=BIT_0;//Следующийфронт-нарастающий
new_sample=1;//Установитьфлагв1
}
}
//Инициализациямикроконтроллера
voidMCU_init(void)
{
SOPT1=bBKGDPE;//Включитьвыводотладки
PTAD=0;
//ВключитьPTA0навход,PTA1-PTA5навыход
PTADD=BIT_1|BIT_2|BIT_3|BIT_4|BIT_5;
PTADS=BIT_0;//Разрешитьрежимконтроляскорости
//нарастаниянапряжениянапортуPTA0
SOPT2=0;
//НастройкавнутреннегогенераторатактовыхимпульсовимодуляICS
ICSSC=MY_NVFTRIM;//ЗадатьзначениеFTRIM
ICSTRM=MY_NVICSTRM;//ЗадатьзначениеTRIM
ICSC2=0;//BDIV=00b
//CPU=16МГц,BUSCLK=ICSCLK/2=8МГц
TPMSC=TPM_BUSCLK|TPM_DIV8;//ЧастотаTPMопределяетсякакBUSCLK/8(1МГц)
TPMMOD=4095;//ЗначениесчетчикаTPM=4096
//НастройкамодуляKBI
KBISC=bKBIE;//РазрешитьпрерыванияпоKBI
KBIPE=BIT_0;//PTA0каквходKBI
KBIES=BIT_0;//Чувствительностьзахватанарастающегофронта
KBISC_KBACK=1;//Сброситьфлагпрерывания
//Установкаглобальныхпеременных
sum_width=0;
new_sample=0;
average_width=0;
EnableInterrupts;//Разрешитьпрерывания(CCR:I=0)
}
voidmain(void)
{
MCU_init();
while(1)
{
if(new_sample)//Еслипросчитанадлительностьновогоимпульса
{
//Добавитьэтудлительностьксуммеостальныхивычестьсреднее
sum_width=sum_width+pulse_width-average_width;
//Подсчитатьновоесреднеезначение(суммаделитсяна8)
average_width=sum_width>>3;
new_sample=0;//Сброситьфлагnew_sample
}
//Включитьреле,еслидлительностьсигналабольше1.8мс
if(average_width>1800)RELAY=1;
//Выключитьреле,еслидлительностьсигналаменее1.3мс
if(average_width<1300)RELAY=0;
}
}

Электронные компоненты Freescale >>>
Подробнее о компании Freescale >>>