Проблема с интерфейсом шины CAN на TM4C123GH6PM - PullRequest
0 голосов
/ 30 марта 2020

Я попытался создать интерфейс для шины CAN на TM4C123GH6PM, я использовал l oop back test, я отправил данные и проверил эти данные в режиме l oop back test, чтобы убедиться, что данные отправлены успешно включив светодиод, подключенный к PORT F, но ничего не произошло, я включил прерывания и создал функцию под названием (CAN0_Handler). Это мой ISR, когда я получил данные, произошло прерывание, и программа go на ISR и включил светодиод в зависимости от на получение данных, но ничего не произошло, и я не знаю, где проблема, это мой код.

#include <stdbool.h>
#include <stdint.h>

#define RCGC2_R ((volatile unsigned int) 0x400FE108)
#define GPIODEN_R ((volatile unsigned int) 0x4002451C)
#define GPIODIR_R ((volatile unsigned int) 0x40024400)
#define GPIOAFSEL_R ((volatile unsigned int) 0x40024420)
#define GPIOPCTL_R ((volatile unsigned int) 0x4002452C)
#define RCGC0_R ((volatile unsigned int) 0x400FE100)
#define CANCTL_R ((volatile unsigned int) 0x40040000)
#define CANIF1CRQ_R ((volatile unsigned int) 0x40040020)
#define CANIF1CMSK_R ((volatile unsigned int) 0x40040024)
#define CANIF1ARB1_R ((volatile unsigned int) 0x40040030)
#define CANIF1ARB2_R ((volatile unsigned int) 0x40040034)
#define CANIF1MCTL_R ((volatile unsigned int) 0x40040038)
#define CANBIT_R ((volatile unsigned int) 0x4004000C)
#define CANBRPE_R ((volatile unsigned int) 0x40040018)
#define CANSTS_R ((volatile unsigned int) 0x40040004)
#define CANIF1DA1_R ((volatile unsigned int) 0x4004003C)
#define CANIF1DA2_R ((volatile unsigned int) 0x40040040)
#define CANIF1DB1_R ((volatile unsigned int) 0x40040044)
#define CANIF1DB2_R ((volatile unsigned int) 0x40040048)
#define CANTST_R ((volatile unsigned int) 0x40040014)
#define CANIF1MSK1_R ((volatile unsigned int) 0x40040028)
#define CANIF1MSK2_R ((volatile unsigned int) 0x4004002C)
#define NVIC_EN1_R ((volatile unsigned int) 0xE000E104)
#define GPIODEN_PORTF_R ((volatile unsigned int) 0x4002551C)
#define GPIODIR_PORTF_R ((volatile unsigned int) 0x40025400)
#define GPIODR2R_PORTF_R ((volatile unsigned int) 0x40025500)
#define GPIODR4R_PORTF_R ((volatile unsigned int) 0x40025504)
#define GPIODR8R_PORTF_R ((volatile unsigned int) 0x40025508)
#define GPIODATA_PORTF_R ((volatile unsigned int) 0x40025008)

char Can_data_buffer[8];

typedef struct
{
unsigned long MsgID ; // CAN message ID , 11 or 29 bit
unsigned long MsgIDMask ; // CAN message ID mask
unsigned long MsgLen ; // CAN message data length field
unsigned long MsgFlags ; // CAN message control and status
const char *MsgData ; // CAN message data

} CAN_Msg_Object ;

void CAN0_init_mode();
void CAN_Config_Tx_Message ( CAN_Msg_Object can_msg );
void CAN_Config_Tx_Message_test_mode ( CAN_Msg_Object can_msg );
void Delay ( unsigned long counter );
void CAN0_Handler(void);

int main(void)
{
RCGC2_R |= 0x30; //Enable clock to port E & F
GPIODEN_R |= 0x30; //enable digital function to PE4 , PE5
GPIODIR_R |= 0x20; //PE4 as input RX & PE5 as output TX
GPIOAFSEL_R |= 0x30; //
GPIOPCTL_R |= 0x880000; //enable CAN0 TX , RX on PE5 , PE4
RCGC0_R |= 0x1000000; //enable clock to CAN0
Delay ( 3 );

GPIODEN_PORTF_R |= 0x02;                                            //
GPIODIR_PORTF_R |=0xFF;                                             //
GPIODR2R_PORTF_R = 0;
GPIODR4R_PORTF_R = 0;
GPIODR8R_PORTF_R = 0xFF;


CAN0_init_mode();

CAN_Msg_Object id;

id.MsgID = 0x011;
id.MsgLen = 0x8;
id.MsgData = "abcdefgh";

CAN_Config_Tx_Message_test_mode ( id );

/*if(Can_data_buffer[0]=='a')
{
    GPIODATA_PORTF_R = 2;
}*/


return 0;
}

