Я попытался создать интерфейс для шины 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;
}