返回列表 发新帖

SAM4E-EK开发板代码解读04——CAN

[复制链接] 1
回复
24249
查看
打印 上一主题 下一主题

28

主题

45

帖子

1万

积分

允许发帖

积分
10186
楼主
跳转到指定楼层
发表于 2020-5-13 13:48:26 | 只看该作者 | 只看大图 回帖奖励 |正序浏览 | 阅读模式
本帖最后由 Mcuzone_TKN 于 2020-5-15 09:13 编辑

关键词:Microchip Atmel  SAM4E SAM4E-EK  SAM4E16E 芯片CAN 控制器局域网络

概述:实现板载两路之间的收发

开发板有两路CAN,每个CAN有8个信箱。CAN总线上的逻辑数值是用显性电平和隐性电平表示,显性是指在同时传输显性电平和隐性电平时,总线上呈现的是显性电平。显性电平表示逻辑0,隐性电平表示逻辑1。

打开产品光盘SAM4E16E-EK/SAM4E16E-EK中文资料/softpack软件包/Atmel Studio 7,打开03_CAN_EXAMPLE例子。



int main(void)
{
uint32_t ul_sysclk;
uint8_t uc_char;

sysclk_init();
board_init();

configure_console();
//输出示例信息
puts(STRING_HEADER);
//初始化CAN0收发信机
sn65hvd234_set_rs(&can0_transceiver, PIN_CAN0_TR_RS_IDX);
sn65hvd234_set_en(&can0_transceiver, PIN_CAN0_TR_EN_IDX);

//启用CAN0收发信机
sn65hvd234_disable_low_power(&can0_transceiver);
sn65hvd234_enable(&can0_transceiver);

/初始化CAN1收发信机/
sn65hvd234_set_rs(&can1_transceiver, PIN_CAN1_TR_RS_IDX);
sn65hvd234_set_en(&can1_transceiver, PIN_CAN1_TR_EN_IDX);

//使能CAN1收发信机
sn65hvd234_disable_low_power(&can1_transceiver);
sn65hvd234_enable(&can1_transceiver);

//使能CAN0和CAN1时钟
pmc_enable_periph_clk(ID_CAN0);
pmc_enable_periph_clk(ID_CAN1);

ul_sysclk = sysclk_get_cpu_hz();
if (can_init(CAN0, ul_sysclk, CAN_BPS_1000K) &&
  can_init(CAN1, ul_sysclk, CAN_BPS_1000K)) {
  puts("CAN initialization is completed." STRING_EOL);
  //关闭CAN0和CAN1的中断
  can_disable_interrupt(CAN0, CAN_DISABLE_ALL_INTERRUPT_MASK);
  can_disable_interrupt(CAN1, CAN_DISABLE_ALL_INTERRUPT_MASK);

  //配置并启用CAN1的中断
NVIC_EnableIRQ(CAN1_IRQn);
  //运行测试
  puts("Press any key to start test" STRING_EOL);
  while (uart_read(CONSOLE_UART, &uc_char)) {
  }
  test_1();
  g_ul_recv_status = 0;
  puts("Press any key to continue..." STRING_EOL);
  while (uart_read(CONSOLE_UART, &uc_char)) {
  }
  test_2();
  g_ul_recv_status = 0;
  puts("Press any key to continue..." STRING_EOL);
  while (uart_read(CONSOLE_UART, &uc_char)) {
  }
  test_3();
  g_ul_recv_status = 0;
  puts("Press any key to continue..." STRING_EOL);
  while (uart_read(CONSOLE_UART, &uc_char)) {
  }
  test_4();
  g_ul_recv_status = 0;
  //关闭CAN0
can_disable(CAN0);
  //关闭CAN0收发信机
  sn65hvd234_enable_low_power(&can0_transceiver);
  sn65hvd234_disable(&can0_transceiver);

  //关闭CAN1
  can_disable(CAN1);
  //关闭CAN1收发器
  sn65hvd234_enable_low_power(&can1_transceiver);
  sn65hvd234_disable(&can1_transceiver);

  puts("End of all tests" STRING_EOL);
} else {
  puts("CAN initialization (sync) ERROR" STRING_EOL);
}
while (1) {
}
}



图1.png (55.8 KB, 下载次数: 9937)

原理图

原理图
回复

使用道具 举报

28

主题

45

帖子

1万

积分

允许发帖

积分
10186
沙发
发表于 2020-5-13 13:56:47 | 只看该作者
  1. static void test_1(void)
  2. {
  3.         can_reset_all_mailbox(CAN0);
  4.         can_reset_all_mailbox(CAN1);

  5.         puts("\n\rTest1: CAN0 Mailbox 0 transmitting to CAN1 Mailbox 0" STRING_EOL);

  6.          //初始化CAN1邮箱0到接收邮箱
  7.         reset_mailbox_conf(&can1_mailbox);
  8.         can1_mailbox.ul_mb_idx = TEST1_CAN_COMM_MB_IDX;
  9.         can1_mailbox.uc_obj_type = CAN_MB_RX_MODE;
  10.         can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk;
  11.         can1_mailbox.ul_id = CAN_MID_MIDvA(TEST1_CAN_TRANSFER_ID);
  12.         can_mailbox_init(CAN1, &can1_mailbox);

  13.        
  14.         //初始化CAN0邮箱0来传输邮箱
  15.         reset_mailbox_conf(&can0_mailbox);
  16.         can0_mailbox.ul_mb_idx = TEST1_CAN_COMM_MB_IDX;
  17.         can0_mailbox.uc_obj_type = CAN_MB_TX_MODE;
  18.         can0_mailbox.uc_tx_prio = TEST1_CAN0_TX_PRIO;
  19.         can0_mailbox.uc_id_ver = 0;
  20.         can0_mailbox.ul_id_msk = 0;
  21.         can_mailbox_init(CAN0, &can0_mailbox);

  22.        
  23.         //写发送信息到邮箱
  24.         can0_mailbox.ul_id = CAN_MID_MIDvA(TEST1_CAN_TRANSFER_ID);
  25.         can0_mailbox.ul_datal = CAN_MSG_TOGGLE_LED_0;
  26.         can0_mailbox.ul_datah = CAN_MSG_DUMMY_DATA;
  27.         can0_mailbox.uc_length = MAX_CAN_FRAME_DATA_LEN;
  28.         can_mailbox_write(CAN0, &can0_mailbox);

  29.        
  30.         //使能CAN1邮箱0中断
  31.         can_enable_interrupt(CAN1, CAN_IER_MB0);

  32.        
  33.         //把邮箱里的信息发出去
  34.         can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0);

  35.         while (!g_ul_recv_status) {
  36.         }

  37.         if ((can1_mailbox.ul_datal == CAN_MSG_TOGGLE_LED_0) &&
  38.                 (can1_mailbox.uc_length == MAX_CAN_FRAME_DATA_LEN)) {
  39.                 puts("Test1 passed" STRING_EOL);
  40.                 decode_can_msg(&can1_mailbox);
  41.         } else {
  42.                 puts("Test1 ERROR" STRING_EOL);
  43.         }
  44. }
复制代码
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表