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

📄 mcdemo.c

📁 pic单片机驱动mcp2510源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 */
void checkMsg(void) {
    ulong id;
    unsigned char dlc;
    unsigned char buf[8];
    unsigned int flags;
    canStatus stat;
    int i;

    stat = canRead(&id, buf, &dlc, &flags);
    if (stat == canOK) {
        //  printf("Message rcvd: id=%d, dlc=%d, {%d,%d,%d,...}\r\n", (int)id, dlc, buf[0], buf[1], buf[2]);
        for (i = 0; i < FOLDER_COUNT; i++)
            if (checkFolderEnable(i) && folder_env[i] == id)
                break;
        if (i < FOLDER_COUNT) {
            if (flags & canMSG_RTR) {
                // An RTR message
                switch(i) {
                    case doc_MayorsDocument:
                        mpPending = 0; // txMP(0);
                        break;
                    case doc_Inputs:
                        txInputs();
                        break;
                }
            } else {
                // An ordinary message
                switch(i) {
                    case doc_KingsDocument: // KP
                        if (dlc == 8)
                            rxKP(buf);
                        break;
                    case doc_ParamSetting: // Parameter setting
                        if (dlc == 8)
                            rxParam(buf);
                        break;
                    case doc_LEDcontrol: // LED control
                        if (dlc >= 1) {
                            LEDsave = (uchar)(buf[0] & 3);
                            setLEDs(LEDsave);
                        }
                        break;
                    case doc_RequestInputs: // Request Inputs
                        txInputs();
                        break;
                }
                if (mpPending != 255) {
                    txMP(mpPending);
                    mpPending = 255;
                }
            }
        }
    }
}

// Extracts an Envelop number from a message; it starts at buf[0].
// The highest bit decides if it is an extended CAN id or not and is kept,
// the other two reserved or control bits are cleared.
// We support extended CAN as we must be able to detect 0x1fffffff for an
// undefined base number.
ulong extractEnvelope(uchar *buf) {
    return buf[0] + ((buf[1] + ((buf[2] +((buf[3] & 0x9f) << 8)) << 8)) << 8);
}
// Handle a King's Page. In buf, there is an 8 byte message.
void rxKP(uchar *buf) {
    ulong env; // Has to be long, even if we support only standard CAN.
    uchar i, folderNo, enableF, cmd;

    if (buf[0] == 0 || buf[0] == nodeNo) {
        switch(buf[1]) {
            case 0:  // KP0: Selects Action and Communication mode.
                if (buf[2] && buf[2] < 4)
                    actMode = (actModesT)buf[2];
                if (buf[3] && buf[3] < 4)
                    commMode = (commModesT)buf[3];

                switch(actMode) {
                    case ckReset:
#ifdef __WIN32__
                        // doReset() won't return, so we must show the status now.
                        mcThread->showCKStatus();
#endif
                        doReset();
                        break;
                    case ckFreeze:
                        doFreeze();
                        break;
                    case ckRunning:
                        doRun();
                        break;
                }
                canSetCommMode(commMode);
#ifdef __WIN32__
                mcThread->showCKStatus();
#endif
                break;

            case 1: // KP1: Provides the Base numbers, asks for a Mayor's response.
                env = extractEnvelope(buf+4);
                if ((env & 0x1fffffff) == 0x1fffffff)
                    baseNo = envInvalid;
                else if (env != 0)
                    baseNo = env;
                fixMPEnv();
                if (buf[2] != 0xff) {
                    mpPending = buf[2]; //  txMP(buf[2]);
                }
#ifdef __WIN32__
                mcThread->showCKStatus();
                mcThread->showFolders();
#endif
                break;

            case 2: // Assigns an Envelope to a Folder
                env = extractEnvelope(buf+2);
                folderNo = buf[6];
                enableF = (uchar)(buf[7] & 1);
                cmd = (uchar)(buf[7] >> 1); // We demand the reserved bits to be zero.

                // Find the folder with envelope env. Should there be more than one
                // folder with this envelope, all will not be found.
                for (i = 0; i < FOLDER_COUNT; i++)
                    if (folder_env[i] == env)
                        break;

                switch(cmd) {
                    case 0: // Keep current assignment, ignore folderNo, only regard enableF.
                        if (i < FOLDER_COUNT)
                            setFolderEnable(i, enableF);
                        break;
                    case 1: // Assign the envelope env to the folder folderNo.
                        // We do not allow more than one envelope per folder.
                        if (folderNo < FOLDER_COUNT) {
                            folder_env[folderNo] = env;
                            setFolderEnable(folderNo, enableF);
                        }
                        break;
                    case 3: // Transfer the envelope env to to the folder folderNo.
                        // The old assignment is cancelled.
                        if (i < FOLDER_COUNT) {
                            folder_env[i] = envInvalid;
                            setFolderEnable(i, 0);
                        }
                        if (folderNo < FOLDER_COUNT) {
                            folder_env[folderNo] = env;
                            setFolderEnable(folderNo, enableF);
                        }
                        break;

                    case 2: // Expel this envelope from any assignment. Folder No is ignored.
                        if (!enableF) { // AAE has to be 100.
                            if (i < FOLDER_COUNT) {
                                setFolderEnable(i, 0);
                                folder_env[i] = envInvalid;
                            }
                        }
                        break;

                    default:
                        break;
                }
#ifdef __WIN32__
                mcThread->showFolders();
#endif
                break;

            case 9:
                nodeNo = buf[3];
                fixMPEnv();
                if (buf[2] != 0xff) {
                    mpPending = buf[2]; // txMP(buf[2]);
                }
#ifdef __WIN32__
                mcThread->showCKStatus();
                mcThread->showFolders();
#endif

            case 16:
                // As the connection between folder and document is fixed, we do
                // not use these fields. We just make it possible to enable/disable
                // a folder without having to specify the envelope number.
                folderNo = buf[2];
                if (buf[4]) {
                    enableF = (uchar)(buf[4] & 0x40);
                    if (folderNo < FOLDER_COUNT)
                        setFolderEnable(folderNo, enableF);
#ifdef __WIN32__
                    mcThread->showFolders();
#endif
                }
                break;

            default:
                break;
        }
    }
}