void CAN0_init_mode()
{
unsigned char msg_num;
CANCTL_R |= 0x1; //enable initialization mode on CAN0
while( CANIF1CRQ_R & 0x8000 ); //wait for busy bit to clear
CANIF1CMSK_R |= 0xB0; //
CANIF1ARB1_R = 0; //
CANIF1ARB2_R = 0; //
CANIF1MCTL_R = 0; //

// Configure all messages objects in message RAM as invalid
for(msg_num=1; msg_num<=32; msg_num++)
{
    while( CANIF1CRQ_R & 0x8000 );                                   //wait for busy bit to clear
    CANIF1CRQ_R = msg_num;

}

CANIF1CMSK_R |= 0x0C;                                                // Make sure that the interrupt and new data flags are updated

for(msg_num=1; msg_num<=32; msg_num++)
{
    while( CANIF1CRQ_R & 0x8000 );                                   //wait for busy bit to clear
    CANIF1CRQ_R = msg_num;

}

CANCTL_R |= 0x40;                                                   //Write accesses to the CANBIT register are allowed

CANBIT_R = (0x0002<<12) | (0x0003<<8) | (0x0001<<6) | 0x3;          //setting bit timing make baud rate 500kbps and sampling point at 60%
CANBRPE_R = 0;                                                      //
CANCTL_R |= 0x0E;                                                   //Enable CAN 0 interrupts for error , status and CAN controller
NVIC_EN1_R |= 0x80;                                                 //enable global interrupt for CAN0

CANCTL_R &= ~(0x41);                                                //disable initialization mode
}

//Normal mode
void CAN_Config_Tx_Message ( CAN_Msg_Object can_msg )
{
CANIF1CMSK_R |= 0xF3; //
CANIF1ARB1_R = 0; //
CANIF1ARB2_R = 0xA000 | (can_msg.MsgID << 2); //
CANIF1MCTL_R = (0x180 | can_msg.MsgLen); //

CANIF1DA1_R = can_msg.MsgData[0] + (can_msg.MsgData[1] << 8);       //
CANIF1DA2_R = can_msg.MsgData[2] + (can_msg.MsgData[3] << 8);       //
CANIF1DB1_R = can_msg.MsgData[4] + (can_msg.MsgData[5] << 8);       //
CANIF1DB2_R = can_msg.MsgData[6] + (can_msg.MsgData[7] << 8);       //

CANIF1CRQ_R = 2;                                                    //Initiate programming message object to second message buffer
while( CANIF1CRQ_R & 0x8000 );                                      //wait for busy bit to clear
}

//loop back test mode
void CAN_Config_Tx_Message_test_mode ( CAN_Msg_Object can_msg )
{
CANCTL_R |= 0x80; //test mode
CANTST_R |= 0x10; //enable loop back test
CANIF1CMSK_R |= 0xF3; //
CANIF1MSK1_R = 0; //
CANIF1MSK2_R = 0; //
CANIF1ARB1_R = 0; //
CANIF1ARB2_R = 0xA000 | (can_msg.MsgID << 2); //
CANIF1MCTL_R = (0x180 | can_msg.MsgLen); //

CANIF1DA1_R = can_msg.MsgData[0] + (can_msg.MsgData[1] << 8);       //
CANIF1DA2_R = can_msg.MsgData[2] + (can_msg.MsgData[3] << 8);       //
CANIF1DB1_R = can_msg.MsgData[4] + (can_msg.MsgData[5] << 8);       //
CANIF1DB2_R = can_msg.MsgData[6] + (can_msg.MsgData[7] << 8);       //

CANIF1CRQ_R = 2;                                                    //Initiate programming message object to second message buffer
while( CANIF1CRQ_R & 0x8000 );                                      //wait for busy bit to clear
}

void Delay ( unsigned long counter )
{
unsigned long i = 0;
for (i =0; i< counter ; i ++) ;
}

//CAN interrupt handler
void CAN0_Handler(void)
{
unsigned long status;
status = CANSTS_R; //Clear interrupt register

if(status & 0x10)
{
    CANIF1MCTL_R |= 0x088;                                          //
    CANIF1CRQ_R = 1;                                                //
    while( CANIF1CRQ_R & 0x8000 );                                  //wait for busy bit to clear

    Can_data_buffer[0] = (char)CANIF1DA1_R;                         //
    Can_data_buffer[1] = (char)(CANIF1DA1_R >> 8);                  //
    Can_data_buffer[2] = (char)CANIF1DA2_R;                         //
    Can_data_buffer[3] = (char)(CANIF1DA2_R >> 8);                  //
    Can_data_buffer[4] = (char)CANIF1DB1_R;                         //
    Can_data_buffer[5] = (char)(CANIF1DB1_R >> 8);                  //
    Can_data_buffer[6] = (char)CANIF1DB2_R;                         //
    Can_data_buffer[7] = (char)(CANIF1DB2_R >> 8);                  //

}

if(Can_data_buffer[0]=='a')
{
    GPIODATA_PORTF_R = 2;
}
...