最新电影在线观看,jrs低调看直播,avav天堂,囯产精品宾馆在线精品酒店,亚洲精品成人区在线观看

兩輪平衡車_6_調試上位機搭建

平衡車后續調試需要監控角度、加速度、速度等波形;思考了許久,之前學習Can驅動的時候自己寫了一個畫波形的上位機,這時候剛好能派得上場;軟件安裝和界面操作如下圖,先安裝軟件,在桌面上打開CanScope監控軟件,界面上運行模式選擇正常模式,點擊連接(連接失敗會提示),然后點擊啟動CAN,即可接收波形;操作界面上面還有發送CAN數據的界面,需要發數據給下位機可以通過該界面操作。

CAN用的是下面這個型號,上位機是基于該型號提供的驅動文件開發的,其他型號的CAN可能會連接不上;

F28035的CAN驅動程序是之前做項目一直沿用下來的,稍微修改了一下可以匹配上位機;使用時,只需要先用 InitCana()出始化,然后調用Can_Task()填充數據發送;

/******************************************************************************
 *    FILENAME : Bsp_Can.c
 *
 *    PURPOSE  : Can Initialization & Support Functions.
 *
 *       Author: 電筆小新                      Created on: 2025年9月12日
******************************************************************************/
#include "User_Include.h"
#include "Bsp_Can.h"

//==================================================================
// *  Variables & Function_Defines
//==================================================================
Uint16  CAN_command0 = 0;
Uint16  CAN_command1 = 0;

CANFRAME CAN_TxBuf;
CANFRAME CAN_RxBuf;

int16 SinTabCnt = 0;
int16 CosTabCnt = 100;

const int16 SinCosTab[400]={
    0,   64,  129,  193,  257,  321,  385,  449,  513,  577,
  641,  704,  768,  831,  894,  956, 1019, 1081, 1143, 1204,
 1266, 1327, 1387, 1448, 1508, 1567, 1627, 1686, 1744, 1802,
 1860, 1917, 1973, 2029, 2085, 2140, 2195, 2249, 2302, 2355,
 2408, 2459, 2510, 2561, 2611, 2660, 2709, 2757, 2804, 2850,
 2896, 2941, 2986, 3030, 3072, 3115, 3156, 3197, 3236, 3276,
 3314, 3351, 3388, 3423, 3458, 3492, 3526, 3558, 3589, 3620,
 3650, 3678, 3706, 3733, 3759, 3784, 3808, 3832, 3854, 3875,
 3896, 3915, 3933, 3951, 3967, 3983, 3997, 4011, 4023, 4035,
 4046, 4055, 4064, 4071, 4078, 4083, 4088, 4091, 4094, 4095,

 4096, 4095, 4094, 4091, 4088, 4083, 4078, 4071, 4064, 4055,
 4046, 4035, 4023, 4011, 3997, 3983, 3967, 3951, 3933, 3915,
 3896, 3875, 3854, 3832, 3808, 3784, 3759, 3733, 3706, 3678,
 3650, 3620, 3589, 3558, 3526, 3492, 3458, 3423, 3388, 3351,
 3314, 3276, 3236, 3197, 3156, 3115, 3072, 3030, 2986, 2941,
 2896, 2850, 2804, 2757, 2709, 2660, 2611, 2561, 2510, 2459,
 2408, 2355, 2302, 2249, 2195, 2140, 2085, 2029, 1973, 1917,
 1860, 1802, 1744, 1686, 1627, 1567, 1508, 1448, 1387, 1327,
 1266, 1204, 1143, 1081, 1019,  956,  894,  831,  768,  704,
  641,  577,  513,  449,  385,  321,  257,  193,  129,   64,

    0,  -64, -129, -193, -257, -321, -385, -449, -513, -577,
 -641, -704, -768, -831, -894, -956,-1019,-1081,-1143,-1204,
-1266,-1327,-1387,-1448,-1508,-1567,-1627,-1686,-1744,-1802,
-1860,-1917,-1973,-2029,-2085,-2140,-2195,-2249,-2302,-2355,
-2408,-2459,-2510,-2561,-2611,-2660,-2709,-2757,-2804,-2850,
-2896,-2941,-2986,-3030,-3072,-3115,-3156,-3197,-3236,-3276,
-3314,-3351,-3388,-3423,-3458,-3492,-3526,-3558,-3589,-3620,
-3650,-3678,-3706,-3733,-3759,-3784,-3808,-3832,-3854,-3875,
-3896,-3915,-3933,-3951,-3967,-3983,-3997,-4011,-4023,-4035,
-4046,-4055,-4064,-4071,-4078,-4083,-4088,-4091,-4094,-4095,

-4096,-4095,-4094,-4091,-4088,-4083,-4078,-4071,-4064,-4055,
-4046,-4035,-4023,-4011,-3997,-3983,-3967,-3951,-3933,-3915,
-3896,-3875,-3854,-3832,-3808,-3784,-3759,-3733,-3706,-3678,
-3650,-3620,-3589,-3558,-3526,-3492,-3458,-3423,-3388,-3351,
-3314,-3276,-3236,-3197,-3156,-3115,-3072,-3030,-2986,-2941,
-2896,-2850,-2804,-2757,-2709,-2660,-2611,-2561,-2510,-2459,
-2408,-2355,-2302,-2249,-2195,-2140,-2085,-2029,-1973,-1917,
-1860,-1802,-1744,-1686,-1627,-1567,-1508,-1448,-1387,-1327,
-1266,-1204,-1143,-1081,-1019, -956, -894, -831, -768, -704,
 -641, -577, -513, -449, -385, -321, -257, -193, -129,  -64,

};

