⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tbcmain.c

📁 基于cc1010的设计实例
💻 C
📖 第 1 页 / 共 2 页
字号:

    // 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 + -