Я только начал программировать микроконтроллер SAM4e для CAN, но столкнулся с проблемой. Я реализовал USB_serial comm для отладки процесса CAN, но не сильно помог. Конфигурация CAN работает нормально. Это также показывает, что данные передаются, но на другом контроллере данные не принимаются. Я использую контроллер ATSAM4e8e и трансивер TJA1050.
#include "asf.h"
#include "stdio_usb.h"
#include "pmc.h"
#include "conf_clock.h"
#include "user_board.h"
#include "sam4e8e.h"
#define STRING_EOL "\r"
#define STRING_HEADER "-- CAN Example --\r\n" \
"-- ATSAM4E --\r\n" \
"-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL
#define CAN_COMM_RXMB_ID 0
#define CAN_COMM_TXMB_ID 1
#define CAN_TRANSFER_ID 7
#define CAN_TX_PRIO 15
#define CAN_MSG_DUMMY_DATA 0x55AAAA55u
/** CAN frame max data length */
#define MAX_CAN_FRAME_DATA_LEN 8
/** Transfer mailbox structure */
can_mb_conf_t tx_mailbox, rx_mailbox;
/** Receive status */
volatile uint32_t g_ul_recv_status = 0;
/**
* \brief Default interrupt handler for CAN 1.
*/
void CAN1_Handler(void)
{
uint32_t ul_status;
ul_status = can_mailbox_get_status(CAN1, 0);
if (ul_status & CAN_MSR_MRDY) {
rx_mailbox.ul_status = ul_status;
can_mailbox_read(CAN1, &rx_mailbox);
puts("Got CAN message, press 'r' to display\r");
g_ul_recv_status = 1;
}
}
/**
* \brief Decode CAN messages.
*
* \param p_mailbox Pointer to CAN Mailbox structure.
*/
static void decode_can_msg(can_mb_conf_t *p_mailbox)
{
if (p_mailbox->ul_datal != CAN_MSG_DUMMY_DATA) {
puts("Wrong message header\r");
} else {
printf("%d\r\n", (int)p_mailbox->ul_datah);
}
}
/**
* \brief Reset mailbox configure structure.
*
* \param p_mailbox Pointer to mailbox configure structure.
*/
static void reset_mailbox_conf(can_mb_conf_t *p_mailbox)
{
p_mailbox->ul_mb_idx = 0;
p_mailbox->uc_obj_type = 0;
p_mailbox->uc_id_ver = 0;
p_mailbox->uc_length = 0;
p_mailbox->uc_tx_prio = 0;
p_mailbox->ul_status = 0;
p_mailbox->ul_id_msk = 0;
p_mailbox->ul_id = 0;
p_mailbox->ul_fid = 0;
p_mailbox->ul_datal = 0;
p_mailbox->ul_datah = 0;
}
/**
* Configure UART for debug message output.
*/
static void configure_console(void)
{
/* Configure console UART. */
sysclk_enable_peripheral_clock(ID_UDP);
stdio_usb_init();
}
/**
* \brief can_example application entry point.
*
* \return Unused (ANSI-C compatibility).
*/
int main(void)
{
uint32_t ul_sysclk, cnt = 0;
char uc_key;
/* Initialize the SAM system. */
sysclk_init();
board_init();
/* Configure UART for debug message output. */
configure_console();
/* Output example information. */
puts(STRING_HEADER);
/* Enable CAN1 clock. */
pmc_enable_periph_clk(ID_CAN1);
ul_sysclk = sysclk_get_cpu_hz();
if (can_init(CAN1, ul_sysclk, CAN_BPS_1000K)) {
puts("CAN initialization is completed." STRING_EOL);
/* Disable all CAN1 interrupts. */
can_disable_interrupt(CAN1, CAN_DISABLE_ALL_INTERRUPT_MASK);
can_reset_all_mailbox(CAN1);
/* Init CAN1 Mailbox 0 to Reception Mailbox. */
reset_mailbox_conf(&rx_mailbox);
rx_mailbox.ul_mb_idx = CAN_COMM_RXMB_ID;
rx_mailbox.uc_obj_type = CAN_MB_RX_MODE;
rx_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk;
rx_mailbox.ul_id = CAN_MID_MIDvA(CAN_TRANSFER_ID);
can_mailbox_init(CAN1, &rx_mailbox);
/* Init CAN1 Mailbox 1 to Transmit Mailbox. */
reset_mailbox_conf(&tx_mailbox);
tx_mailbox.ul_mb_idx = CAN_COMM_TXMB_ID;
tx_mailbox.uc_obj_type = CAN_MB_TX_MODE;
tx_mailbox.uc_tx_prio = CAN_TX_PRIO;
tx_mailbox.uc_id_ver = 0;
tx_mailbox.ul_id_msk = 0;
can_mailbox_init(CAN1, &tx_mailbox);
/* Write transmit information into mailbox. */
tx_mailbox.ul_id = CAN_MID_MIDvA(CAN_TRANSFER_ID);
tx_mailbox.ul_datal = CAN_MSG_DUMMY_DATA;
tx_mailbox.uc_length = MAX_CAN_FRAME_DATA_LEN;
/* Enable CAN1 mailbox interrupt. */
can_enable_interrupt(CAN1, 1 << CAN_COMM_RXMB_ID);
/* Configure and enable interrupt of CAN1. */
NVIC_EnableIRQ(CAN1_IRQn);
puts("\tt: Perform CAN Transmisson \r");
while (1) {
scanf("%c", &uc_key);
switch (uc_key) {
case 'R':
case 'r':
if (!g_ul_recv_status) {
puts("No CAN message\r");
} else {
g_ul_recv_status = 0;
decode_can_msg(&rx_mailbox);
puts("CAN data decoded\n");
}
break;
case 'T':
case 't':
if (can_get_status(CAN1) & CAN_SR_TBSY) {
puts("Transmission is busy\r");
} else {
tx_mailbox.ul_datah = cnt++;
can_mailbox_write(CAN1, &tx_mailbox);
/* Send out the information in the mailbox. */
can_global_send_transfer_cmd(CAN1, CAN_TCR_MB1);
puts("Message is sent\n");
}
break;
default:
puts("Unknown input\r");
break;
}
}
} else {
puts("CAN initialization (sync) ERROR" STRING_EOL);
}
}