Саньку спасибо за ответ.
Вопрос к разработчикам по поводу работы блока выходной модуляции.
Задача - менять ШИМ по синусоидальному закону. На выходе ССOUT63 все получилось. Мне необходимо перенаправить на выход СС60. Пытаюсь использовать блок выходной модуляции для перенаправления сигнала таймера Т3 на СС60 - ничего не выходит: либо сигнала нет, либо прерывания сыплются чаще. Исходник примера прилагаю, проблемное место в самом конце текста. Внесите ясность пожалуйста.
Код: Выделить всё
//----------------------------------------------------------------------------------------------------
#include <K1887VE3T.H>
#include <intrins.h>
//----------------------------------------------------------------------------------------------------
// !!! ЭТО ВСЕ ПРЕАМБУЛА, СУТЬ ВОПРОСА В КОНЦЕ ФУНКЦИИ void sinus_example(void) !!!
//----------------------------------------------------------------------------------------------------
//Частота ядра, Гц
#define FCPU 20000000
//---------------------
#define iNo_T12 0x4D
#define iNo_T13 0x4E
#define iNo_CCU6E 0x4F
#define iNo_CCU6 0x50
//#define DENIS
//----------------------------------------------------------------------------------------------------
sfr __CCU6_IC = 0xF120;
//----------------------------------------------------------------------------------------------------
//Приоритеты прерываний
enum INTERRUPT_LEVELS
{//-------------------------------------->
// GLVL: 0 /**/ 1 /**/ 2 /**/ 3 /**/ 4 /**/ 5 /**/ 6 /**/ 7
//
/* ^ ILVL:15 */NET0 ,/**/iLvl_T4,/**/iLvl_CAP6,/**/iLvl_T12,/**/,NET4,/**/ NET5 ,/**/ NET6 ,/**/ NET7 ,
/* | ILVL:14*/,NET8 ,/**/ NET9 ,/**/ NET10 ,/**/ NET11,/**/, NET12 ,/**/ NET13 ,/**/ NET14 ,/**/ NET15 ,
/* | ILVL:13*/ NET16 ,/**/ NET17 ,/**/ NET18 ,/**/ NET19 ,/**/, NET20 ,/**/ NET21 ,/**/ NET22 ,/**/ NET23 ,
/* | ILVL:12*/ NET24 ,/**/ NET25 ,/**/ NET26 ,/**/ NET27 ,/**/, NET28 ,/**/ NET29 ,/**/ NET30 ,/**/ NET31 ,
/* | ILVL:11*/ NET32 ,/**/ NET33,/**/ NET34 ,/**/ NET35 ,/**/, NET36 ,/**/ NET37 ,/**/ NET38 ,/**/ NET39 ,
/* | ILVL:10*/ NET40 ,/**/ NET41 ,/**/ NET42 ,/**/ NET43 ,/**/, NET44 ,/**/ NET45 ,/**/ NET46 ,/**/ NET47 ,
/* | ILVL:9 */ NET48 ,/**/ NET49 ,/**/ NET50 ,/**/ NET51 ,/**/, NET52 ,/**/ NET53 ,/**/ NET54 ,/**/ NET55 ,
/* | ILVL:8 */ NET56 ,/**/ NET57 ,/**/ NET58 ,/**/ NET59 ,/**/, NET60 ,/**/ NET61 ,/**/ NET62 ,/**/ NET63 ,
/* | ILVL:7 */ NET64 ,/**/ NET65 ,/**/ NET66 ,/**/ NET67 ,/**/, NET68 ,/**/ NET69 ,/**/ NET70 ,/**/ NET71 ,
/* | ILVL:6 */ NET72 ,/**/ NET73 ,/**/ NET74 ,/**/ NET75 ,/**/, NET76 ,/**/ NET77 ,/**/ NET78 ,/**/ NET79 ,
/* | ILVL:5 */ NET80 ,/**/ NET81 ,/**/ NET82 ,/**/ NET83 ,/**/, NET84 ,/**/ NET85 ,/**/ NET86 ,/**/ NET87 ,
/* | ILVL:4 */ NET88 ,/**/ NET89 ,/**/ NET90 ,/**/ NET91 ,/**/, NET92 ,/**/ NET93 ,/**/ NET94 ,/**/ NET95 ,
/* | ILVL:3 */ NET96 ,/**/ NET97 ,/**/ NET98 ,/**/ NET99 ,/**/,NET100 ,/**/ NET101 ,/**/ NET102 ,/**/ NET103 ,
/* | ILVL:2 */NET104 ,/**/NET105 ,/**/NET106 ,/**/NET107 ,/**/,NET108 ,/**/ NET109 ,/**/ NET110 ,/**/ NET111 ,
/* | ILVL:1 */NET112 ,/**/NET113 ,/**/NET114 ,/**/NET115 ,/**/,NET116 ,/**/ NET117 ,/**/ NET118 ,/**/ NET119
};
#define ILVL(LVL) ((((LVL)^0x78)>>3)&0xF)
#define GLVL(LVL) ((LVL)&0x7)
#define PLEV(LVL) (((LVL)&0x30)<<8)
#define INIT_INT_LEVEL(LVL,ENA,REQ) (LVL&0x3)|((LVL&0x4)<<6)|(ILVL(LVL)<<2)|((ENA)<<6)|((REQ)<<7)
//----------------------------------------------------------------------------------------------------
#ifndef DENIS
unsigned int volatile sdata *const SRCP_[8]=
{&SRCP0,&SRCP1,&SRCP2,&SRCP3,&SRCP4,&SRCP5,&SRCP6,&SRCP7};
unsigned int volatile sdata *const DSTP_[8]=
{&DSTP0,&DSTP1,&DSTP2,&DSTP3,&DSTP4,&DSTP5,&DSTP6,&DSTP7};
unsigned int volatile sdata *const PECSN_[8]=
{0xFED0,0xFED2,0xFED4,0xFED6,0xFED8,0xFEDA,0xFEDC,0xFEDE};
#else
extern unsigned int volatile sdata *const SRCP_[8];
extern unsigned int volatile sdata *const DSTP_[8];
extern unsigned int volatile sdata *const PECSN_[8];
#endif
#define PECC(lvl) (*(((unsigned int volatile sdata *)(&PECC0))+((GLVL(lvl)&0x3)|((ILVL(lvl)&0x1)<<2))))
#define SRCP(lvl) *SRCP_[((GLVL(lvl)&0x3)|((ILVL(lvl)&0x1)<<2))]
#define DSTP(lvl) *DSTP_[((GLVL(lvl)&0x3)|((ILVL(lvl)&0x1)<<2))]
//----------------------------------------------------------------------------------------------------
typedef short int16;
typedef unsigned short uint16;
//----------------------------------------------------------------------------------------------------
//Синусоида для выдачи на ШИМ
#define SIN_PNT_COUNT 10
#define PWM_P_MAX (uint16)((FCPU)/(2000*SIN_PNT_COUNT))
#define PWM_P_HALF (PWM_P_MAX>>1)
static int16 idata SinData[SIN_PNT_COUNT]=
{0x00C0,0x01E2,0x30B,0x03C9,0x03D4,0x0327,0x0205,0x00DC,0x001E,0x0013};
//----------------------------------------------------------------------------------------------------
#define PECREINI() do{\
SRCP(iLvl_CAP6)=_sof_(SinData);\
PECC(iLvl_CAP6)=PLEV(iLvl_CAP6)|SIN_PNT_COUNT|(2<<9);\
}while(0)
//---------------------------------------------------------------------------------------------------
extern unsigned long _tst2;
//Прерывание для переинициализации ПЕК
void hz20030isr(void) interrupt iNo_CCU6
{
#ifdef DENIS
_tst2++;
#endif
PECREINI();
}
//----------------------------------------------------------------------------------------------------
void sinus_example(void)
{
static idata kicker=(1<<14)|(1<<6);
/* Disable XBUS for CAN module */ /* 2 Kbytes of XSFR area -> CAP6 */
XBCON1=0; XADRS4=0xE83; XBCON4=0x14BF;
//Настройка пек для запроса теневой передачи Т3 по period match T2
DSTP(iLvl_T12)=_sof_(&CCU6_TCTR4);
SRCP(iLvl_T12)=_sof_(&kicker);
PECC(iLvl_T12)=PLEV(iLvl_T12)|0xFF;
CCU6_T12IC=INIT_INT_LEVEL(iLvl_T12,1,0);
//На всякий случай делаем так, чтобы запрос теневой передачи
// и засылка нового значения синуса не совпадали с моментом переполнения таймера T3
CCU6_T13=10;
//Настройка пек для передачи из масива в регистр сравнения T3
DSTP(iLvl_CAP6)=_sof_(&CCU6_CC63SR);
PECREINI();
//Задаем период
CCU6_T12PR=PWM_P_MAX-1;
CCU6_T13PR=PWM_P_MAX-1;
CCU6_TCTR4=(1<<6)|(1<<14); //Эта строка для работы симулятора
//Разрешаем прерывания в CAPCOM6
CCU6_IEN=(1<<7)| //period match T2
(1<<0); //compare ENCC60R
//Разрешаем выходы порта
ALTSEL0P1L|=((1<<6)|(1<<0));
_bfld_(DP1L,(1<<6)|(1<<0),(1<<6)|(1<<0));
__CCU6_IC=INIT_INT_LEVEL(iLvl_CAP6,1,0);
//-----------------------------------------------------
#if 0
//Вариант для выдачи ШИМ на выход CCOUT63, работает как и ожидалось
CCU6_MODCTR=(1<<15);
#else
//Вариант для выдачи ШИМ на выход CC60, работает неправильно
CCU6_MODCTR=(1<<7)| //Multi channel mode
(1<<8); //T3->CC60
CCU6_MCMOUTS=0x81;
//Если этой строки не написать - на выходе ничего нет,
//если написать - прерывания идут чаще чем нужно
CCU6_T12MSEL=0x1;
#endif
//-----------------------------------------------------
//GO !
CCU6_TCTR4=
(1<<1)| //T2R
(1<<9); //T3R
}
//----------------------------------------------------------------------------------------------------