📄 stim.c
字号:
/*
IEEE 1451.2 Implementation and Authoring Toolset
------------------------------------------------
Target Platform: Analog Devices Aduc812, and Evaluation Board.
This software is a complete working version that implements 2 channels
on the IEEE 1451.2 standard.
- The first channel is a simple temperature sensor (the AD590).
- The second channel is a simple actuator (a fan with two states: on or off)
Written by: Paul Conway
PEI Technologies Ltd.
Foundation Building
National Technological Park
Limerick
Ireland
http://www.ul.ie/~pei
For: Analog Devices
Version: 1.01
*/
#include <aduc812.h>
#include "datatype.h"
#include "function.h"
#include "stim.h"
#include "tii.h"
#include "teds.h"
/*
Note:
throughout the module definitions, the following coding practice
is in use:
- The module a function belongs in shall be indicated by a 2 - 4
letter prefix to the function name.
- A function name containing the word 'read' indicates that this
function sends data from the STIM to an NCAP over the TII.
- A function name containing the word 'write' indicates that this
function receives data from an NCAP and stores it inside the STIM.
- A function name containing the word 'set' indicates that this
function will set a value internal to the STIM.
- A function name containing the word 'get' indicates that this
function gets a value that is already internal to the STIM.
*/
// Channel Sensor / Actuator specific definitions to the
// current implementation go here.
// -----------------------------------------------------
//
// Define the bit that the Actuator (i.e. the Fan) on channel 2
// is controlled by.
//
sbit FAN_CH2 = P2 ^ 7;
// Module Level Variables:
// ----------------------
// The 'reset flag' indicates if a 'reset' was requested, and if so
// for which channel. It defaults to 'invalid channel' to indicate
// that there has not been a reset requested for any channel.
//
static U8E meResetFlag = INVALID_CHANNEL;
// Declare the Channels that will be in use. The channels are accessed
// via a 'CHANNEL' array. The channel located at position 0 in the
// array will represent CHANNEL_ZERO, the channel located at position
// 1 will represent CHANNEL 1, etc.
//
// note: there will be one CHANNEL for each XDCR, and one for CH_ZERO,
// hence the declaration for 'NUM_CHANNELS+1'
//
CHANNEL maChannelData[NUM_CHANNELS+1];
// STIM Functions:
// ---------------
CHANNEL* STIM_GetChHandle(unsigned char ucChNum)
{
if(ucChNum<=NUM_CHANNELS) return &maChannelData[ucChNum];
else return NULL;
}
boolean STIM_GetXdcrData(unsigned char ucChNum, unsigned char* pBuf)
{
boolean ret=TRUE;
if(pBuf)
{
switch(ucChNum)
{
case 1: *(unsigned int*)pBuf = maChannelData[ucChNum].Data.Ch1;
break;
case 2: *pBuf = maChannelData[ucChNum].Data.Ch2;
break;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Note: This is where data for any other channels will be returned.
Replace 'X' with the channel number.
The data-type will determine how the data is returned.
case X: *pBuf = maChannelData[ucChNum].Data.ChX;
break;
*/
default: ret=FALSE;
}
}
else
ret=FALSE;
return ret;
}
boolean STIM_SetXdcrData(unsigned char ucChNum, unsigned char *pBuf)
{
boolean ret=TRUE;
if(pBuf)
{
switch(ucChNum)
{
case 1: maChannelData[ucChNum].Data.Ch1 = *pBuf;
maChannelData[ucChNum].Data.Ch1 <<= 8;
maChannelData[ucChNum].Data.Ch1 |= *(pBuf+1);
break;
case 2: maChannelData[ucChNum].Data.Ch2 = *pBuf;
break;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Note: This is where data for any other channels will be set.
The data-type will determine how the data is set.
*/
default: ret=FALSE;
}
}
else ret=FALSE;
return ret;
}
void STIM_GetVersion(char* pVersion)
{
// let's keep it simple for now...
//
U32L Version = 0x00000000;
if(pVersion) *pVersion = Version;
}
void STIM_SoftReset(void)
{
unsigned char count;
// reset all channels
//
for(count=0; count<(NUM_CHANNELS+1); count++)
{
// Reset the standard and auxiliary status registers.
// Reset the 'transducer-data' field.
//
maChannelData[count].StdStatus = 0;
maChannelData[count].AuxStatus = 0;
maChannelData[count].Data.ChData = 0;
// set the 'reset' and 'operational' bits in standard status register
//
maChannelData[count].StdStatus |= STD_RESET_COMPLETE;
maChannelData[count].StdStatus |= STD_OPERATIONAL;
}
}
void STIM_InitialReset(void)
{
unsigned char count;
// do the standard 'soft' reset for all channels
//
STIM_SoftReset();
for(count=0; count<(NUM_CHANNELS+1); count++)
{
// reset standard and auxiliary interrupt registers.
//
maChannelData[count].StdIntMask = 0xFFFF;
maChannelData[count].AuxIntMask = 0x0000;
}
}
void STIM_ChannelReset(unsigned char ucChNum)
{
if( ucChNum>0 && ucChNum<(NUM_CHANNELS+1) )
{
maChannelData[ucChNum].StdStatus = 0;
maChannelData[ucChNum].AuxStatus = 0;
maChannelData[ucChNum].Data.ChData = 0;
// set the 'reset' and 'operational' bits in standard status register
//
maChannelData[ucChNum].StdStatus |= STD_RESET_COMPLETE;
maChannelData[ucChNum].StdStatus |= STD_OPERATIONAL;
// note: don't change the 'channel data length' field.
}
}
void STIM_SetResetFlag(U8E eFlag)
{
meResetFlag = eFlag;
}
U8E STIM_GetResetFlag(void)
{
return meResetFlag;
}
// Initialize the channels specific to this implementations:
// --------------------------------------------------------
//
void STIM_InitCh1(void)
{
// Initialise the Sensor (AD590):
// -----------------------------
// Set up Port 1.0 as an analog input port (i.e. Sensor Input on ADC0)
// - this is done by writing 1 to that SFR bit.
//
P1 = P1 | 0x01;
ADCCON1 = 0x6C; // ADCCON1 01101100
// SFR explanatory comments...
// MD1 MD0
// 0 1 => ADC normal mode
// CK1 CK0
// 1 0 => Clock divide ratio = 4
// AQ1 AQ0
// 1 1 => time for acquisition = 8 ADC clks
// T2C
// 0 => timer 2 overflow not used as conv start bit
// EXC
// 0 => ext pin 23 not used as conv start bit
ADCCON3 = 0x00; // ADCCON3 00000000
// SFR explanatory comments...
// BUSY X X X CTYP CAL1 CAL0 CALST
// BUSY = 0 => read only. set during conversion.
// CTYP = 0 => Internal calibration
// CAL1 CAL0
// 0 0 => 'full' calibration?? - not used now.
// CALST = 0 => calibration not initiated
ADCCON2 = 0x00; // Don't enable any data conversion mode yet:
// SFR explanatory comments...
// ADCI=0 => interrupt bit. will be set at end of cycle.
// DMA=0 => NOT pre-configured DMA mode
// CCONV=0 => NOT continuous conversion mode
// SCONV=0 => DON'T initiate single conversion mode YET!
// 4 LSBs=0 => ch 0 selected
}
void STIM_InitCh2(void)
{
// Initialise the Actuator:
// -----------------------
// Set up Port 2.7 as a digital output (i.e. Actuator Output)
// - this is done by writing 0 to that SFR bit.
//
FAN_CH2 = 0;
}
unsigned int STIM_GetCh1Sample(void)
{
unsigned int uiSample1=0;
unsigned char ucSample2=0;
// Set the 'single sample' bit in ADCCON2 to initiate a 'single
// conversion cycle' on ADC channel 0
//
ADCCON2 = 0x00; // ADC channel 0
SCONV = 1; // ...single conversion mode
// Wait for the ADC interrupt (i.e. sample acquired) bit ...
//
while( !ADCI )
;
// A sample has been acquired - read it out of the data SFR
//
uiSample1 = ADCDATAH;
ucSample2 = ADCDATAL;
uiSample1 <<= 8;
uiSample1 = uiSample1 | ucSample2;
SCONV = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -