#include "../main/SystemInclude.h" #ifndef ENABLE_ACCPULSE #pragma message("[undefined] ENABLE_ACCPULSE") #elif(ENABLE_ACCPULSE) #define PTAR 0 #define PCCR0 1 #define PCCR1 2 #define PCCR2 3 #define PCCR3 4 #define PCCR4 5 #define PCCR5 6 #define PCCR6 7 #define PTAIV 8 #define PTAEX 9 #define PT_MAX 10 //****************************************************************************** s16 calibUnitPerPulse; u32 unitPerPulse; u16 PulsePeriod[PT_MAX]; //u16 PulsePeriod, PulseDuty, PulseDiv, PulseCapture; u32 pulseCounter; s16 targetPulse; // bool isPulseUpdaed; //****************************************************************************** //0.25s, 0.5s, 1s, 2s, 4s //const unsigned char PulseGain[] = {16, 8, 4, 2, 1}; //const u16 UpdateTimeVaule[] = {3850, 7372, 7372, 7372, 7372}; // 0.235s, 0.45s, 0.5s, 1s, 2s //const u16 MaxPulseOutput[]={ // MAX_TIMER_PULSE>>2, MAX_TIMER_PULSE>>1, MAX_TIMER_PULSE*1 , MAX_TIMER_PULSE*2, // MAX_TIMER_PULSE*4 }; // 0.25s, 0.5s, 1s, 2s, 4s const u8 PulseGain[] = {32, 16, 8, 4, 2, 1}; const u16 MaxPulseOutput[]={ MAX_TIMER_PULSE>>3, MAX_TIMER_PULSE>>2, MAX_TIMER_PULSE>>1, MAX_TIMER_PULSE*1 , MAX_TIMER_PULSE*2, MAX_TIMER_PULSE*4 }; // 0.25s, 0.5s, 1s, 2s, 4s //****************************************************************************** // USER PULSE ( MAX FR = 3600 NM3) const u16 UserHighPulsePeriod[]={ 1022, 511, 341, 255, 204, 170, 146, 128, 114, 102, 93, 85, 79, 73, 68, 64, 60, 55, 51, 48, 46, 45, 43, 41, 39, 37, 36, 35, 34, 33, 32, 31, 30 }; //> 32Hz < 512Hz const u16 UserLowPulsePeriod[]={8192, 4096, 2730, 2048, 1638, 1365, 1170, 1024}; // {4088, 2044, 1363, 1022}; //<32Hz //****************************************************************************** //select timer clock // for flowRate output pulse // set timer A0 //(DCO clk(FREQ) = 2000000) //2000000/32 = 62500 const u16 PULSE_TABLE[]={ 62500, 62499, 31250, 20833, 15625, 12500, 10416, 8928, 7812, 6944, 6250, 5681, 5208, 4807, 4464, 4166, 3906, 3676, 3472, 3289, 3125, 2976, 2840, 2717, 2604, 2500, 2403, 2314, 2232, 2155, 2083, 2016, 1953, 1893, 1838, 1785, 1736, 1689, 1644, 1602, 1562, 1524, 1488, 1453, 1420, 1388, 1358, 1329, 1302, 1275, 1250, 1225, 1201, 1179, 1157, 1136, 1116, 1096, 1077, 1059, 1041, 1024, 1008, 992, 976, 961, 946, 932, 919, 905, 892, 880, 868, 856, 844, 833, 822, 811, 801, 791, 781, 771, 762, 753, 744, 735, 726, 718, 710, 702, 694, 686, 679, 672, 664, 657, 651, 644, 637, 631, 625, 618, 612, 606, 600, 595, 589, 584, 578, 573, 568, 563, 558, 553, 548, 543, 538, 534, 529, 525, 520, 516, 512, 508, 504, 500, 496, 492, 488, 484, 480, 477, 473, 469, 466, 462, 459, 456, 452, 449, 446, 443, 440, 437, 434, 431, 428, 425, 422, 419, 416, 413, 411, 408, 405, 403, 400, 398, 395, 393, 390, 388, 385, 383, 381, 378, 376, 374, 372, 369, 367, 365, 363, 361, 359, 357, 355, 353, 351, 349, 347, 345, 343, 341, 339, 337, 336, 334, 332, 330, 328, 327, 325, 323, 322, 320, 318, 317, 315, 314, 312, 310, 309, 307, 306, 304, 303, 301, 300, 299, 297, 296, 294, 293, 292, 290, 289, 288, 286, 285, 284, 282, 281, 280, 279, 277, 276, 275, 274, 272, 271, 270, 269, 268, 267, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, 234, 233, 232, 231, 230, 229, 228, 228, 227, 226, 225, 224, 224, 223, 222, 221, 220, 220, 219, 218, 217, 217, 216, 215, 214, 214, 213, 212, 211, 211, 210, 209, 209, 208, 207, 206, 206, 205, 204, 204, 203, 202, 202, 201, 200, 200, 199, 199, 198, 197, 197, 196, 195, 195, 194, 194, 193, 192, 192, 191, 191, 190, 189, 189, 188, 188, 187, 187, 186, 186, 185, 184, 184, 183, 183, 182, 182, 181, 181, 180, 180, 179, 179, 178, 178, 177, 177, 176, 176, 175, 175, 174, 174, 173, 173, 172, 172, 171, 171, 170, 170, 169, 169, 168, 168, 168, 167, 167, 166, 166, 165, 165, 164, 164, 164, 163, 163, 162, 162, 161, 161, 161, 160, 160, 159, 159, 159, 158, 158, 157, 157, 157, 156, 156, 155, 155, 155, 154, 154, 153, 153, 153, 152, 152, 152, 151, 151, 150, 150, 150, 149, 149, 149, 148, 148, 148, 147, 147, 147, 146, 146, 146, 145, 145, 145, 144, 144, 144, 143, 143, 143, 142, 142, 142, 141, 141, 141, 140, 140, 140, 139, 139, 139, 138, 138, 138, 137, 137, 137, 137, 136, 136, 136, 135, 135, 135, 134, 134, 134, 134, 133, 133, 133, 132, 132, 132, 132, 131, 131, 131, 131, 130, 130, 130, 129, 129, 129, 129, 128, 128, 128, 128, 127, 127, 127, 127, 126, 126, 126, 126, 125, 125, 125, 125, 124, 124, 124, 124, 123, 123, 123, 123, 122, 122, 122, 122 }; /******************************************************************************/ void CapturePulseStart(u16 timerCLK) { // P3SEL |= BIT2; // P3DIR &= ~BIT2; // CAPTURECTL &= ~(MC0+MC1); // 关闭定时器 // CAPTURECCTL0 = COMPARE; // CAPTURECCR0 = targetPulse; // // CAPTURECTL = CONTINUOUS + DIV_1 + timerCLK; //TIMER_CLR; } /******************************************************************************/ void DisableCapturePulse(void) { // CAPTURECTL = TIMER_CLR; // CAPTURECCTL0 = COMPARE; // start timer A // CAPTUREEX0 = 0; // CAPTURECCR0 = 0; // DISABLE_CAPTURE_INTERRUPT; // P3SEL |= BIT2; // P3DIR &= ~BIT2; } /******************************************************************************/ void CloseFloawRatePulse(void) { // P3SEL &= ~BIT1; // 选择输出端口的第二功能 // P3DIR |= BIT1; // // // HIGH Effective: IO=LOW, PULSE OUT = HIGH; // // LOW Effective: IO=HIGH, PULSE OUT = LOW; // if(PulseLevel == (u16)LOW) P3OUT |= BIT1; // else P3OUT &= ~BIT1; // // PULSECCTL1 |= CCIFG; // PULSECTL = TIMER_CLR; // 关闭定时器 // PULSECCR1 = 0; // PULSECCR0 = 0; // PULSECCTL1 = 0; // // DISABLE_PULSE_INTERRUPT; // DISABLE_CAPTURE_INTERRUPT; // isPulseUpdaed = 1; // // CAPTURECTL = TIMER_CLR; // CAPTURECCTL0 = COMPARE; // start timer A // CAPTUREEX0 = 0; // CAPTURECCR0 = 0; // // DMADisableInterrupt(2); // DMADisableAndStop(2); HWState.PulseOperate = 0; } /******************************************************************************/ void CompareLossCount(void) { // u16 countTemp; // // // systemAlarm.Bit.PulseAlarm = 1; // // compute lose pulse // countTemp = CAPTURETAR; // targetPulse = CAPTURECCR0; // // CAPTURECTL |= TIMER_CLR; // if(countTemp >= (targetPulse >> 1)) // { // targetPulse -= countTemp; // if(targetPulse > 50) targetPulse = 50; // } // else if(targetPulse == 0) // { // isPulseUpdaed = 1; // } // else // { // targetPulse = 0; // isPulseUpdaed = 1; // } } /******************************************************************************/ void ReadyForCalibrationPulseOutput(void) { u16 countTemp; // 计算已发出的脉冲数 if(HWState.PulseOperate) { // countTemp = CAPTURETAR; // targetPulse = (u16)CAPTURECCR0; // targetPulse -= countTemp; // CAPTURECTL |= TIMER_CLR; } else targetPulse = 0; // 判定是否已经超过发送脉冲数 targetPulse += (s16)totalPulse; if(targetPulse <= 0) { CloseFloawRatePulse(); return; } // 计算定时器计数值 totalPulse = (u16)targetPulse; totalPulse *= PulseOutGain[samplingInterval]; totalPulse >>= 2; if(totalPulse >= MaxPulseOutput[RESP_1000MS]) totalPulse = MaxPulseOutput[RESP_1000MS]; else if(totalPulse == 0) totalPulse = 1; //--------------------------------------------------------------------------- // Table //PulsePeriod[PCCR0] = PULSE_TABLE[totalPulse]; //--------------------------------------------------------------------------- // Compute // if(totalPulse < 16){ // PulsePeriod[PTAEX]= TAIDEX_7; // PulsePeriod[PCCR0] = 62500/totalPulse; // } // else { // PulsePeriod[PTAEX]= TAIDEX_0; // PulsePeriod[PCCR0] = (u16)(500000/(unsigned long int)totalPulse); // } // //--------------------------------------------------------------------------- // PulsePeriod[PCCR1] = PulsePeriod[PCCR0] >> 1; // //--------------------------------------------------------------------------- // if(HWState.PulseOperate) { // DMA2CTL &= ~(DMAREQ + DMAEN); // DMADisableInterrupt(2); // //DMAInit(2, DMA_CAPTURE_UPDATE, BURST_BLOCK+DMASA_INC+DMADA_INC, (u16)&PulsePeriod[PTAR], (u16)&PULSETAR, 3); // DMAInit(2, DMA_CAPTURE_UPDATE, BURST_BLOCK+DMASA_INC+DMADA_INC, (u16)&PulsePeriod[PTAR], (u16)&PULSETAR, PT_MAX); // countTemp = CAPTURETAR; // if(countTemp == targetPulse) { // CloseFloawRatePulse(); // return; // } // // CAPTURECCR0 = targetPulse; // //PULSECTL |= UP_CCR0; // PULSECCTL0 &= ~CCIFG; // DMA2CTL |= DMAREQ + DMAEN; // } // // 首次启动设置 // else{ // // HIGH Effective: IO=LOW, PULSE OUT = HIGH; // // LOW Effective: IO=HIGH, PULSE OUT = LOW; // if(PulseLevel == (u16)LOW) { // CapturePulseStart(TIMER_TACLK); // PULSECCTL1 = OUT_RESET_SET; // } // else { // CapturePulseStart(TIMER_INVTACLK); // PULSECCTL1 = OUT_SET_RESET; // } // // PulsePeriod[PTAR] = 0; // PulsePeriod[PCCR2] = 0; // PulsePeriod[PCCR3] = 0; // PulsePeriod[PCCR4] = 0; // PulsePeriod[PCCR5] = 0; // PulsePeriod[PCCR6] = 0; // PulsePeriod[PTAIV] = 0; // // PULSECTL = TIMER_CLR; // PULSECCR0 = PulsePeriod[PCCR0]; // PULSECCR1 = PulsePeriod[PCCR1]; // // PULSEEX0 = PulsePeriod[PTAEX]; // TAIDEX_7; // P3SEL |= BIT1; // P3DIR |= BIT1; // PULSECTL = UP_CCR0 + DIV_8 + TIMER_SMCLK + TIMER_CLR; // for SMCLK = 4MHz // } HWState.PulseOperate = 1; } //****************************************************************************** void ReadyForUserPulseOutput(void) { //select timer clock // for flowRate output pulse // stop pulse output capture timer // for 32768Hz if(totalPulse == 0) { CloseFloawRatePulse(); return; } //--------------------------------------------------------------------------- // 计算脉冲定时值 // targetPulse = (u16)totalPulse; // totalPulse = (u16)targetPulse; // totalPulse *= PulseOutGain[samplingInterval]; // totalPulse >>= 2; // if(totalPulse >= MaxPulseOutput[RESP_1000MS]) totalPulse = MaxPulseOutput[RESP_1000MS]; // else if(totalPulse == 0) totalPulse = 1; // //--------------------------------------------------------------------------- // if(totalPulse < 32) PULSECCR0 = UserLowPulsePeriod[totalPulse >> 2]; // else // { // totalPulse >>= 5; // if(totalPulse > 32) totalPulse = 32; // PULSECCR0 = UserHighPulsePeriod[totalPulse]; // } // // CAPTURECTL |= TIMER_CLR; // PULSECTL |= TIMER_CLR; // P3SEL |= BIT1; // P3DIR |= BIT1; // PULSECCR1 = PULSECCR0 >> 1; // // // HIGH Effective: IO=LOW, PULSE OUT = HIGH; // // LOW Effective: IO=HIGH, PULSE OUT = LOW; // if(PulseLevel == (u16)LOW) // { // PULSECCTL1 = OUT_RESET_SET; // CapturePulseStart(TIMER_TACLK); // } // else // { // PULSECCTL1 = OUT_SET_RESET; // CapturePulseStart(TIMER_INVTACLK); // } // // // 设置捕获关闭 // PulsePeriod[0] = (u16)TIMER_CLR; // CAPTURECCTL0 &= ~CCIFG; // DMADisableInterrupt(2); // DMAInit(2, DMA_CAPTURE_CLOSE, SINGLE_TRAN+DMASA_UNCHANGED+DMADA_UNCHANGED, (u16)&PulsePeriod, (u16)&PULSECTL, 1); // DMA2CTL |= DMAREQ + DMAEN; // // PULSEEX0 = 0; // PULSECTL = UP_CCR0 + DIV_1 + TIMER_ACLK + TIMER_CLR; HWState.PulseOperate = 0; } /******************************************************************************/ //set up flowRate PULSE OUTPUT void UpdateAccPulse(void) { if(currentMode.Bit.CalibMode) ReadyForCalibrationPulseOutput(); else { pulseCounter += (u32)totalPulse; //if(factoryUnitPerPulse <= CALIB_PULSE_DEFAULT) ReadyForCalibrationPulseOutput(); //else ReadyForUserPulseOutput(); } totalPulse = 0; targetPulse = 0; } /******************************************************************************/ void PulseParameterInit(void) { // for pulse output unit ReadMultiByteFromEEPROM(PULSE_UNIT, tempL.Byte, PULSE_UNIT_WIDTH, PARA_EEPROM); if(tempL.Byte[PULSE_UNIT_CRC] != CRC8(tempL.Byte, PULSE_UNIT_CRC)) factoryUnitPerPulse = PULSE_UNIT_DEFAULT; else factoryUnitPerPulse = tempL.Word[0]; ReadMultiByteFromEEPROM(CALIB_PULSE, tempL.Byte, CALIB_PULSE_WIDTH, PARA_EEPROM); if(tempL.Byte[CALIB_PULSE_CRC] != CRC8(tempL.Byte, CALIB_PULSE_CRC)) calibUnitPerPulse = CALIB_PULSE_DEFAULT; else calibUnitPerPulse = tempL.Word[0]; // for pulse output cunter // ReadMultiByteFromEEPROM(PULSE_COUNTER, tempL.Byte, PULSE_COUNTER_WIDTH, PARA_EEPROM); // if(tempL.Byte[PULSE_COUNTER_CRC] != CRC8(tempL.Byte, PULSE_COUNTER_CRC)) pulseCounter = 0; // else pulseCounter = tempL.Word[0]; ReadMultiByteFromEEPROM(PULSE_LEVEL, tempL.Byte, PULSE_LEVEL_WIDTH, PARA_EEPROM); if(tempL.Byte[PULSE_LEVEL_CRC] != CRC8(tempL.Byte, PULSE_LEVEL_CRC)) PulseLevel = (u16)PULSE_LEVEL_DEFAULT; else PulseLevel = (u16)tempL.Byte[0]; // HIGH Effective: IO=LOW, PULSE OUT = HIGH; // LOW Effective: IO=HIGH, PULSE OUT = LOW; DisableCapturePulse(); CloseFloawRatePulse(); } /******************************************************************************/ u32 InitPulseUnit(s16 unitPulse) { switch(unitPulse) { //case PULSE_0_1ML: return PULSE_0_1ML_VAL; case PULSE_1ML: return PULSE_1ML_VAL; case PULSE_10ML: return PULSE_10ML_VAL; case PULSE_100ML: return PULSE_100ML_VAL; case PULSE_1L: return PULSE_1L_VAL; case PULSE_10L: return PULSE_10L_VAL; case PULSE_100L: return PULSE_100L_VAL; case PULSE_1000L: return PULSE_1000L_VAL; //case PULSE_10000L: return PULSE_10000L_VAL; default: return InitPulseUnit(PULSE_UNIT_DEFAULT); } } #endif