📄 tbcmain.c
字号:
// Initialize the SPP timer
sppStartTimer(CC1010EB_CLKFREQ);
SPP_INIT_TIMEOUTS();
// Reset the node IDs
for (n = 0; n < TBC_MAX_NODE_COUNT; n++) {
nodeIDs[n] = TBC_UNUSED_NODE_ID;
}
// Reset our name buffer
for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) {
nodeNames[0][n] = 0x00;
}
// Setup UART0 for polled I/O
UART0_SETUP(57600, CC1010EB_CLKFREQ, UART_NO_PARITY | UART_RX_TX | UART_POLLED);
// Get our name
VT100_CLEAR_SCREEN();
VT100_GO_TOP_LEFT();
// Removed so that CC1010EM can operate stand-alone
/* printf("\nEnter node name (use up to 20 characters):");
scanf("%s", &nodeNames[0][0]);*/
// Load name from Flash
memcpy(&nodeNames[0][0],flashUnitName,TBC_NODE_NAME_LENGTH);
// Get our ID from CRC16(our name)
nodeIDs[0] = culFastCRC16Block(&nodeNames[0][0], TBC_NODE_NAME_LENGTH, CRC16_INIT);
// Prepare the id+name part of the packet
txDataBuffer[0] = (nodeIDs[0] >> 8) & 0xFF;
txDataBuffer[1] = nodeIDs[0] & 0xFF;
for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) {
txDataBuffer[n + TBC_NODE_ID_LENGTH] = nodeNames[0][n];
}
// Loop forever
while (TRUE) {
tbcTransmit();
tbcPrintTable();
tbcWaitRandom();
tbcReceive();
tbcWaitRandom();
}
} // main
//----------------------------------------------------------------------------
// void tbcWaitRandom (void)
//
// Description:
// Wait for a random number of msecs (0 to 255*8=2040)
// Note: The function uses busy waiting
//----------------------------------------------------------------------------
void tbcWaitRandom (void) {
byte xdata time;
byte xdata n;
time = rand();
for (n = 0; n < waitMultiplier; n++) {
halWait (time, CC1010EB_CLKFREQ);
}
} // tbcWaitRandom
//----------------------------------------------------------------------------
// void tbcTransmit (void)
//
// Description:
// Update our temperature value (ADC) and transmit together with our node
// ID and node name.
//----------------------------------------------------------------------------
void tbcTransmit (void) {
word xdata temp;
// Indicate transmission
RLED = LED_ON;
YLED = LED_ON;
// Power up the ADC and sample the temperature
ADC_SAMPLE_SINGLE();
temp = ADC_GET_SAMPLE_10BIT();
// Update the TX buffer and the table with the new temperature
txDataBuffer[TBC_TEMP_OFFSET] = (temp >> 8) & 0xFF;
txDataBuffer[TBC_TEMP_OFFSET + 1] = temp & 0xFF;
nodeTemps[0] = temp;
nodeLastT[0] = (int) sppGetTime();
YLED = LED_OFF;
// Transmit the temperature
sppSend(&TXI);
do { /*nothing*/ } while (sppStatus() != SPP_IDLE_MODE);
RLED = LED_OFF;
} // tbcTransmit
//----------------------------------------------------------------------------
// void tbcReceive (void)
//
// Description:
// Receive a temperature broadcast packet and register it in the table
// Temperatures older than 30 secs get thrown out
//----------------------------------------------------------------------------
void tbcReceive (void) {
byte xdata n,m,o;
byte xdata nodeIndex;
word xdata nodeID;
// Throw out "old" nodes (no updates during the last 30 seconds)
for (n = 0; n < TBC_MAX_NODE_COUNT; n++) {
if (((int) sppGetTime() - nodeLastT[n]) > 3000) {
// Re-organize the list (by moving the remaining nodes up one index)
for (m = n; m < (TBC_MAX_NODE_COUNT - 1); m++) {
nodeIDs[m] = nodeIDs[m + 1];
for (o = 0; o < TBC_NODE_NAME_LENGTH; o++) {
nodeNames[m][o] = nodeNames[m + 1][o];
}
nodeTemps[m] = nodeTemps[m + 1];
nodeLastT[m] = nodeLastT[m + 1];
}
}
}
// Receive the packet (if any)
YLED = LED_ON;
sppReceive(&RXI);
do { /*nothing*/ } while (sppStatus() != SPP_IDLE_MODE);
YLED = LED_OFF;
// Process the packet
if (RXI.status == SPP_RX_FINISHED) {
GLED = LED_ON;
// Get the node ID
nodeID = (rxDataBuffer[0] << 8) + rxDataBuffer[1];
// Get the node's index in the temperature table
for (n = 0; n < TBC_MAX_NODE_COUNT; n++) {
if (nodeIDs[n] == nodeID) {
nodeIndex = n;
break;
} else if (nodeIDs[n] == TBC_UNUSED_NODE_ID) {
nodeIndex = n;
break;
} else {
nodeIndex = TBC_INVALID_NODE_INDEX;
}
}
// Update the table
if (nodeIndex != TBC_INVALID_NODE_INDEX) {
nodeIDs[nodeIndex] = nodeID;
for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) {
nodeNames[nodeIndex][n] = rxDataBuffer[n + TBC_NODE_ID_LENGTH];
}
nodeTemps[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET] << 8) + rxDataBuffer[TBC_TEMP_OFFSET + 1];
nodeLastT[nodeIndex] = (int) sppGetTime();
}
} else {
GLED = LED_OFF;
}
} // tbcReceive
//----------------------------------------------------------------------------
// void tbcPrintTable (void)
//
// Description:
// Executes keyboard commands (change of the waiting multiplier)
// Prints the temperature table to the terminal window
//----------------------------------------------------------------------------
void tbcPrintTable (void) {
int xdata n,m;
float xdata fTemp;
word xdata timeDiff;
// Receive key strokes
if (RI_0) {
RI_0 = 0;
if (isdigit(UART0_RECEIVE())) {
waitMultiplier = toint(UART0_RECEIVE());
} else if (UART0_RECEIVE() == 'd') {
for (n = 1; n < TBC_MAX_NODE_COUNT; n++) {
nodeIDs[n] = TBC_UNUSED_NODE_ID;
}
}
else if (UART0_RECEIVE() == 'n') {
memset(&nodeNames[0][0],0,TBC_NODE_NAME_LENGTH);
printf("\nEnter node name (use up to 20 characters):");
scanf("%s", &nodeNames[0][0]);
// Write new name into Flash
halCopy2Flash(flashUnitName,&nodeNames[0][0],TBC_NODE_NAME_LENGTH,
ramBufNonAligned, CC1010EB_CLKFREQ);
// Get our ID from CRC16(our name)
nodeIDs[0] = culFastCRC16Block(&nodeNames[0][0], TBC_NODE_NAME_LENGTH, CRC16_INIT);
// Prepare the id+name part of the packet
txDataBuffer[0] = (nodeIDs[0] >> 8) & 0xFF;
txDataBuffer[1] = nodeIDs[0] & 0xFF;
for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) {
txDataBuffer[n + TBC_NODE_ID_LENGTH] = nodeNames[0][n];
}
}
}
// Header:
VT100_GO_TOP_LEFT();
// Items:
printf("TEMPERATURE LIST:");
for (n = 0; n < TBC_MAX_NODE_COUNT; n++) {
if (nodeIDs[n] == TBC_UNUSED_NODE_ID) {
continue;
}
// Node number and ID:
printf("\n%01X. (0x%X) ", n, nodeIDs[n]);
// Node name:
for (m = 0; m < TBC_NODE_NAME_LENGTH; m++) {
UART0_WAIT_AND_SEND(nodeNames[n][m]);
}
// Temperature:
fTemp = nodeTemps[n];
fTemp -= 492;
fTemp /= 8.192;
printf(" - TEMP: %3.2f", fTemp);
// Time after the last update
timeDiff = abs((int) sppGetTime() - nodeLastT[n]) * 10;
printf(" - AGE (msecs): %d", timeDiff);
VT100_CLEAR_LINE_RIGHT();
}
// Available keyboard input options
VT100_INSERT_BLANK_LINE();
printf("\nPress '0'-'9' to change the waiting multiplier");
VT100_CLEAR_LINE_RIGHT();
printf("\nPress 'd' to empty the table");
VT100_CLEAR_LINE_RIGHT();
printf("\nPress 'n' to give the unit a new name");
VT100_CLEAR_LINE_RIGHT();
VT100_CLEAR_SCREEN_DOWN();
} // tbcPrintTable
// Flash interrupt handler (do nothing)
// We need to handle the interrupt even though we do not do anything.
// If not, the program will not run correctly except under the debugger,
// which has its own Flash interrupt handler
void FlashIntrHandler(void) interrupt INUM_FLASH {
INT_SETFLAG(INUM_FLASH, INT_CLR);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -