Canbus TM4C

huyphuc92

Trứng gà
Chào cả nhà.

Em đang làm mạng CAN trên kit TM4C123g, có một lỗi mò mãi chưa giải quyết được. Em send một message từ Master qua slave, rõ ràng bên slave đã nhận đúng và phản hồi một xung ACK ở cuối frame, trong ngắt của Master em cũng đã xóa cờ ngắt TX rồi nhưng nó cứ cắm đầu cắm cổ send đúng cái message đó :gach

Ai kinh qua món này rồi cho em ý kiến ạ.
 

huyphuc92

Trứng gà
Download code tham khảo:
http://www.payitforward.edu.vn/forum/threads/1511/#post-15273

trong code này có nhiều phần, trong đó có CAN.
Em có tham khảo code thư viện đó rồi, còn cả code tham khảo của TI nữa, có mấy dòng thôi, có khác gì đâu, thậm chí copy y chang cả code của người ta mà nó vẫn vậy @.@
Code copy đây, chỉ chỉnh sửa TM4C1294 sang TM4C123G: http://ohm.ninja/tiva-c-series-can-bus-with-mcp2551/

Phân tích đường truyền cho thấy tín hiệu có vẻ đúng :-(
Kênh 0: Master-TX
Kênh 1: Master-RX
Kênh 4: Slave- TX
Kênh 5: Slave- RX

Như vậy là slave đã phản hồi xác nhận frame truyền tốt, có xung ACK ở cuối frame. Debug phía master cho thấy cờ trạng thái ngắt của CAN = 1, chứng tỏ nó ngắt TX đúng với object 1, đã clear cờ này rồi mà debug thấy nó vẫn = 1, chứng tỏ clear có vấn đề???
Code bên master:
//
Code:
#include <stdbool.h>
#include <stdint.h>
#include <math.h>

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "driverlib/can.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/uart.h"
#include "driverlib/pin_map.h"

#include "utils/uartstdio.h"

#define PI 3.14159265359f

volatile bool errFlag = 0; // transmission error flag
unsigned int sysClock; // clockspeed in hz
int view;
int sendcount;
uint32_t status;
void delay(unsigned int milliseconds) {
    SysCtlDelay((SysCtlClockGet() / 3) * (milliseconds / 1000.0f));
}

// CAN interrupt handler
void CANIntHandler(void) {
    status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // read interrupt status
    if(status == CAN_INT_INTID_STATUS) { // controller status interrupt
        status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // read back error bits, do something with them?
        errFlag = 1;
    } else if(status == 1) { // message object 1
        CANIntClear(CAN0_BASE, 1); // clear interrupt
        errFlag = 0; // clear any error flags
        sendcount++;
    } else { // should never happen
        UARTprintf("Unexpected CAN bus interrupt\n");
    }
}
void
InitConsole(void)
{
    //
    // Enable GPIO port A which is used for UART0 pins.
    // TODO: change this to whichever GPIO port you are using.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Configure the pin muxing for UART0 functions on port A0 and A1.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);

    //
    // Enable UART0 so that we can configure the clock.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Select the alternate (UART) function for these pins.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);
}
int main(void) {

    tCANMsgObject msg; // the CAN message object
    unsigned int msgData; // the message data is four bytes long which we can allocate as an int32
    unsigned char *msgDataPtr = (unsigned char *)&msgData; // make a pointer to msgData so we can access individual bytes


    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    // Set up debugging UART
    InitConsole();

    // Set up CAN0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // enable CAN0 GPIO peripheral
    GPIOPinConfigure(GPIO_PE4_CAN0RX);
    GPIOPinConfigure(GPIO_PE5_CAN0TX);
    GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    CANInit(CAN0_BASE);
    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
    CANIntRegister(CAN0_BASE, CANIntHandler); // use dynamic vector table allocation
    CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    IntEnable(INT_CAN0);
    CANEnable(CAN0_BASE);

    // Set up msg object
    msgData = 0;
    msg.ui32MsgID = 1;
    msg.ui32MsgIDMask = 0;
    msg.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    msg.ui32MsgLen = sizeof(msgDataPtr);
    msg.pui8MsgData = msgDataPtr;

    unsigned int t = 0; // loop counter
    float freq = 0.3; // frequency scaler

    while(1) {

        // set up next colour (scale sinf (0-1) to 0-255)
        msgDataPtr[0] = (0.5 + 0.5*sinf(t*freq)) * 0xFF;
        msgDataPtr[1] = (0.5 + 0.5*sinf(t*freq + (2*PI/3))) * 0xFF; // 120 degrees out of phase
        msgDataPtr[2] = (0.5 + 0.5*sinf(t*freq + (4*PI/3))) * 0xFF; // 240 degrees out of phase
        msgDataPtr[3] = 128; // 50% intensity

        UARTprintf("Sending colour\tr: %d\tg: %d\tb: %d\n", msgDataPtr[0], msgDataPtr[1], msgDataPtr[2]); // write colour to UART for debugging
        CANMessageSet(CAN0_BASE, 1, &msg, MSG_OBJ_TYPE_TX); // send as msg object 1
        view++;
        delay(250); // wait 100ms

        if(errFlag) { // check for errors
            UARTprintf("CAN Bus Error\n");
        }

        t++; // overflow is fine
    }

//    return 0;
}
 
Last edited:

huyphuc92

Trứng gà
À mà được rồi.
Trước đó em dùng tivaware bản 2.1.3.156, cài lại bản cũ 2.1.2.111 thì ổn. Chắc bản mới có bug @.@
 

huunho

Trứng gà
chương trình debug CAN của bạn tên gì mà trông hay vay? bạn nói qua chức năng của nó và có thẻ share cho mình dc ko?
 

huyphuc92

Trứng gà
chương trình debug CAN của bạn tên gì mà trông hay vay? bạn nói qua chức năng của nó và có thẻ share cho mình dc ko?
Salea logic á, lên trang taobao.com mua một mạch salea logic 24Mhz có cỡ 180k, nó hỗ trợ mình phân tích logic cũng tốt.
 

huunho

Trứng gà
Salea logic á, lên trang taobao.com mua một mạch salea logic 24Mhz có cỡ 180k, nó hỗ trợ mình phân tích logic cũng tốt.
bạn nhận dc mạch là 180k à? có thể đặt giúp mình dc ko?
 
Top