1. Background: Use LPC1769 to do CAN transmission and reception. Here is a summary and record of using LPC1769 CAN controller for transmission and reception, in preparation for the next Get started quickly for the first time development. Note: LPC1768/1769 are basically the same except for the maximum frequency they support. 2. Main text: First, here is a block diagram of the LPC1769 CAN controller:
.
As can be seen from the figure above, the entire CAN controller has a CPU on one end and a CAN transceiver on the other end: The CAN transceiver is responsible for the communication of CAN data with the CAN network. The CAN kernel module parses and encapsulates the data to be sent to the CAN transceiver and received from the CAN The data sent by the transceiver, the CAN core work here is completed by the hardware itself. The CPU can set the CAN controller status and read interrupt information and interrupt status through the APB bus. There are 3 send buffers (mailboxes) in total, which ensures that at least 3 sets of concurrent CAN data can be sent; 2 receive buffers The CPU can process the received data of one mailbox while using another mailbox to receive data on the network. The LPC1769 CAN acceptance filter is quite special. It is a device independent of the CAN controller and is also a peripheral. What is special is that it is a peripheral that serves the CAN controller. The significance of this is that the acceptance filtering no longer requires software. To do anything, the table lookup algorithm is implemented directly by hardware, saving precious CPU resources. Since it is also an independent peripheral, it can be used It is also quite complicated, and the length of this article is limited, so I will not go into details for now. I will write another blog next time. At this point, the structure of the LPC1769 CAN has been introduced. Next, we will explain what needs to be done to enable it to start sending and receiving CAN data correctly.
CAN1/2 uses the following registers to set up: a) Power enable: In the PCONP register, set PCAN1/2. Note: On reset, CAN1/2 will be enabled (PCAN1/2=0). b) Clock enable: Select PCLK_CAN1/2 and PCLK_ACF for the acceptance filter in the PCLK_SEL0 register. Note: If the required CAN baud rate must be higher than 100 kbit/s (see Table 16.12), then IRC cannot be selected. as a clock source. c) Wake-up: The CAN controller is able to wake up the microcontroller from Power-down mode. d) Pins: The CAN1/2 pins are selected through the PINSEL register and the pin mode is selected through the PINMODE register. e) Interrupt: CAN interrupt is enabled through CAN1/2IER register. Interrupt is enabled by enabling This is achieved using the corresponding Interrupt Set Enable register. f) CAN controller initialization: set in the CANNOD register. The above is the CAN controller initialization process introduced in the data sheet. In plain words: "a)" CAN is a peripheral device of LPC1769. To make it work, you must first set PCONP. The various bits of this register determine the peripheral Whether the clock is turned on or off. If a peripheral is not in use, turn it off to save power. To use CAN, first turn on the CAN peripheral clock. "b)" Secondly, if the peripherals are to work properly, they all need a suitable clock frequency, which is determined by PCLK_SEL01. "c)" In order to further reduce the power consumption of the MCU, when there is no data transmission on the CAN network, there is no CAN interrupt processing, and the corresponding If the sleep bit is set to "1", the CAN peripheral will enter the sleep state. If a dominant bit appears on the CAN bus, the CAN peripheral will come out of the sleep state. At the same time, if the relevant bits have been configured and the entire MCU enters power-down or deep sleep mode, the CAN It can also wake up the MCU. "d)" Configure the CAN transmit and receive pins. Needless to say, tell the CAN controller which pin to use to transmit and receive CAN data. "e)" Configure various interrupt enable conditions for CAN. Here, the transmit/receive interrupt and error interrupt are enabled; and configure the NVIC internal CAN peripheral interrupt. "f)" Configure CAN related parameters, such as baud rate, etc. At this point, the CAN controller initialization part is completed, and the receiving and sending functions, as well as the interrupt function, are still needed to realize the CAN receiving and sending. , and error management. Of course, there is a lot to say about the baud rate parameter settings in the CAN controller initialization part. This article is limited in space and will not be described in detail next time. Let me start another blog to introduce it. CAN interrupt function: /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/ /****************************************************** *********************//** * @brief CAN_IRQ Handler, control receive message operation * param[in] none * @return none *************************************************** ************************/ void CAN_IRQHandler() { uint8_t IntStatus; uint32_t data1; /* get interrupt status * Note that: Interrupt register CANICR will be reset after read. * So function "CAN_IntGetStatus" should be call only one time */ // The following function obtains the register data of CAN1ICR/CAN2ICR, which indicates the source of the interrupt IntStatus = CAN_IntGetStatus(LPC_CAN1);if((IntStatus>>0)&0x01) {// Receive interrupt } ... // The omitted content is to parse the interrupt information according to the interrupt source data of each bit of the register. // IntStatus = CAN_IntGetStatus(LPC_CAN2); // if(...) ... } CAN receiving function: This function is a library function provided by NXP. The download link of the library function is in the third part of this article. The content of this function is nothing more than During the interruption, check whether there is any information in the two receiving mailboxes. If there is, extract the information. /************************************************************************//** * @briefReceive message data * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: * - LPC_CAN1: CAN1 peripheral * - LPC_CAN2: CAN2 peripheral * @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received * message information such as: ID, DLC, RTR, ID Format * @return Status: * - SUCCESS: receive message successfully * - ERROR: receive message unsuccessfully *************************************************** *******************/ Status CAN_ReceiveMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg) { uint32_t data; CHECK_PARAM(PARAM_CANx(CANx)); //check status of Receive Buffer if((CANx->SR &0x00000001)) { /* Receive message is available */ /* Read frame informations */ CAN_Msg->format = (uint8_t)(((CANx->RFS) & 0x80000000)>>31); CAN_Msg->type = (uint8_t)(((CANx->RFS) & 0x40000000)>>30); CAN_Msg->len = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16); /* Read CAN message identifier */ CAN_Msg->id = CANx->RID; /* Read the data if received message was DATA FRAME */ if (CAN_Msg->type == DATA_FRAME) { /* Read first 4 data bytes */ data = CANx->RDA; *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8; ; *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16; *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24; /* Read second 4 data bytes */ data = CANx->RDB; *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8; *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16; *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24; /*release receive buffer*/ CANx->CMR = 0x04; } else { /* Received Frame is a Remote Frame, not have data, we just receive * message information only */ CANx->CMR = 0x04; /*release receive buffer*/ return SUCCESS; } } else { // no receive message available return ERROR; } return SUCCESS; } CAN sending function: This function is also a library function, that is, it queries the status of three sending mailboxes in turn. If the mailbox status is empty, the data is filled into the mailbox The sending flag is set, and then the CAN core module hardware automatically sends it. The sending priority can be configured in the register and will not be described in detail. I don't want to make the article too long, so I'll omit the code part 2/3 of the mailbox query. /************************************************************************//** * @brief Send message data * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: * - LPC_CAN1: CAN1 peripheral * - LPC_CAN2: CAN2 peripheral * @param[in] CAN_Msg point to the CAN_MSG_Type Structure, it contains message * information such as: ID, DLC, RTR, ID Format * @return Status: * - SUCCESS: send message successfully * - ERROR: send message unsuccessfully *************************************************** *******************/ Status CAN_SendMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg) { uint32_t data; CHECK_PARAM(PARAM_CANx(CANx)); CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format)); if(CAN_Msg->format==STD_ID_FORMAT) { CHECK_PARAM(PARAM_ID_11(CAN_Msg->id)); } else { CHECK_PARAM(PARAM_ID_29(CAN_Msg->id)); } CHECK_PARAM(PARAM_DLC(CAN_Msg->len)); CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type)); //Check status of Transmit Buffer 1 if (CANx->SR & (1<<2)) { /* Transmit Channel 1 is available */ /* Write frame informations and frame data into its CANxTFI1, * CANxTID1, CANxTDA1, CANxTDB1 register */ CANx->TFI1 &= ~0x000F0000; CANx->TFI1 |= (CAN_Msg->len)<<16; if(CAN_Msg->type == REMOTE_FRAME) { CANx->TFI1 |= (1<<30); //set bit RTR } else { CANx->TFI1 &= ~(1<<30); } if(CAN_Msg->format == EXT_ID_FORMAT) { CANx->TFI1 |= (0x80000000); //set bit FF } else { CANx->TFI1 &= ~(0x80000000); } /* Write CAN ID*/ CANx->TID1 = CAN_Msg->id; /*Write first 4 data bytes*/ data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)| ((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); CANx->TDA1 = data; /*Write second 4 data bytes*/ data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)| ((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); CANx->TDB1 = data; /*Write transmission request*/ // Note the value and set send mailbox 1 to inform the hardware that the information in mailbox 1 has been filled and can be sent. CANx->CMR = 0x21; return SUCCESS; } //check status of Transmit Buffer 2 else if(CANx->SR & (1<<10)) { /* Transmit Channel 2 is available */ /* Write frame informations and frame data into its CANxTFI2, * CANxTID2, CANxTDA2, CANxTDB2 register */ ... /*Write transmission request*/ // Note the value and set send mailbox 2 to inform the hardware that the information in mailbox 2 has been filled and can be sent. CANx->CMR = 0x41; return SUCCESS; } //check status of Transmit Buffer 3 else if (CANx->SR & (1<<18)) { /* Transmit Channel 3 is available */ /* Write frame informations and frame data into its CANxTFI3, * CANxTID3, CANxTDA3, CANxTDB3 register */ ... /*Write transmission request*/ // Note the value and set send mailbox 3 to inform the hardware that the information in mailbox 3 has been filled and can be sent. CANx->CMR = 0x81; return SUCCESS; } else { // All mailboxes are not idle and cannot be sent return ERROR; } } At this point, with the initialization part, CAN interrupt function, CAN sending and receiving functions, the sending and receiving of CAN data is realized. Filtering is based on baud rate and CAN bus error handling. I will write a blog post about this in detail next time. 3. Reference Documents LPC175x_6x CMSIS-Compliant Standard Peripheral Firmware Driver Library (Keil, IAR, GNU) https://www.lpcware.com/content/nxpfile/lpc175x6x-cmsis-compliant-standard-peripheral-firmware-driver-library-keil-iar-gnu So far, the record is complete.
Previous article:LPC1769 CAN self-test mode
Next article:Cotex-M3 core LPC17xx series clock and its configuration method
Recommended ReadingLatest update time:2024-11-22 21:34
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- A2B, In-car entertainment network, a new direction
- Noise around the oscilloscope and its environment
- Phased Array Beamforming IC Simplifies Antenna Design
- 2SC5047 transistor
- Communication example between two nodes of SM32W108 wireless RF module
- Several Commonly Used Data Files and Their Reference Simulation in ADS
- Sailor Hat ESP32 Development Board
- 【Qinheng CH582】4 Bluetooth serial port transparent transmission experiment
- EEWORLD University Hall - A robot that can type
- This week's highlights