//==================================================================
// *  FUNCTION:  SetGpio_Cana()
// *
// *  PURPOSE :  Initializes the GPIOs for CANa.
//==================================================================
//CAN的GPIO初始化
//這里采用GPIO30 GPIO31
//--------------------------------------------------------------------
void SetGpio_Cana(void)
{
   EALLOW;
    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;     // Enable pull-up for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;     // Enable pull-up for GPIO31 (CANTXA)

    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)

    //IO30 IO21配置為CAN外設引腳
    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;    // Configure GPIO30 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;    // Configure GPIO31 for CANTXA operation

    EDIS;
}

//==================================================================
// *  FUNCTION:  SetERegs_Cana()
// *
// *  PURPOSE :  Initializes the Registers for CANa.
//==================================================================
void SetERegs_Cana(void)        // Initialize eCAN-A module
{

/* Create a shadow register structure for the CAN control registers. This is
 needed, since only 32-bit access is allowed to these registers. 16-bit access
 to these registers could potentially corrupt the register contents or return
 false data. */

struct ECAN_REGS ECanaShadow;

    EALLOW;     // EALLOW enables access to protected bits

/* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/

    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

/* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
                                    // HECC mode also enables time-stamping feature

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;               //P35  Select eCAN mode.
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

/* Initialize all bits of 'Message Control Register' to zero */
// Some bits of MSGCTRL register come up in an unknown state. For proper operation,
// all bits (including reserved bits) of MSGCTRL must be initialized to zero

    ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//  as a matter of precaution.
    ECanaRegs.CANTA.all = 0xFFFFFFFF;   /* Clear all TAn bits */
    ECanaRegs.CANRMP.all = 0xFFFFFFFF;  /* Clear all RMPn bits */
    ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

/* Configure bit timing parameters for eCANA*/
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    // Wait until the CPU has been granted permission to change the configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );       // Wait for CCE bit to be set..

    ECanaShadow.CANBTC.all = 0;

    //-------------------------自定義的配置------------------------------------------
    //P47
    /* The following block is only for 60 MHz SYSCLKOUT. (30 MHz CAN module clock Bit rate = 1 Mbps
       See Note at end of file. */
    //rate Bit =(SYSCLKOUT/2)/(BRP * Bit-time )
    //BRP = BRPreg+1
    //Bit-time = (TSEG1reg + 1) + (TSEG2reg+ 1) + 1
    //配置TQ 和BRP ,
    //方案一 TQ為10, 則TSEG1REG = 6, BRP = 5 ,為500K
    //方案二,TQ為12,則TSEG1REG = 8, BRP = 4 ,為500K
    //500KHz
    ECanaShadow.CANBTC.bit.BRPREG = 5;
    ECanaShadow.CANBTC.bit.TSEG2REG = 1;
    ECanaShadow.CANBTC.bit.TSEG1REG = 6;
    ECanaShadow.CANBTC.bit.SAM = 1;
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0;    // Set CCR = 0
    ECanaShadow.CANMC.bit.STM = 0;    // 0: normal mode/1: self-test mode
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    // Wait until the CPU no longer has permission to change the configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );       // Wait for CCE bit to be  cleared..

/* Disable all Mailboxes  */
    ECanaRegs.CANME.all = 0;        // Required before writing the MSGIDs

    EDIS;
}

/**********************************************************************
* FUNCION :   SetMailbox_Cana()
* PURPOSE :   Initializes the Mailboxes for Can.
//-----------------------------------------------
//配置發送、接收郵箱等操作
//數據區8個長度字節
//發送郵箱   1到6
//接收郵箱   16, ID為0x0A
//-----------------------------------------------
**********************************************************************/
void SetMailbox_Cana(void)
{
   struct ECAN_REGS ECanaShadow;

   EALLOW;
    ECanaShadow.CANGAM.all = ECanaRegs.CANGAM.all;
    ECanaShadow.CANGAM.bit.AMI=1;            // Standard and extended frames can be received.
    ECanaRegs.CANGAM.all = ECanaShadow.CANGAM.all;
   EDIS;

//P59
//In standard identifier mode,if the IDE bit(MSGID.31) =0,the message identifier is storedin bits ID.28:18.
//IDE =0:The RECEIVED message had a standard identifier
//Auto answer mode bit. AAM =0 ;  Normal transmit mode
//AME = 1 ;The corresponding acceptance mask is used

//MSGID.31=IDE; MSGID.30=AME; MSGID.29=AAM
// Mailboxs can be written to 16-bits or 32-bits at a time

   // Mailboxes can be written to 16-bits or 32-bits at a time
      // Write to the MSGID field of TRANSMIT mailboxes MBOX0 - 15
      ECanaMboxes.MBOX0.MSGID.all = ( (TXCanId0_Std|0x10000000)<<18); // stand Identifier
      ECanaMboxes.MBOX1.MSGID.all = ( (TXCanId1_Std|0x10000000)<<18); // stand Identifier

      // Write to the MSGID field of RECEIVE mailboxes MBOX16 - 31
      ECanaMboxes.MBOX16.MSGID.all = ((RXCanId0_Std|0x10000000)<<18); // stand Identifier
      ECanaMboxes.MBOX17.MSGID.all = ((RXCanId1_Std|0x10000000)<<18); // stand Identifier

      // Configure Mailboxes 0-15 as Tx, 16-31 as Rx
      // Since this write is to the entire register (instead of a bit
      // field) a shadow register is not required.
      ECanaRegs.CANMD.all = 0xFFFF0000;

    // Specify that 8 bits will be sent/received //8字節數據
      ECanaMboxes.MBOX0.MSGCTRL.bit.DLC  = 8;
      ECanaMboxes.MBOX1.MSGCTRL.bit.DLC  = 8;

////////////////////////////////////////////////////////////////////////////////////
    EALLOW;
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.DBO = 1;
    ECanaShadow.CANMC.bit.SCB = 1;//Select eCAN mode
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    // Configure Mailboxes 0-15 as Tx, 16-31 as Rx
    ECanaRegs.CANMD.all = 0xFFFF0000;

    // Since this write is to the entire register (instead of a bit
    // field) a shadow register is not required.
    ECanaRegs.CANME.all = 0x00030003;
    EDIS;
}

//==================================================================
// *  FUNCTION:  SetInterrupt_Cana()
// *
// *  PURPOSE :  Initializes the ISR for CANa.
//==================================================================
void SetInterrupt_Cana(void)
{
/* Create a shadow register structure for the CAN control registers. This is
 needed, since only 32-bit access is allowed to these registers. 16-bit access
 to these registers could potentially corrupt the register contents or return
 false data. */
    struct ECAN_REGS ECanaShadow;

    EALLOW;     // EALLOW enables access to protected bits
    ECanaShadow.CANMIL.all = ECanaRegs.CANMIL.all;
    ECanaShadow.CANMIL.all = 0xFFFFFFFF ;            //P76, mailbox interrupts to level 1
    ECanaRegs.CANMIL.all = ECanaShadow.CANMIL.all;


    ECanaShadow.CANMIM.all = ECanaRegs.CANMIM.all;
    ECanaShadow.CANMIM.all =0x00010000 ;            //P48,相應的郵箱中斷使能位 Mailbox interrupt is enabled.
    ECanaRegs.CANMIM.all = ECanaShadow.CANMIM.all;

    //1-32號郵箱中斷在中斷線0上產生
    ECanaShadow.CANMIL.all = ECanaRegs.CANMIL.all;
    ECanaShadow.CANMIL.all = 0;
    ECanaRegs.CANMIL.all = ECanaShadow.CANMIL.all;


    //------------中斷配置步驟-----1
    //中斷線0使能
    ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all;
    ECanaShadow.CANGIM.bit.I0EN = 1;
//    ECanaShadow.CANGIM.bit.I1EN = 1;
    ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all;


// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//  as a matter of precaution.

    ECanaRegs.CANTA.all   = 0xFFFFFFFF;   /* Clear all TAn bits */
    ECanaRegs.CANRMP.all  = 0xFFFFFFFF;  /* Clear all RMPn bits */
    ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

//------------中斷配置步驟-----3
// Enable CAN in PIE
   PieCtrlRegs.PIEIER9.bit.INTx5 = 1;      // Enable INT 9.5 in the PIE
//   PieCtrlRegs.PIEIER9.bit.INTx6 = 1;      // Enable INT 9.6 in the PIE

//------------中斷配置步驟-----4
   IER |= M_INT9;                          // Enable CPU Interrupt 9

   EINT;
   ERTM;
   EDIS;

}

//==================================================================
// *  FUNCTION:  InitCana()
// *
// *  PURPOSE :   Initializes the Enhanced Can modules.
//==================================================================
void InitCana(void)
{
    SetGpio_Cana();
    SetERegs_Cana();
    SetMailbox_Cana();
    SetInterrupt_Cana();
}

//==================================================================
// *  FUNCTION:  sCanHdRead()
// *
// *  PURPOSE :   Read Can Data From Registers And Save Into Buffer.
//==================================================================
void sCanHdRead(const Uint8 ubMailBox,CANFRAME *pdata)
{
    volatile struct MBOX *pMailbox;

    pMailbox = &ECanaMboxes.MBOX0 + ubMailBox;

    pdata->CanId.all = pMailbox->MSGID.all;
    pdata->CanData0 = pMailbox->MDL.word.LOW_WORD;
    pdata->CanData1 = pMailbox->MDL.word.HI_WORD;
    pdata->CanData2 = pMailbox->MDH.word.LOW_WORD;
    pdata->CanData3 = pMailbox->MDH.word.HI_WORD;
}
//==================================================================
// *  FUNCTION:  sCanHdSend()
// *
// *  PURPOSE :  Write Can Data Into Registers And Send.
//==================================================================
void sCanHdSend(const Uint8 ubMailBox,const CANFRAME *pdata)
{
    struct ECAN_REGS ECanShadow;
    volatile struct MBOX *pMailbox;

    pMailbox = &ECanaMboxes.MBOX0 + ubMailBox;

    /*step3: Load the message to the MSGID Registers of the object*/
    pMailbox->MSGID.all= pdata->CanId.all;

    /*step4: configure the data length*/
    pMailbox->MSGCTRL.bit.DLC = 8;


    /*step5: Write the message data to the mail box data field*/
    pMailbox->MDL.word.LOW_WORD = pdata->CanData0;
    pMailbox->MDL.word.HI_WORD = pdata->CanData1;
    pMailbox->MDH.word.LOW_WORD = pdata->CanData2;
    pMailbox->MDH.word.HI_WORD = pdata->CanData3;

    /* Enable transmit mailbox*/
    ECanShadow.CANME.all = ECanaRegs.CANME.all;
    ECanShadow.CANME.all |= ((Uint32)1 << ubMailBox);
    ECanaRegs.CANME.all = ECanShadow.CANME.all;

    ECanShadow.CANTRS.all=0;
    ECanShadow.CANTRS.all|= ((Uint32)1 << ubMailBox);
    ECanaRegs.CANTRS.all= ECanShadow.CANTRS.all;

    ECanShadow.CANTA.all = 0;
    ECanShadow.CANTA.all |= ((Uint32)1 << ubMailBox);  // Clear all TAn
    ECanaRegs.CANTA.all=ECanShadow.CANTA.all;
}
//---------------------------------------------------------------------------
// Can_Task:
//---------------------------------------------------------------------------
void Can_Task(void)
{
   SinTabCnt++;
   if(SinTabCnt>399)
    {
       SinTabCnt=0;
    }
   CosTabCnt++;
   if(CosTabCnt>399)
    {
       CosTabCnt=0;
    }
   CAN_TxBuf.CanId.all = ((TXCanId0_Std|0x10000000)<<18); // stand Identifier
   CAN_TxBuf.CanData0 = SinCosTab[SinTabCnt];
   CAN_TxBuf.CanData1 = SinCosTab[CosTabCnt];
   CAN_TxBuf.CanData2 = 0x5432;
   CAN_TxBuf.CanData3 = 0x9876;
   sCanHdSend(0,&CAN_TxBuf);
}
//---------------------------------------------------------------------------
// INT_ISR for Ecana_RX
//---------------------------------------------------------------------------
//// INT9.5
interrupt void ECAN0INTA_ISR(void)  // eCAN-A
{
    struct ECAN_REGS ECanaShadow;
    // Insert ISR Code here
    ECanaShadow.CANRMP.all=ECanaRegs.CANRMP.all;
    if(ECanaShadow.CANRMP.bit.RMP16==1)
    {
        ECanaShadow.CANRMP.bit.RMP16=1;
        ECanaRegs.CANRMP.all=ECanaShadow.CANRMP.all;
        sCanHdRead(16,&CAN_RxBuf);
    }

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;     // Must acknowledge the PIE group
}

//==================================================================
// End of file.
//==================================================================
聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
本篇所含全部資料,點擊此處留下郵箱我會發給你
資料明細:附件為上位機安裝包和CAN驅動代碼
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 1
收藏 2
關注 85
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