void txMP(uchar pageNo) {
    uchar buf[8];
    buf[0] = 0;
    buf[1] = pageNo;
    if (commMode != ckSilent && pageNo < 2 &&
        folder_env[doc_MayorsDocument] != envInvalid) {
        switch(pageNo) {
            case 0:
                strcpy((char*)buf+2, "!EAN!"); // Clears buf[7] as well.
                break;
            case 1:
                strcpy((char*)buf+2, "SerNo"); // Clears buf[7] as well
                break;
        }
        if (canWrite(folder_env[doc_MayorsDocument], buf, 8, 0) != canOK)
            ; // canWriteFailures++;
    }
}


// Read the input variables (buttons, analogue value) and transmit a message.
//     Inputs    DLC = 2   RTR always enabled
//          line 0: Bit 0..1 Current LED status
//                  Bit 2..4 Buttons 0..2, current value
//                  Bit 5..7 Buttons 0..2, sticky (cleared at Tx).
//          line 1: Analog value, 0..255

void txInputs(void) {
    uchar buf[2];
    if (actMode == ckRunning && commMode == ckCommunicate &&
        folder_env[doc_Inputs] != envInvalid && checkFolderEnable(doc_Inputs)) {
        buf[0] = (uchar)((LEDsave & 3) | (getButtons() << 2) | (buttonsSticky << 5));
        buf[1] = (uchar)getAnalogue();
        if (canWrite(folder_env[doc_Inputs], buf, 2, 0) == canOK)
            buttonsSticky = 0;
        else
            ; // canWriteFailures++;
    }
}

// Parse a paramter setting doucument.
//      Parameter settings   DLC = 8
//        Page 0
//          line 0: 0 (page number)
//          line 1:  Period to transmit the Inputs document, 1..255, 0 no transmissions
//          line 2..7: 0
//
void rxParam(uchar *buf) {
    unsigned int pSave = txPeriod;
    txPeriod = buf[1] + (buf[2] << 8);
    if (pSave == 0 && txPeriod != 0) // Make sure a message is transmitted at once.
        txLastTime = timerValue()-txPeriod;

#ifdef __WIN32__
    mcThread->showModuleStatus();
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -