单片机TwinCAN调试心得

发布者:梅花居士最新更新时间:2017-01-10 来源: eefocus关键字:单片机  TwinCAN  调试心得 手机看文章 扫描二维码
随时随地手机看文章

1、  帧类型

(1)       数据帧:数据帧将数据从发送器传输到接收器

(2)       远程帧:总线单元发出远程帧,请求发送具有同一标识符的数据帧。/ MSGDRn4。

(3)       错误帧:任何单元检测到总线错误就发出错误帧

(4)       过载帧:过载帧用于在先行和后续数据帧(或远程帧)之间提供一附加的延时。

数据帧和远程帧即可使用标准帧,也可使用扩展帧。

2、  帧格式介绍

1  数据帧

数据帧由7个不同的位场组成,即帧起始、仲裁场、控制场、数据场、CRC场、应答场、帧结束。

2  远程帧

远程帧由6个不同的位场组成,即帧起始、仲裁场、控制场、CRC场、应答场、帧结束。

3  错误帧

错误帧由两个不同的场组成。第一个场是错误标志,用做为不同站提供错误标志的叠加;第二个场是错误界定符。

4  超载帧

超载帧包括两个位场:超载标志和超载界定符。

3、  报文路由:报文的内容由识别符命名。识别符不指出报文的目的地,但解释数据的含义。因此,网络上所有的节点可以通过报文滤波确定是否应对该数据做出反应。

4、  不同的系统,CAN 的速度不同。可是,在一给定的系统里,位速率是唯一的,并且是固定的。

5、  该模块分为两个节点,NODE A和NODE B,32个对象可以通过MSGCFGHn.NODE位来分别选择将该对象分配到哪个节点。

6、  该32个报文对象只能作为接受对象或发送对象,不能在接收和发送之间转换。作为接收对象的必须在初始化的时候首先将其配置成接收对象。

7、  回环模式可方便的用于调试,ABTR.LBM = 1和BBTR.LBM = 1,使能回环模式。在回环模式下,属于节点A的对象发送的报文只能由属于节点B的对象接受,反之亦如此。

8、  报文接收时可对所接收的报文进行验收滤波,称为报文标识符验收滤波。它们分别通过仲裁寄存器(MSGARHn,MSGARLn)(ID)和验收屏蔽寄存器(MSGAMRHn,MSGAMRLn)设置实现。具体过程如下:

 

9、  几个结构体的说明:

(1)       该寄存器用于软件编程,说明如下

typedef struct

  {

     uword  ;   // 消息配置寄存器

     ulong  ulID;       // 扩展标识 (29-bit)

     ulong  ulMask;     // 标准验收屏蔽(11-bit)/扩展验收屏蔽 (29-bit)

     ubyte  ubData[8];  // 八个字节数据

     uword  uwCounter;  // 当前接收对象接收到数据的帧数CAN_BFCRL或//CAN_AFCRL

  }TCAN_SWObj;

uwMsgCfg一般用到低字节,各位代表的意义如下:

         7     6     5      4    3     2     1     0

      |-----------------------------------------------------------------------|

      |        DLC            | DIR | XTD | NODE | RMM |

      |------------------------------------------------------------------------|

(2)       每个CAN对象寄存器结构体

struct stCanObj

{

  ubyte  ubData[8];  // Message Data 0..7

  ulong  ulCANAR;    // Arbitration Register

  ulong  ulCANAMR;   // Acceptance Mask Register

  uword  uwMSGCTR;   // Message Control Register

  uword  uwCounter;  // Frame Counter

  uword  uwMSGCFG;   // Message Configuration Register

  uword  uwINP;      // Interrupt Node Pointer

  uword  uwCANFCR;   // FIFO / Gateway Control Register

  uword  uwCANPTR;   // FIFO Pointer

  ulong  ulReserved; // Reserved

};

 

10、              几个重要寄存器的意义:

 

n.RXIE报文对象接收中断使能(=10)

.TXIE----报文对象发送中断使能(=10)

(3)       MSGCTRHn.MSGVAL---报文对象有效(=10)

(4)       MSGCTRHn.NEWDAT---报文对象中数据已更新(=10)

(5)       MSGCTRHn.MSGLST---NEWDAT仍然置位,CAN控制器已将报文保存到该报文对象中,而先前的报文丢失(=10),仅用于接受

(6)       MSGCTRHn.CPUUPD---报文对象自动发送被禁止(=10);可由CAN控制器自动发送报文对象中的数据(=01)

(7)       MSGCTRHn.TXRQ---CPU或远程帧请求的报文对象数据发送被挂起(=10)。报文成功发送后,TXRQ自动复位;如果存在几个有效的报文对象又挂起的发送请求,报文编号最低的报文对象将被首先发送

(8)       MSGCTRHn.RMTPND---远程节点请求报文对象数据发送,但数据并未发送。当RMTPND被置位时,CAN节点控制器也置位TXRQ.

 

.RMM---该发送报文对象的远程监控模式被使能。带匹配标识符远程帧的标识符和DLC码被复制到发送报文对象中,以监控输入的远程帧。该位仅对发送报文有效,对接受报文无影响。

(2)       MSGCFGHn.NODE---报文对象CAN节点选择,0=A,1=B

(3)       MSGCFGHn.XTD-----报文对象扩展标识符,1=11位,0=29位

(4)       MSGCFGHn.DIR------报文对象方向控制,0=定义该报文为发送对象,1=定义该报文为接受对象

(5)       MSGCFGHn.DLC-----报文对象数据长度码

(6)       MSGCFGHn.RXINP/TXINP---分别为接收/发送中断节点指针,0~7

 

11、              发送后一定要判断TXOK时候置位,确保在发送下一组数据之前将数据发送完成

12、              附程序:

 

H

 

#ifndef _CAN_H_

#define _CAN_H_

 

 

// The following data type serves as a software message object. Each access to

// a hardware message object has to be made by forward a pointer to a software

// message object (TCAN_SWObj). The data type has the following fields:

//

// uwMsgCfg:

// this byte has the same structure as the message configuration register of a

// hardware message object. It contains the "Data Lenght Code" (DLC), the

// "Extended Identifier" (XTD), the "Message Direction" (DIR), the "Node

// Select" and the "Remote Monitoring Mode".

//

//

//         7     6     5      4    3     2     1     0

//      |------------------------------------------------|

//      |        DLC            | DIR | XTD | NODE | RMM |

//      |------------------------------------------------|

//

// ulID:

// this field is four bytes long and contains either the 11-bit identifier

// or the 29-bit identifier

//

// ulMask:

// this field is four bytes long and contains either the 11-bit mask

// or the 29-bit mask

//

// ubData[8]:

// 8 bytes containing the data of a frame

//

// uwCounter:

// this field is two bytes long and contains the counter value

//

 

typedef struct

  {

     uword  uwMsgCfg;   // Message Configuration Register

     ulong  ulID;       // standard (11-bit)/extended (29-bit) identifier

     ulong  ulMask;     // standard (11-bit)/extended (29-bit) mask

     ubyte  ubData[8];  // 8-bit Data Bytes

     uword  uwCounter;  // Frame Counter

  }TCAN_SWObj;

 

 

void CAN_vInit(void);

void CAN_vGetMsgObj(ubyte ubObjNr, TCAN_SWObj *pstObj);

ubyte CAN_ubRequestMsgObj(ubyte ubObjNr);

ubyte CAN_ubNewData(ubyte ubObjNr);

void CAN_vTransmit(ubyte ubObjNr);

void CAN_vConfigMsgObj(ubyte ubObjNr, TCAN_SWObj *pstObj);

void CAN_vLoadData(ubyte ubObjNr, ubyte *pubData);

ubyte CAN_ubMsgLost(ubyte ubObjNr);

ubyte CAN_ubDelMsgObj(ubyte ubObjNr);

void CAN_vReleaseObj(ubyte ubObjNr);

void CAN_vSetMSGVAL(ubyte ubObjNr);

 

 

// USER CODE BEGIN (CAN_Header,8)

//发送一帧数据

 void CAN_vSend1Frame(unsigned char ObjNr, unsigned char XTD, unsigned long ID, unsigned char   *DataBuf, unsigned char LEN);

 //发送N个字节  

void CAN_vSendDataN(unsigned char ObjNr, unsigned char XTD, unsigned long ID, unsigned char *DataBuf, unsigned char LEN);

//报文对象初始化

TCAN_SWObj Init_vSWObj(TCAN_SWObj pstObj);

//接收报文函数

void CAN_vReveiveMsgObj(ubyte ubObjNr, TCAN_SWObj pstObj);

// USER CODE END

 

 

#define CAN_SRN0INT    0x54

 

#endif  // ifndef _CAN_H_

 

(2)    CAN.C

 

 
#include "MAIN.H"
  
  
extern unsigned char data2[8] ; 
extern unsigned char j;
extern unsigned int num;
unsigned char dataa[8] = {0x0a,0x1a,0x2a,0x3a,0x4a,0x5a,0x6a,0x7a};

extern unsigned char CCPdata[8]; 
struct stCanObj 
{
  ubyte  ubData[8];  // Message Data 0..7
  ulong  ulCANAR;    // Arbitration Register
  ulong  ulCANAMR;   // Acceptance Mask Register
  uword  uwMSGCTR;   // Message Control Register
  uword  uwCounter;  // Frame Counter
  uword  uwMSGCFG;   // Message Configuration Register
  uword  uwINP;      // Interrupt Node Pointer
  uword  uwCANFCR;   // FIFO / Gateway Control Register 
  uword  uwCANPTR;   // FIFO Pointer
  ulong  ulReserved; // Reserved
};

#define CAN_HWOBJ ((struct stCanObj volatile far *) 0x200300)  
   
 
void CAN_vInit(void)
{

  // USER CODE BEGIN (Init,2)

  // USER CODE END

  ///  -----------------------------------------------------------------------
  ///  Configuration of CAN Node A:
  ///  -----------------------------------------------------------------------

  ///  General Configuration of the Node A:
  ///  - set INIT and CCE

  CAN_ACR        =  0x0041;      // load global control register

  ///  -----------------------------------------------------------------------
  ///  Configuration of CAN Node B:
  ///  -----------------------------------------------------------------------

  ///  General Configuration of the Node B:
  ///  - set INIT and CCE

  CAN_BCR        =  0x0041;      // load global control register
  CAN_BGINP      =  0x0000;      // load global interrupt node pointer 
                                 // register

  ///  Configuration of the Node B Error Counter:
  ///  - the error warning threshold value (warning level) is 96

  CAN_BECNTH     =  0x0060;      // load error counter register high

  ///  Configuration of the used CAN Port Pins:
  ///  - P4.4 is used for CAN Interface Input (RXDCB)
  ///  - P4.7 is used for CAN Interface Output (TXDCB)

  ALTSEL0P4     |=  0x0080;      // select alternate output function
  DP4  = (DP4  & ~(uword)0x0080) | 0x0080;    //set direction register

  ///  Configuration of the Node B Baud Rate:
  ///  - required baud rate = 1.000 Mbaud
  ///  - real baud rate     = 1.000 Mbaud
  ///  - sample point       = 60.00 %
  ///  - there are 5 time quanta before sample point
  ///  - there are 4 time quanta after sample point
  ///  - the (re)synchronization jump width is 2 time quanta

  CAN_BBTRL      =  0x3443;      // load bit timing register low

  CAN_BBTRH      =  0x0000;      // load bit timing register high

  ///  Configuration of the Frame Counter:
  ///  - the counter is incremented each time a frame was received correctly
  ///  - frame counter: 0x0000

  CAN_BFCRL      =  0x0000;      // load frame counter timing register low

  CAN_BFCRH      =  0x0002;      // load frame counter timing register high

  ///  -----------------------------------------------------------------------
  ///  Configuration of the CAN Message Objects 0 - 31:
  ///  -----------------------------------------------------------------------

  ///  -----------------------------------------------------------------------
  ///  Configuration of Message Object 0:
  ///  -----------------------------------------------------------------------
  ///  - message object 0 is valid
  ///  - enable receive interrupt; bit INTPND is set after successfull 
  ///    reception of a frame

  ///  - message object is used as receive object
  ///  - standard 11-bit identifier
  ///  - 0 valid data bytes
  ///  - this message object works with CAN node B
  ///  - remote monitoring is disabled
  ///  - receive interrupt node pointer: TwinCAN SRN 0

  CAN_MSGCFGL0   =  0x0002;      // load message configuration register low
  CAN_MSGCFGH0   =  0x0000;      // load message configuration register high

  ///  - acceptance mask 11-bit: 0x7FF
  ///  - identifier 11-bit:      0x0B0

  CAN_MSGAMRL0   =  0x0000;      // load acceptance mask register low
  CAN_MSGAMRH0   =  0xFFFC;      // load acceptance mask register high
  CAN_MSGARL0    =  0x0000;      // load arbitration register low
  CAN_MSGARH0    =  0x02C0;      // load arbitration register high
  CAN_MSGDRL00   =  0x0000;      // load data register 0 low
  CAN_MSGDRH00   =  0x0000;      // load data register 0 high
  CAN_MSGDRL04   =  0x0000;      // load data register 4 low
  CAN_MSGDRH04   =  0x0000;      // load data register 4 high

  ///  - functionality of standard message object

  CAN_MSGFGCRL0  =  0x0000;      // load FIFO/gateway control register low
  CAN_MSGFGCRH0  =  0x0000;      // load FIFO/gateway control register high

  CAN_MSGCTRH0   =  0x0000;      // load message control register high
  CAN_MSGCTRL0   =  0x5599;      // load message control register low

  ///  -----------------------------------------------------------------------
  ///  Configuration of Message Object 1:
  ///  -----------------------------------------------------------------------
  ///  - message object 1 is valid

  ///  - message object is used as receive object
  ///  - standard 11-bit identifier
  ///  - 8 valid data bytes
  ///  - this message object works with CAN node B
  ///  - remote monitoring is disabled

  CAN_MSGCFGL1   =  0x0082;      // load message configuration register low
  CAN_MSGCFGH1   =  0x0000;      // load message configuration register high

  ///  - acceptance mask 11-bit: 0x7FF
  ///  - identifier 11-bit:      0x002

  CAN_MSGAMRL1   =  0xFFFF;      // load acceptance mask register low
  CAN_MSGAMRH1   =  0xFFFF;      // load acceptance mask register high
  CAN_MSGARL1    =  0x0000;      // load arbitration register low
  CAN_MSGARH1    =  0x0008;      // load arbitration register high
  CAN_MSGDRL10   =  0x0000;      // load data register 0 low
  CAN_MSGDRH10   =  0x0000;      // load data register 0 high
  CAN_MSGDRL14   =  0x0000;      // load data register 4 low
  CAN_MSGDRH14   =  0x0000;      // load data register 4 high

  ///  - functionality of standard message object

  CAN_MSGFGCRL1  =  0x0000;      // load FIFO/gateway control register low
  CAN_MSGFGCRH1  =  0x0001;      // load FIFO/gateway control register high

  CAN_MSGCTRH1   =  0x0000;      // load message control register high
  CAN_MSGCTRL1   =  0x5595;      // load message control register low


  ///  -----------------------------------------------------------------------
  ///  Configuration of Service Request Nodes 0 - 7:
  ///  -----------------------------------------------------------------------
  ///  SRN0 service request node configuration:
  ///  - SRN0 interrupt priority level (ILVL) = 15
  ///  - SRN0 interrupt group level (GLVL) = 0
  ///  - SRN0 group priority extension (GPX) = 0

  CAN_0IC        =  0x007C;    

  ///  Use PEC channel 4 for CAN INT 0:
  ///  - normal interrupt
  ///  - pointers are not modified
  ///  - transfer a word
  ///  - service End of PEC interrrupt by a EOP interrupt node is disabled
  ///  - channel link mode is disabled

  PECC4          =  0x0000;      // load PECC4 control register

 


  // USER CODE BEGIN (Init,3)

  // USER CODE END


  CAN_PISEL      =  0x0000;      // load port input select register

  //   -----------------------------------------------------------------------
  //   Start the CAN Nodes:
  //   -----------------------------------------------------------------------

  CAN_BCR       &= ~(uword)0x0041; // reset INIT and CCE


  // USER CODE BEGIN (Init,4)

  // USER CODE END

} //  End of function CAN_vInit


 
//****************************************************************************
// @Function      ubyte CAN_ubRequestMsgObj(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   If a TRANSMIT OBJECT is to be reconfigured it must first be 
//                accessed. The access to the transmit object is exclusive. 
//                This function checks whether the choosen message object is 
//                still executing a transmit request, or if the object can be 
//                accessed exclusively.
//                After the message object is reserved, it can be 
//                reconfigured by using the function CAN_vConfigMsgObj or 
//                CAN_vLoadData.
//                Both functions enable access to the object for the CAN 
//                controller. 
//                By calling the function CAN_vTransmit transfering of data 
//                is started.
//
//----------------------------------------------------------------------------
// @Returnvalue   0 message object is busy (a transfer is active), else 1
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//**************************************************************************** 
ubyte CAN_ubRequestMsgObj(ubyte ubObjNr)
{
  ubyte ubReturn;

  ubReturn = 0;
  if((CAN_HWOBJ[ubObjNr].uwMSGCTR & 0x3000) == 0x1000)  // if reset TXRQ 
  {
    CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xfbff;               // set CPUUPD 
    ubReturn = 1;
  }
  return(ubReturn);

} //  End of function CAN_ubRequestMsgObj


