?? psoft.c
字號(hào):
/***************************************************************************
* This code and information is provided "as is" without warranty of any *
* kind, either expressed or implied, including but not limited to the *
* implied warranties of merchantability and/or fitness for a particular *
* purpose. *
* *
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
***************************************************************************/
//**************************************************************************
// DESCRIPTION: 71M65xx POWER METER - Software pulsing.
// This code emits pulses on two DIO pins, PULSE3 and PULSE4, proportional
// to power inputs on the psoft_update() interface. Rename the DIO
// pins PULSE3 and PULSE4 in reg65xx.h to move the outputs to different pins.
// The pins for PULSE3 and PULSE4 have to be initialized in defaults.c.
// It uses the same units and interface as the CE pulse outputs,
// except implemented in software on the MPU.
// It generates 50% duty-cycle pulses, and is linear (within 0.0001%) from
// 150Hz to below 0.01 Hz, giving at least four decades of accuracy.
// Jitter is about 3.2 ms.
// It is preintegrated with the version 4 demo firmware, and
// can optionally count its pulses (See pcnt.c for more info on pulse counts).
//
// AUTHOR: RGV
//
// HISTORY: See end of file.
//**************************************************************************
// File: psoft.c
//
#include "options.h"
#if PULSE_SOFT
#include "library.h"
#include "psoft.h"
/*** Public variables declared within this module *** Selectable via "defaults" */
bool pulse3_val;
bool pulse4_val;
volatile int32i_t pulse3_accum;
volatile int32i_t pulse4_accum;
volatile int32i_t pulse3_inc;
volatile int32i_t pulse4_inc;
#if PULSE_CNT
uint16d_t dPulse3_Cnt, dPulse4_Cnt;
#endif
/*** Private functions declared within this module ***/
#pragma save
#pragma NOAREGS
// This routine can be called in the ce_busy interrupt, 2520/8 times
// per second, and from there it will use about 3% of the total CPU
// in real time. The hardware and software timers have too much jitter
// to run this routine and generate a stable pulse output.
// When run from the CE busy interrupt, the pulse outputs appear synchronized
// to the CE pulse outputs, even though they are simply done at the same
// frequency.
void psoft_out(void) small reentrant
{
// calculates pulse value without using I/O, in order to
// increase noise resistance
pulse3_accum += pulse3_inc;
if (pulse3_val != (pulse3_accum < 0)) // did bit 31 change?
{
// It has to change.
// If it's at the starting value, count it
#if PULSE_CNT
if (pulse3_val)
{
++dPulse3_Cnt; // count the pulse outputs
// This count needs to be added to a longer, 64 bit
// count once per second. See pcnt.c
}
#endif
pulse3_val = ~pulse3_val;
PULSE3 = pulse3_val; // set a DIO configured for output
}
// calculates pulse value without using I/O, in order to
// increase noise resistance
pulse4_accum += pulse4_inc;
if (pulse4_val != (pulse4_accum < 0)) // did bit 31 change?
{
// It has to change.
// If it's at the starting value, count it
#if PULSE_CNT
if (pulse4_val)
{
++dPulse4_Cnt; // count the pulse outputs
// This count needs to be added to a longer, 64 bit
// count once per second. See pcnt.c
}
#endif
pulse4_val ^= 1;
PULSE4 = pulse4_val; // set a DIO configured for output
}
}
#pragma restore
// the inputs are watt hours, as generated by the CE, and set the pulse
// generators to blink at the same rate as CE pulse outputs, with the same
// units. This should be called each time a new accumulation interval has data.
void psoft_update (int32_t pulse3_in, int32_t pulse4_in)
{
bool ea_saved;
bool PulseFast, PulseSlow;
int32_t xdata Wrate;
#if M6520
uint32_t my_cestate;
#endif
// figure software pulse outputs pulse 3 and 4
// The designed maximum frequency is 157.54 Hz,
// somewhat over a practical 150 Hz spec.
// The CE code has a pulse rate 3x2520Hz,
// the CE_BUSY interrupt skips 7, a 1/8 decimation of 2520 Hz.k
#if M6520
my_cestate = memget_ce(&cestate);
PulseFast = (0 != (my_cestate & CE_PULSE_FAST));
PulseSlow = (0 != (my_cestate & CE_PULSE_SLOW));
#elif TRACE10
PulseFast = (memget_ce (&pulse_fast) < 0) ? 0 : 1;
PulseSlow = (memget_ce (&pulse_slow) < 0) ? 0 : 1;
#elif HOST15
PulseFast = pulse_fast;
PulseSlow = pulse_slow;
#else
#error unknown device type
#endif
Wrate = memget_ce (&wrate);
pulse3_in = 3 * pulse3_in;
pulse4_in = 3 * pulse4_in;
if (!PulseSlow)
{
if (!PulseFast)
{
// simulated at 0.0001% error
pulse3_in = ((pulse3_in + 512L) >> 10) * Wrate;
pulse4_in = ((pulse4_in + 512L) >> 10) * Wrate;
}
else
{
// simulated at 0% (too small to print) error
// This case fails for speeds even slightly faster than 150 Hz
pulse3_in = ((pulse3_in + 32L) >> 6) * Wrate;
pulse4_in = ((pulse4_in + 32L) >> 6) * Wrate;
}
}
else
{
if (!PulseFast)
{
// simulated at 0.00006% error
// The 2^16 divisor causes 0.005% error by
// underflow unless the division is performed in two steps
pulse3_in = ((pulse3_in + 512L) >> 10) * Wrate;
pulse3_in = (pulse3_in + 32L) >> 6;
pulse4_in = ((pulse4_in + 512L) >> 10) * Wrate;
pulse4_in = (pulse4_in + 32L) >> 6;
}
else
{
// simulated at 0.0001% error
pulse3_in = ((pulse3_in + 2048L) >> 12) * Wrate;
pulse4_in = ((pulse4_in + 2048L) >> 12) * Wrate;
}
}
ea_saved = EA;
EA = 0;
pulse3_val = PULSE3; // update the pulse value
pulse4_val = PULSE4;
pulse3_inc = pulse3_in;
pulse4_inc = pulse4_in;
EA = ea_saved;
}
// Initialize the software pulse outputs
void psoft_init(void)
{
// the DIO for pulse3 and 4 should be configured in defaults
// for the starting values and direction
// start with pulse outputs high (bit 31 is put out)
pulse3_inc = 0;
pulse3_val = PULSE3; // set the starting polarity for the pulse
if (pulse3_val)
pulse3_accum = 0xC0000000;
else
pulse3_accum = 0x40000000;
pulse4_inc = 0;
pulse4_val = PULSE4; // set the starting polarity for the pulse
if (pulse4_val)
pulse4_accum = 0xC0000000;
else
pulse4_accum = 0x40000000;
#if M6520 // pulse3 and pulse4 are the same pins as OPT_RX and OPT_TX
DIO |= OPT_RXDIS; // disable OPT_RX, enable DIO1 = PULSE3
// Config2 is also affected by ser1.h, which contains code
// to switch between an optical serial port, and optical pulse.
// It does this automatically, by the way, if the command line interface
// is in the system. See ser1cli.c for the high level code.
CONFIG2 = (CONFIG2 & !OPT_TXE) | _DIO2; // disable OPT_RX, enable DIO2/P4
#endif
}
#endif // PULSE_SOFT
/***************************************************************************
* History:
* $Log: psoft.c,v $
* Revision 1.15 2006/10/13 00:51:11 tvander
* Removed compile options for 6530, 6515;
* renamed 6511 and 6513 to trace11 and trace13;
* Binary verified unchanged from previous version.
*
* Revision 1.14 2006/09/09 01:14:40 gmikef
* *** empty log message ***
*
* Revision 1.13 2006/08/17 22:18:20 tvander
* Tested with 6513 and 6521F at 4.9mHz. Fails with 6521F at 614kHz.
*
* Revision 1.12 2006/08/08 18:46:13 tvander
* Added an option for 6515 test PCB
*
* Revision 1.11 2006/03/03 11:30:38 Michael T. Fischer
* Prep for 6530 LCD, etc.
*
* Revision 1.10 2006/01/16 20:11:29 tvander
* Clean Keil build, all versions
*
* Revision 1.9 2006/01/04 04:47:54 gmikef
* Switched RMS and VA calculations to use floating point. (and Calibration).
*
* Revision 1.7 2005/12/21 01:35:28 tvander
* 6513
*
* Revision 1.6 2005/09/22 23:45:19 tvander
* Clean build all models and unit tests, updated copyright to be fore Teridian
*
* Revision 1.5 2005/09/12 07:47:31 tvander
* Power measurement is stable, with no creep.
* VARh measurement is stable, with no creep.
* Pulse sources work.
* Full access to MPU variables.
* Rolled date.
* Clock software works.
*
* Revision 1.4 2005/08/30 18:19:46 gmikef
* *** empty log message ***
*
* Revision 1.3 2005/08/12 21:56:26 tvander
* Fixed logic error is flag decoding.
*
* Revision 1.2 2005/08/12 06:02:47 gmikef
* Added MPU temperature compensation for GAIN_ADJ.
* Added changes to support new CE 6521 code.
*
* Revision 1.1 2005/08/02 22:36:30 tvander
* Optional software pulse logic.
* Fixed build in 6511B and 6521B
*
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
* this program is fully protected by the United States copyright *
* laws and is the property of Teridian Semiconductor Corporation. *
***************************************************************************/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -