欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
一次CAN波形分析之旅

Prepare

CAN通信協(xié)議使用了有一段時(shí)間了,但都是基于軟件層面的使用,對于其波形不是很了解,正好這段時(shí)間比較閑,是時(shí)候補補硬知識。

開(kāi)始之前,先介紹一下設備:

  • 咸魚(yú)淘來(lái)的古董級別示波器GDS-2202。200MHz,數據記錄長(cháng)度是12500個(gè)點(diǎn)(每個(gè)點(diǎn)40ns,總記錄長(cháng)度是500us)

  • EK-LM4F120XL開(kāi)發(fā)板。也就是現在的EK-TM4C123GXL,板載MCU是TM4C1233H6PM,對應原來(lái)的老型號LM4F120H5QR

 

 

  • CAN收發(fā)器,TJA1050模塊

 

 Ongoing

軟件準備

用CCS9.0導入TI提供的CAN驅動(dòng)庫,每隔1秒鐘發(fā)送一個(gè)CAN信息:

  • 波特率:500 kb/s
  • ID(Normal): 0x220
  • 信息長(cháng)度 :4 bytes
  • 數據:0x12, 0x34, 0x56, 0x78
  1 int main(void)  2 {  3     tCANMsgObject sCANMessage;  4     unsigned char ucMsgData[4];  5   6     //  7     // Set the clocking to run directly from the external crystal/oscillator.  8     // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the  9     // crystal on your board. 10     // 11     SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | 12                    SYSCTL_XTAL_16MHZ); 13  14     // 15     // Set up the serial console to use for displaying messages.  This is 16     // just for this example program and is not needed for CAN operation. 17     // 18     InitConsole(); 19  20     // 21     // For this example CAN0 is used with RX and TX pins on port D0 and D1. 22     // The actual port and pins used may be different on your part, consult 23     // the data sheet for more information. 24     // GPIO port D needs to be enabled so these pins can be used. 25     // TODO: change this to whichever GPIO port you are using 26     // 27     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); 28  29     // 30     // Configure the GPIO pin muxing to select CAN0 functions for these pins. 31     // This step selects which alternate function is available for these pins. 32     // This is necessary if your part supports GPIO pin function muxing. 33     // Consult the data sheet to see which functions are allocated per pin. 34     // TODO: change this to select the port/pin you are using 35     // 36     GPIOPinConfigure(GPIO_PE4_CAN0RX); 37     GPIOPinConfigure(GPIO_PE5_CAN0TX); 38  39     // 40     // Enable the alternate function on the GPIO pins.  The above step selects 41     // which alternate function is available.  This step actually enables the 42     // alternate function instead of GPIO for these pins. 43     // TODO: change this to match the port/pin you are using 44     // 45     GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5); 46  47     // 48     // The GPIO port and pins have been set up for CAN.  The CAN peripheral 49     // must be enabled. 50     // 51     SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); 52  53     // 54     // Initialize the CAN controller 55     // 56     CANInit(CAN0_BASE); 57  58     // 59     // Set up the bit rate for the CAN bus.  This function sets up the CAN 60     // bus timing for a nominal configuration.  You can achieve more control 61     // over the CAN bus timing by using the function CANBitTimingSet() instead 62     // of this one, if needed. 63     // In this example, the CAN bus is set to 500 kHz.  In the function below, 64     // the call to SysCtlClockGet() is used to determine the clock rate that 65     // is used for clocking the CAN peripheral.  This can be replaced with a 66     // fixed value if you know the value of the system clock, saving the extra 67     // function call.  For some parts, the CAN peripheral is clocked by a fixed 68     // 8 MHz regardless of the system clock in which case the call to 69     // SysCtlClockGet() should be replaced with 8000000.  Consult the data 70     // sheet for more information about CAN peripheral clocking. 71     // 72  73     sysclk = SysCtlClockGet(); 74     CANBitRateSet(CAN0_BASE, sysclk, 500000); 75  76     // 77     // Enable interrupts on the CAN peripheral.  This example uses static 78     // allocation of interrupt handlers which means the name of the handler 79     // is in the vector table of startup code.  If you want to use dynamic 80     // allocation of the vector table, then you must also call CANIntRegister() 81     // here. 82     // 83     // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors 84     // 85     CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); 86  87     CANRetrySet(CAN0_BASE, false); 88     // 89     // Enable the CAN interrupt on the processor (NVIC). 90     // 91     IntEnable(INT_CAN0); 92  93     // 94     // Enable the CAN for operation. 95     // 96     CANEnable(CAN0_BASE); 97  98     // 99     // Initialize the message object that will be used for sending CAN100     // messages.  The message will be 4 bytes that will contain an incrementing101     // value.  Initially it will be set to 0.102     //103     *(unsigned long *)ucMsgData = 0;104     sCANMessage.ulMsgID = 0x220;                    // CAN message ID105     sCANMessage.ulMsgIDMask = 0;                    // no mask needed for TX106     sCANMessage.ulFlags = MSG_OBJ_TX_INT_ENABLE;    // enable interrupt on TX107     sCANMessage.ulMsgLen = sizeof(ucMsgData);       // size of message is 4108     sCANMessage.pucMsgData = ucMsgData;             // ptr to message content109 110     ucMsgData[0] = 0x12;111     ucMsgData[1] = 0x34;112     ucMsgData[2] = 0x56;113     ucMsgData[3] = 0x78;114     //115     // Enter loop to send messages.  A new message will be sent once per116     // second.  The 4 bytes of message content will be treated as an unsigned117     // long and incremented by one each time.118     //119     for(;;)120     {121         //122         // Print a message to the console showing the message count and the123         // contents of the message being sent.124         //125         UARTprintf("Sending msg: 0x%02X %02X %02X %02X",126                    ucMsgData[0], ucMsgData[1], ucMsgData[2], ucMsgData[3]);127 128         //129         // Send the CAN message using object number 1 (not the same thing as130         // CAN ID, which is also 1 in this example).  This function will cause131         // the message to be transmitted right away.132         //133         CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);134 135         //136         // Now wait 1 second before continuing137         //138         SimpleDelay();139 140         //141         // Check the error flag to see if errors occurred142         //143         if(g_bErrFlag)144         {145             UARTprintf(" error - cable connected?\n");146         }147         else148         {149             //150             // If no errors then print the count of message sent151             //152             UARTprintf(" total count = %u\n", g_ulMsgCount);153         }154 155         //156         // Increment the value in the message data.157         //158         //(*(unsigned long *)ucMsgData)++;159     }160 161     //162     // Return no errors163     //164     return(0);165 }

 

編譯,通過(guò)板載調試器下載代碼,復位運行代碼。

硬件準備

示波器探頭CH1連接TJA1050的CANH引腳,探頭CH2連接CANL引腳,地跟開(kāi)發(fā)板的GND連接,使用邊沿觸發(fā)模式捕獲波形:

分析

為了方便分析,將波形保存成CSV格式。該CSV文件記錄了波形信息和數據,從第17行開(kāi)始,就是波形的數據,如下圖:

 

使用Matplotlib導入CSV,繪制折線(xiàn)圖,代碼如下:

 1 import csv 2 import matplotlib 3 import matplotlib.pyplot as plt 4 import matplotlib.collections as collections 5 from matplotlib.ticker import MultipleLocator 6 import numpy as np 7 import pandas as pd 8  9 ax = plt.subplot()10 #將x主刻度標簽設置為125的倍數11 xmajorLocator = MultipleLocator(125) 12 ax.xaxis.set_major_locator(xmajorLocator)13 #y軸數據14 raw_canh = pd.read_csv("canh.csv")15 raw_canl = pd.read_csv("canl.csv")16 #x軸數據17 t = np.arange(130, 12000, 1)18 ax.plot(t, raw_canh[130:12000], raw_canl[130:12000])19 ax.xaxis.grid(True)20 21 plt.show()

 

運行,效果如下,

 

局部放大波形圖,

 

 接下來(lái)的工作就是PS了,參照CAN2.0B的Spec,找到每一位的定義。首先是整個(gè)數據幀(Data Frame)的定義,

 

進(jìn)一步細化每個(gè)字段(Field):

 

將差分信號轉換為實(shí)際的二進(jìn)制值,十六進(jìn)制值。這里需要補充一點(diǎn)知識,CAN信號電壓與實(shí)際邏輯的關(guān)系,很好記憶,波形像口張開(kāi)的(O),表示邏輯0(顯示);另外一種則表示邏輯1(隱性)。如下圖:

 

根據上面的信息,我們可以進(jìn)一步得到以下數據,

 

如果你很細心的看上面圖,就會(huì )發(fā)現一個(gè)問(wèn)題,有些十六進(jìn)制為什么是有9位?因為有一位是填充位(Bit Stuffing),CAN2.0的協(xié)議規定,連續5個(gè)顯性/隱性電平后,要填充一位隱性/顯性電平。如上圖中的仲裁字段(Arbitration Field),連續5個(gè)'0'后,填充一個(gè)'1'。

 Post

分析到這里接近尾聲了,還有一個(gè)疑問(wèn),這個(gè)CRC校驗是怎么算出來(lái)的呢?從CAN2.0的Spec了解到,CRC的計算的值從SOF開(kāi)始,到數據字段(Data Field),多項式:

                                          P(x) = x15+ x14+ x10+ x8+ x7+ x4+ x3+ 1

 通過(guò)在線(xiàn)CRC計算網(wǎng)站,輸入我們的數據,計算CRC的值:

 

 如我們所料,計算的CRC值是正確的!

 -----------------------------------------------------------------------------------END

[參考資料]

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
device tree pinctrl
CCS5.4+Proteus8的F28027實(shí)踐課十、SPI
Android 5.1高通方案增加GPIO按鍵
IDT M2I介紹
ESP32引腳參考:您應該使用哪個(gè)GPIO引腳?
[原創(chuàng )]通過(guò)Raspberry Pi(樹(shù)莓派)的GPIO接口控制步進(jìn)電機/Control ...
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久