//****************************************************************************
// @Function      ubyte CAN_ubNewData(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   This function checks whether the selected RECEIVE OBJECT 
//                has received a new message. If so the function returns the 
//                value '1'.
//
//----------------------------------------------------------------------------
// @Returnvalue   1 the message object has received a new message, else 0
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (NewData,1)

// USER CODE END

ubyte CAN_ubNewData(ubyte ubObjNr)
{
  ubyte ubReturn;

  ubReturn = 0;
  if((CAN_HWOBJ[ubObjNr].uwMSGCTR & 0x0300) == 0x0200)  // if NEWDAT
  {
    ubReturn = 1;
  }
  return(ubReturn);

} //  End of function CAN_ubNewData


//****************************************************************************
// @Function      void CAN_vTransmit(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   This function triggers the CAN controller to send the 
//                selected message.
//                If the selected message object is a TRANSMIT OBJECT then 
//                this function triggers the sending of a data frame. If 
//                however the selected message object is a RECEIVE OBJECT 
//                this function triggers the sending of a remote frame.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (Transmit,1)

// USER CODE END

void CAN_vTransmit(ubyte ubObjNr)
{
  CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xe7ff;  // set TXRQ, reset CPUUPD

} //  End of function CAN_vTransmit


//****************************************************************************
// @Function      void CAN_vConfigMsgObj(ubyte ubObjNr, TCAN_SWObj *pstObj) 
//
//----------------------------------------------------------------------------
// @Description   This function sets up the message objects. This includes 
//                the 8 data bytes, the identifier (11- or 29-bit), the 
//                acceptance mask (11- or 29-bit), the data number (0-8 
//                bytes), the frame counter value and the XTD-bit (standard 
//                or extended identifier).  The direction bit (DIR), the NODE 
//                bit and the RMM (remote monitoring) bit can not be changed. 
//                The message is not sent; for this the function 
//                CAN_vTransmit must be called.
//                
//                The structure of the SW message object is defined in the 
//                header file CAN.H (see TCAN_SWObj).
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object to be configured (0-31)
// @Parameters    *pstObj: 
//                Pointer on a message object
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (ConfigMsgObj,1)

// USER CODE END

void CAN_vConfigMsgObj(ubyte ubObjNr, TCAN_SWObj *pstObj)
{
  ubyte i;

  CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xfb7f;     // set CPUUPD, reset MSGVAL

  if(pstObj->uwMsgCfg & 0x0004)             // extended identifier
  {
    CAN_HWOBJ[ubObjNr].uwMSGCFG |= 0x0004;
    CAN_HWOBJ[ubObjNr].ulCANAR   = pstObj->ulID ;
    CAN_HWOBJ[ubObjNr].ulCANAMR  = pstObj->ulMask ;
  }
  else                                      // standard identifier
  {
    CAN_HWOBJ[ubObjNr].uwMSGCFG &= ~(uword)0x0004;
    CAN_HWOBJ[ubObjNr].ulCANAR   = pstObj->ulID << 18;
    CAN_HWOBJ[ubObjNr].ulCANAMR  = pstObj->ulMask << 18;
  }

  CAN_HWOBJ[ubObjNr].uwCounter = pstObj->uwCounter;

  CAN_HWOBJ[ubObjNr].uwMSGCFG  = (CAN_HWOBJ[ubObjNr].uwMSGCFG & 0x000f) | (pstObj->uwMsgCfg & 0x00f0);

  if(CAN_HWOBJ[ubObjNr].uwMSGCFG & 0x0008)  // if transmit direction
  {
    for(i = 0; i < (pstObj->uwMsgCfg & 0x00f0) >> 4; i++)
    {
      CAN_HWOBJ[ubObjNr].ubData[i] = pstObj->ubData[i];
    }
    CAN_HWOBJ[ubObjNr].uwMSGCTR  = 0xf6bf;  // set NEWDAT, reset CPUUPD, 
  }                                         // set MSGVAL
  else                                      // if receive direction
  {
    CAN_HWOBJ[ubObjNr].uwMSGCTR  = 0xf7bf;  // reset CPUUPD, set MSGVAL
  }

} //  End of function CAN_vConfigMsgObj


//****************************************************************************
// @Function      void CAN_vLoadData(ubyte ubObjNr, ubyte *pubData) 
//
//----------------------------------------------------------------------------
// @Description   If a hardware TRANSMIT OBJECT has to be loaded with data 
//                but not with a new identifier, this function may be used 
//                instead of the function CAN_vConfigMsgObj. The message 
//                object should be accessed by calling the function 
//                CAN_ubRequestMsgObj before calling this function. This 
//                prevents the CAN controller from working with invalid data.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object to be configured (0-31)
// @Parameters    *pubData: 
//                Pointer on a data buffer
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (LoadData,1)

// USER CODE END

void CAN_vLoadData(ubyte ubObjNr, ubyte *pubData)
{
  ubyte i;

  CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xfaff;       // set CPUUPD and NEWDAT

  for(i = 0; i < (CAN_HWOBJ[ubObjNr].uwMSGCFG & 0xf0) >> 4; i++)
  {
    CAN_HWOBJ[ubObjNr].ubData[i] = *(pubData++);
  }

  CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xf7ff;       // reset CPUUPD

} //  End of function CAN_vLoadData


//****************************************************************************
// @Function      ubyte CAN_ubMsgLost(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   If a RECEIVE OBJECT receives new data before the old object 
//                has been read, the old object is lost. The CAN controller 
//                indicates this by setting the message lost bit (MSGLST). 
//                This function returns the status of this bit. 
//                
//                Note:
//                This function resets the message lost bit (MSGLST).
//
//----------------------------------------------------------------------------
// @Returnvalue   1 the message object has lost a message, else 0
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (MsgLost,1)

// USER CODE END

ubyte CAN_ubMsgLost(ubyte ubObjNr)
{
  ubyte ubReturn;

  ubReturn = 0;
  if((CAN_HWOBJ[ubObjNr].uwMSGCTR & 0x0c00) == 0x0800)  // if set MSGLST 
  {
    CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xf7ff;               // reset MSGLST 
    ubReturn = 1;
  }
  return(ubReturn);

} //  End of function CAN_ubMsgLost


//****************************************************************************
// @Function      ubyte CAN_ubDelMsgObj(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   This function marks the selected message object as not 
//                valid. This means that this object cannot be sent or 
//                receive data. If the selected object is busy (meaning the 
//                object is transmitting a message or has received a new 
//                message) this function returns the value "0" and the object 
//                is not deleted.
//
//----------------------------------------------------------------------------
// @Returnvalue   1 the message object was deleted, else 0
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (DelMsgObj,1)

// USER CODE END

ubyte CAN_ubDelMsgObj(ubyte ubObjNr)
{
  ubyte ubReturn;

  ubReturn = 0;
  if(!(CAN_HWOBJ[ubObjNr].uwMSGCTR & 0xa200)) // if set RMTPND, TXRQ or NEWDAT
  {
    CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xff7f;     // reset MSGVAL
    ubReturn = 1;
  }
  return(ubReturn);

} //  End of function CAN_ubDelMsgObj


//****************************************************************************
// @Function      void CAN_vReleaseObj(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   This function resets the NEWDAT flag of the selected 
//                RECEIVE OBJECT, so that the CAN controller have access to 
//                it. This function must be called if the function 
//                CAN_ubNewData detects, that new data are present in the 
//                message object and the actual data have been read by 
//                calling the function CAN_vGetMsgObj. 
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (ReleaseObj,1)

// USER CODE END

void CAN_vReleaseObj(ubyte ubObjNr)
{
  CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xfdff;       // reset NEWDAT

} //  End of function CAN_vReleaseObj


//****************************************************************************
// @Function      void CAN_vSetMSGVAL(ubyte ubObjNr) 
//
//----------------------------------------------------------------------------
// @Description   This function sets the MSGVAL flag of the selected object. 
//                This is only necessary if the single data transfer mode 
//                (SDT) for the selected object is enabled. If SDT is set to 
//                '1', the CAN controller automatically resets bit MSGVAL 
//                after receiving or tranmission of a frame.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    ubObjNr: 
//                Number of the message object (0-31)
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (SetMSGVAL,1)

// USER CODE END

void CAN_vSetMSGVAL(ubyte ubObjNr)
{
  CAN_HWOBJ[ubObjNr].uwMSGCTR = 0xffbf;  // set MSGVAL

} //  End of function CAN_vSetMSGVAL


//****************************************************************************
// @Function      void CAN_viSRN0(void) 
//
//----------------------------------------------------------------------------
// @Description   This is the interrupt service routine for the Service 
//                Request Node 0 of the TwinCAN module.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    None
//
//----------------------------------------------------------------------------
// @Date          2010-5-14
//
//****************************************************************************

// USER CODE BEGIN (SRN0,1)

// USER CODE END

void CAN_viSRN0(void) interrupt CAN_SRN0INT using RB_LEVEL15
{

  // USER CODE BEGIN (SRN0,2) 
 TCAN_SWObj pstObj0;
  // USER CODE END

  while((( ((ulong)CAN_RXIPNDH << 16) + CAN_RXIPNDL) & 0x00000003))
  {

    // message object 0 interrupt

    if((CAN_HWOBJ[0].uwMSGCTR & 0x0003) == 0x0002)         // if INTPND 
    {
      if(CAN_RXIPNDL & CAN_RXIPNDL_RXIPND0)   // message object 0 receive interrupt
      {

        if((CAN_HWOBJ[0].uwMSGCTR & 0x0300) == 0x0200)     // if NEWDAT is set
        {

          if ((CAN_HWOBJ[0].uwMSGCTR & 0x0c00) == 0x0800)  // if MSGLST is set
          {
            // Indicates that the CAN controller has stored a new 
            // message into this object, while NEWDAT was still set,
            // ie. the previously stored message is lost.

            CAN_HWOBJ[0].uwMSGCTR = 0xf7ff;  // reset MSGLST

            // USER CODE BEGIN (SRN0_OBJ0,1)

            // USER CODE END
          }
          else
          {
            // The CAN controller has stored a new message
            // into this object.

            // USER CODE BEGIN (SRN0_OBJ0,2)
   
    CAN_vReveiveMsgObj(0, pstObj0);
            // USER CODE END
          }

          CAN_HWOBJ[0].uwMSGCTR = 0xfdff;    // reset NEWDAT
        }

      }  // End of RXIPND0


      CAN_HWOBJ[0].uwMSGCTR = 0xfffd;        // reset INTPND

      // USER CODE BEGIN (SRN0_OBJ0,6)

      // USER CODE END

    }


    // message object 1 interrupt
 
    // USER CODE BEGIN (SRN0,3)

    // USER CODE END


  }  // End of while()

  // USER CODE BEGIN (SRN0,7)

  // USER CODE END

} //  End of function CAN_viSRN0

 

// USER CODE BEGIN (CAN_General,10)

// 发送数据后重新对CAN模块初始化,主要是仲裁寄存器和屏蔽寄存器
void CAN_vSetARMR(void)

   

  ///  General Configuration of the Node A:           
  ///  - set INIT and CCE

  CAN_ACR        =  0x0041;      // load global control register
 

  ///  General Configuration of the Node B:
  ///  - set INIT and CCE

  CAN_BCR        =  0x0041;      // load global control register 

  ///  -----------------------------------------------------------------------
  ///  Configuration of the CAN Message Objects 0 - 31:
  ///  ----------------------------------------------------------------------- 
   
  ///  - acceptance mask 11-bit: 0x7FF
  ///  - identifier 11-bit:      0x0B0

  CAN_MSGAMRL0   =  0x0000;      // load acceptance mask register low
  CAN_MSGAMRH0   =  0xFFFC;      // load acceptance mask register high
  CAN_MSGARL0    =  0x0000;      // load arbitration register low
  CAN_MSGARH0    =  0x02C0;      // load arbitration register high
  CAN_MSGDRL00   =  0x0000;      // load data register 0 low
  CAN_MSGDRH00   =  0x0000;      // load data register 0 high
  CAN_MSGDRL04   =  0x0000;      // load data register 4 low
  CAN_MSGDRH04   =  0x0000;      // load data register 4 high
  ///  - acceptance mask 11-bit: 0x7FF
  ///  - identifier 11-bit:      0x400

  CAN_MSGAMRL1   =  0x0000;      // load acceptance mask register low
  CAN_MSGAMRH1   =  0xFFFC;      // load acceptance mask register high
  CAN_MSGARL1    =  0x0000;      // load arbitration register low
  CAN_MSGARH1    =  0x1000;      // load arbitration register high
  CAN_MSGDRL10   =  0x0000;      // load data register 0 low
  CAN_MSGDRH10   =  0x0000;      // load data register 0 high
  CAN_MSGDRL14   =  0x0000;      // load data register 4 low
  CAN_MSGDRH14   =  0x0000;      // load data register 4 high 
  CAN_HWOBJ[1].uwMSGCFG &=  ~0x0008;   //定义报文对象为接收对象   
  //   -----------------------------------------------------------------------
  //   Start the CAN Nodes:
  //   -----------------------------------------------------------------------

  CAN_BCR       &= ~(uword)0x0041; // reset INIT and CCE 
}

//初始化接收数组对象
TCAN_SWObj Init_vSWObj(TCAN_SWObj pstObj){
 int i;
 pstObj.ulID = 0x0000;
 pstObj.ulMask = 0x0000;
 pstObj.uwCounter = 0;
 pstObj.uwMsgCfg = 0;
 for(i=0; i<8; i++)
 {
  pstObj.ubData[i] = 0x00;
 }
 return pstObj;
}
//CAN_vSendData(0,0x10,data,6);
//功  能:CAN发送1帧数据(数据长度<=8)                                       *
//参  数:ID---报文标识符                                                   *
//       DataBUF---报文数据区首址                                          *
//       LEN---报文数据长度                                                *
//   objNr---报文对象
//       XTD  ---标识符类型 0=标准标识符,1=扩展标识符
//返  回:INT8U CANsnd1DFrm --- 发送成功与否标志,                          *
//       =0,没有空闲发送缓冲区,发送不成功;=1,发送成功                  */
void CAN_vSend1Frame(unsigned char ObjNr,unsigned char XTD, unsigned long ID, unsigned char *DataBuf, unsigned char LEN)

 unsigned char i; 
 TCAN_SWObj pstObj;
 //初始化报文对象 
 pstObj = Init_vSWObj(pstObj);
 if(XTD == 0)
 {             
  pstObj.uwMsgCfg &= ~0x0004;    //11位标准标识符
 }
 else
 {         
  pstObj.uwMsgCfg |= 0x0004;    //29位扩展标识符
 }
 pstObj.ulID  = ID;
    pstObj.uwMsgCfg |= (1 <<3 ); //定义该报文对象为发送对象,请求发送,发送数据帧
 pstObj.uwMsgCfg |= LEN << 4;  //定义发送报文长度
 for(i=0; i {          
     pstObj.ubData[i] = *((unsigned char far *)(DataBuf++));
  data2[i] =  pstObj.ubData[i];
 }  
 if(CAN_ubRequestMsgObj(ObjNr))//判断节点空闲
 {  
  CAN_HWOBJ[ObjNr].uwMSGCFG |=  0x0008;   //定义报文对象为发送对象
  CAN_vConfigMsgObj(ObjNr, &pstObj);     
        CAN_HWOBJ[ObjNr].uwMSGCTR = 0xe7ff;  // 置位 TXRQ, 复位 CPUUPD,开始发送数据
  if(CAN_HWOBJ[ObjNr].uwMSGCFG & 0x0002) //该对象与B节点相连
  {       
   while(0 == (CAN_BSR & 0X008))  //等待发送完成
   {
    for(i=0;i<10;i++);
   }
   CAN_BSR &= 0XFFF7;      //清除TXOK标志
  }
  else   //该对象与A节点相连
  {     
   while(0 == (CAN_ASR & 0X008))  //等待发送完成
   {
    for(i=0;i<10;i++);
   }
   CAN_ASR &= 0XFFF7;      //清除TXOK标志
  }           
        CAN_HWOBJ[ObjNr].uwMSGCTR = 0xfdff;       // 复位 NEWDAT,使用完后释放该节点  
//  CAN_vSetARMR();     //重新设定仲裁和标识符屏蔽寄存器
 }       
}
//发送N个字节 
void CAN_vSendDataN( unsigned char ObjNr, unsigned char XTD,unsigned long ID, unsigned char *DataBuf, unsigned char LEN)
{
 unsigned int num1, num2, i;  
 if(XTD == 1)
 {          
  CAN_HWOBJ[ObjNr].uwMSGCFG |= 0x0004;  //扩展帧标识符
 } 
 num1 = LEN / 8;
 num2 = LEN % 8;
 for(i=0; i {
  CAN_vSend1Frame(ObjNr, XTD, ID, DataBuf+i*8, 8);
 } 

 CAN_vSend1Frame(ObjNr, XTD,ID, DataBuf+num1*8, num2);  
 if(XTD == 1)
 {          
  CAN_HWOBJ[ObjNr].uwMSGCFG &= ~0x0004;  //设置回标准帧标识符 
 } 
}
// CAN_vSendFarFrame(0,0, 0x0001b, data_send, 4);
// 发送远程帧,当接收到带有匹配标识符的数据帧时,报文数据保存到相关的数据寄存器MSGDRn0/ MSGDRn4
void CAN_vSendFarFrame(unsigned char ObjNr,unsigned char XTD, unsigned long ID, unsigned char *DataBuf, unsigned char LEN)
{  
  unsigned char i; 
 TCAN_SWObj pstObj;
 //初始化报文对象 
 pstObj = Init_vSWObj(pstObj);
 if(XTD == 0)
 {             
  pstObj.uwMsgCfg &= ~0x0004;    //11位标准标识符
 }
 else
 {         
  pstObj.uwMsgCfg |= 0x0004;    //29位扩展标识符
 }
 pstObj.ulID  = ID;
    pstObj.uwMsgCfg &= ~(1 <<3 ); //定义该报文对象为接受对象,请求发送,发送远程
 pstObj.uwMsgCfg |= LEN << 4;  //定义发送报文长度
 for(i=0; i {          
     pstObj.ubData[i] = *((unsigned char far *)(DataBuf++));
  data2[i] =  pstObj.ubData[i];
 }  
 if(CAN_ubRequestMsgObj(ObjNr))//判断节点空闲
 {  
  CAN_HWOBJ[ObjNr].uwMSGCFG |=  0x0008;   //定义报文对象为发送对象
  CAN_vConfigMsgObj(ObjNr, &pstObj);     
        CAN_HWOBJ[ObjNr].uwMSGCTR = 0xe7ff;  // 置位 TXRQ, 复位 CPUUPD,开始发送数据
  if(CAN_HWOBJ[ObjNr].uwMSGCFG & 0x0002) //该对象与B节点相连
  {      
   while(0 == (CAN_BSR & 0X008)); //等待发送完成
   CAN_BSR &= 0XFFF7;      //清除TXOK标志
  }
  else   //该对象与A节点相连
  {    
   while(0 == (CAN_ASR & 0X008)); //等待发送完成
   CAN_ASR &= 0XFFF7;      //清除TXOK标志
  } 
        CAN_HWOBJ[ObjNr].uwMSGCTR = 0xfdff;       // 复位 NEWDAT,使用完后释放该节点  
   CAN_HWOBJ[ObjNr].uwMSGCFG &=  ~0x0008;   //定义报文对象为接收对象   
  //   CAN_vSetARMR();     //重新设定仲裁和标识符屏蔽寄存器
 }    
}

//功能:接收报文函数
//参数:
//  ubObjNr:接收报文对象的编号 
// pstObj:接收参数 
//返回:空
void CAN_vReveiveMsgObj(ubyte ubObjNr, TCAN_SWObj pstObj)
{       
 int i;
 //初始化报文对象 
 pstObj = Init_vSWObj(pstObj);    
 for(i = 0; i < (CAN_HWOBJ[ubObjNr].uwMSGCFG & 0x00f0) >> 4; i++)//接收数据
 {
  pstObj.ubData[i] = CAN_HWOBJ[ubObjNr].ubData[i];
 }
 
 if(CAN_HWOBJ[ubObjNr].uwMSGCFG & 0x04)  // extended identifier
 {
  pstObj.ulID   = CAN_HWOBJ[ubObjNr].ulCANAR;
  pstObj.ulMask = CAN_HWOBJ[ubObjNr].ulCANAMR;
 }
 else                                    // standard identifier 
 {
  pstObj.ulID   = CAN_HWOBJ[ubObjNr].ulCANAR >> 18;
  pstObj.ulMask = CAN_HWOBJ[ubObjNr].ulCANAMR >> 18;
 }
 
 pstObj.uwCounter = CAN_HWOBJ[ubObjNr].uwCounter;
 pstObj.uwMsgCfg  = CAN_HWOBJ[ubObjNr].uwMSGCFG;    
  
 
 ccpCommand(pstObj.ubData); // CCP命令解析  
}

// USER CODE END


// USER CODE END

(3)     调用方法

 //使用节点0发送data_send中的12个字节

//11位标准标识符,标识符为0x0400,

 

 CAN_vSendDataN(0,0, 0x00400, data_send, 12);

 //使用节点1送data_send中的12个字节

//11位标准标识符,标识符为0x0400,

CAN_vSendDataN(1,0, 0x00400, data_send, 12);   


关键字:单片机  TwinCAN  调试心得 引用地址:单片机TwinCAN调试心得

上一篇:ARM处理机模式--内部寄存器
下一篇:LPC21XX系列ARM7驱动RTC RX8025(I/O模拟IIC)

推荐阅读最新更新时间:2024-03-16 15:29

单片机单按键控制led台灯
按键控制LED台灯亮度 C语言方案 功能要求:单独一个按键控制LED台灯的亮度,上电默认关机,分5个档位。 第一档:100%亮度 第二档:65%亮度 第三档:35%亮度 第四档:20%亮度 第五档:10%亮度 第六档:关机 思路:设定一个改变占空比的变量PWM,每按一次按键PWM值自加一次(自加值看需要定,比如PWM+=100),值越小产生的驱动脉冲频率越高。PWM函数采用模拟方法产生,从成本上考虑,带中断,定时器等功能的单片机价格比较高。所以采用价格低廉的低档单片机。鉴于仿真方便,本程序采用PIC16F505(当然也可以用12F508等芯片)。 端口连接:RC1 LED RC0----蜂鸣器 RC5----按键 程序代码:
[单片机]
PIC单片机存储体0或1的选用说明(程序)
  PIC单片机中级产品PIC16C6X的数据存储器通常分为两个存储体,即存储体0(Bank0)和存储体1(Bank1)。每个存储体都是由专用寄存器和通用寄存器两部分组成的。两个存储体中的一些寄存器单元实际上是同一个寄存器单元,却又具备有不同的地址。例如本版介绍的PIC16F84的状态寄存器STATUS-Reg的两个地址是03H和83H。又如通用寄存器也是如此。   不同型号的PIC单片机,其数据存储器的组成(即功能)是不完全相同的,所以设计人员一旦选用了某个PIC单片机的型号后,常要查找该单片机的数据存储器资料,以便编程用。   笔者以PIC16F84在MPLAB集成开发软件的环境下编写的源程序中,有关RB口(RB7、R
[单片机]
一文详解MCS-51单片机的中断系统
MCS-51中断系统:5个中断源(两个外部中断, 两个定时器, 一个串口),2个优先级 中断相关概念 中断:当CPU正在处理某件事情时,单片机外部或内部发生的某一紧急事件请求CPU立即去处理,于是,CPU暂时中止当前的工作,转去处理这个紧急事件,待处理完毕后,再回到原来被中止的地方,继续原来的工作。 中断过程 中断发生:CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理; 中断响应和中断服务:CPU暂时中断当前的工作,转去处理事件B(B的优先级要高于A); 中断返回:待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A ; 中断源(中断请求源):能够向CPU发出中断申请的部件。 中断系统结
[单片机]
一文详解MCS-51<font color='red'>单片机</font>的中断系统
单片机引脚,单片机引脚是什么意思
8051单片机引脚功能介绍 首先我们来连接一下单片机的引脚图,如果,具体功能在下面都有介绍。 单片机的40个引脚大致可分为4类:电源、时钟、控制和I/O引脚。 ⒈ 电源: ⑴ VCC - 芯片电源,接+5V; ⑵ VSS - 接地端; ⒉ 时钟:XTAL1、XTAL2 - 晶体振荡电路反相输入端和输出端。 ⒊ 控制线:控制线共有4根, ⑴ ALE/PROG:地址锁存允许/片内EPROM编程脉冲 ① ALE功能:用来锁存P0口送出的低8位地址 ② PROG功能:片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。 ⑵ PSEN:外ROM读选通信号。 ⑶ RST/VPD:复位/备
[单片机]
<font color='red'>单片机</font>引脚,<font color='red'>单片机</font>引脚是什么意思
基于单片机的等精度数字测频
在电子技术领域内,频率是一个最基本的参数,频率与其它许多电参量的测量方案,都有十分密切的关系。因此,频率的测量就显得更为重要,而且,目前在电子测量中,频率的测量精确度最高。 1. 电子计数测频原理框图 首先,被测信号通过放大整形,形成幅度一致,形状一致是计数脉冲。然后,N将它加到闸门的一个输入端,闸门由门控信号来控制其关闭时间。计得的脉冲送至译码,再送显示器显示出来。而由晶振产生的1MHz的振荡信号经放大整形,形成方波,经多个10分频10s,1s,0.1s,0.01s,1ms,那么有fx=N/T符合测频定义。根据f=N/T。不难看出,采用计数器测频的测量误差,一方面决定于闸门时间T准不准确,即由晶振提供的标准频率的准确度△T/
[应用]
双机热备单片机系统内部通信接口的简化设计
单片机以其高可靠性和高性价比在工业控制、数据采集系统、智能化仪表、办公自动化等诸多领域得到极为广泛的应用。在测控系统中,有时对单片机系统的可靠性有非常严格的要求。除了在系统设计、生产中采用多种措施以提高其可靠性之外,双机热备份是一种非常有效且经常被采用的方法。在双机热备份系统中,两个单片机必须保持工作状态的完全一致,需要随时进行数据交换。通常可以使用多单片机信息共享技术来实现两个单片机的数据交换,如信箱存储系统、共享存储器等,但这些方法实现复杂,硬件成本高1。大多数单片机都提供通用串行收发器(UART),在单片机系统不与其他设备(如上位机)进行通信的情况下,使用UART是非常方便的,但不幸的是绝大多数情况下UART已被使用。当然也
[单片机]
双机热备<font color='red'>单片机</font>系统内部通信接口的简化设计
单片机中应用观察者模式
环境: 主机:WIN8 开发环境:MDK5.13 mcu: stm32f103RB 说明: 之前在java中应用观察者模式,现将此模式的思想应用在单片机程序设计中 Android编程:观察者模式设计: http://blog.csdn.net/jdh99/article/details/41821295 观察者模式本质: 有两个模块A,B。A是目标,B是观察者。则B能观察到A的变化。 在程序实现中过程是: 1.A产生数据 2.A通知B 3.B处理数据 单片机中实现的方法: Java中通过接口实现此思想,单片机是C语言编程,则可以通过函数指针来实现。 源代码中dw1000通信模块提供了两个被观
[单片机]
微芯、Luminary对簿公堂,专利侵权战火燃至32位MCU领域
微芯科技(Microchip Technology)日前指控Luminary Micro侵犯其32位微处理器技术的专利权。 这项在美国亚利桑那州法院提出的起诉声称,Luminary Micro公司的28引脚Stellaris系列32位微控制器侵犯了Microchip公司的三项专利。Microchip公司(美国亚丽桑那)请求法院发布禁止令,永远禁止Stellaris系列产品的销售与使用,并要求赔偿。 Microchip是微控制器供应商,声称Luminary Micro(美国德州)侵犯了它的三项专利,美国专利号为5,847,450、6,483,183以及6,696,316。Luminary Micro是一家无厂半导体初创公司,成立
[焦点新闻]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved