打印
[活动专区]

【AT-START-F423测评】+ CAN 收发数据

[复制链接]
1991|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cuyebiren|  楼主 | 2023-11-10 23:12 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本测评测试 AT32F423 的 CAN 外设模块。硬件配置上,使用 fifo 标识符过滤功能。
软件编写上,使用软件 fifo 管理接收数据。

步骤:
1、配置


2、代码编写

main()
int main(void)
{
  /* add user code begin 1 */
    uint32_t start_tick;
  /* add user code end 1 */

  /* add a necessary delay to ensure that Vdd is higher than the operating
     voltage of battery powered domain (2.57V) when the battery powered
     domain is powered on for the first time and being operated. */
  wk_wait_for_power_stable();
  
  /* system clock config. */
  wk_system_clock_config();

  /* config periph clock. */
  wk_periph_clock_config();

  /* nvic config. */
  wk_nvic_config();

  /* init usart1 function. */
  wk_usart1_init();

  /* init can1 function. */
  wk_can1_init();

  /* init gpio function. */
  wk_gpio_config();

  /* add user code begin 2 */
    sys_init();

    fifo_init(&can_rx_fifo, can_rx_msg_buf,
                sizeof(can_rx_msg_buf)/sizeof(can_rx_msg_buf[0]));
    can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);

    // printf("The demo is started!\n");
    start_tick = sys_get_tick();
  /* add user code end 2 */

  while(1)
  {
    /* add user code begin 3 */
    if (!FIFO_IS_EMPTY(&can_rx_fifo)) {
        can_tx_message_type tx_msg;
        can_rx_message_type *rx_msg = fifo_read(&can_rx_fifo, can_rx_message_type);
        fifo_decrement(&can_rx_fifo);

        // tx_msg.standard_id = rx_msg->standard_id;
        // tx_msg.extended_id = rx_msg->extended_id;
        // tx_msg.id_type = rx_msg->id_type;
        // tx_msg.frame_type = rx_msg->frame_type;
        memcpy(&tx_msg, rx_msg, sizeof(can_tx_message_type));
        can_message_transmit(CAN1, &tx_msg);
    }

    if (sys_get_tick() - start_tick >= 1000) {
        start_tick = sys_get_tick();
        gpio_bits_toggle(LED2_GPIO_PORT, LED2_PIN);
        can_message_transmit(CAN1, &can_tx_msg);
    }
    /* add user code end 3 */
  }
}
CAN1_RX0_IRQHandler()
void CAN1_RX0_IRQHandler(void)
{
  /* add user code begin CAN1_RX0_IRQ 0 */
    if (can_flag_get(CAN1, CAN_RF0MN_FLAG) == SET) {
        can_flag_clear(CAN1, CAN_RF0MN_FLAG);

        if (!FIFO_IS_FULL(&can_rx_fifo)) {
            can_rx_message_type *msg = fifo_tail_member(&can_rx_fifo,
                                                        can_rx_message_type);
            can_message_receive(CAN1, CAN_RX_FIFO0, msg);
            fifo_increment(&can_rx_fifo);
        } else {
            can_receive_fifo_release(CAN1, CAN_RX_FIFO0);
        }
    }
  /* add user code end CAN1_RX0_IRQ 0 */
  /* add user code begin CAN1_RX0_IRQ 1 */

  /* add user code end CAN1_RX0_IRQ 1 */
}
fifo.h - fifo 功能全部使用宏定义函数实现

#ifndef _FIFO_H
#define _FIFO_H

#include <stdint.h>
#include <string.h>

typedef struct {
    uint16_t head;
    uint16_t tail;
    uint16_t size;
    void *data;
} fifo_t;

#define FIFO_IS_FULL(fifo)      ((fifo)->tail - (fifo)->head == (fifo)->size)
#define FIFO_IS_EMPTY(fifo)     ((fifo)->head == (fifo)->tail)

#define fifo_increment(fifo)    ((fifo)->tail++)
#define fifo_decrement(fifo)    ((fifo)->head++)

#define fifo_init(fifo, pdata, dsize) do { \
    (fifo)->head = (fifo)->tail = 0; \
    (fifo)->data = (pdata); \
    (fifo)->size = (dsize); \
} while (0)

#define fifo_head_member(fifo, TYPE) \
            (&((TYPE *)(fifo)->data)[(fifo)->head % (fifo)->size])
#define fifo_tail_member(fifo, TYPE) \
            (&((TYPE *)(fifo)->data)[(fifo)->tail % (fifo)->size])
#define fifo_read(fifo, TYPE)   fifo_head_member((fifo), TYPE)
#define fifo_write(fifo, data, TYPE) \
    memcpy(fifo_tail_member((fifo), TYPE), (data), sizeof(TYPE));

#endif


3、测试


芯片每隔 1s 发送1帧 ID = 0x123 的固定报文,上位机每隔 500ms 发送1帧 ID = 1FF 的报文,芯片收到上位机的报文后原样转发出来

4、测试中遇到的问题
当配置 PA11 & PA12 为 CAN 接口时,CAN 通信不了,没有报文收发。切换到 PD0 & PD1 之后,一切正常。

can.zip

6.12 MB

使用特权

评论回复
沙发
muyichuan2012| | 2023-11-11 12:41 | 只看该作者
PA11  PA12的usb脚,你使用的at start 板子已经接到usb端口了。

使用特权

评论回复
板凳
cuyebiren|  楼主 | 2023-11-11 12:57 | 只看该作者
muyichuan2012 发表于 2023-11-11 12:41
PA11  PA12的usb脚,你使用的at start 板子已经接到usb端口了。

谢谢,是的。看了原理图,根本原因是 R33  R32 没焊,导致 A11  A12 插针和芯片的 PA11  PA12 引脚不连通

使用特权

评论回复
地板
gyh974| | 2023-11-11 14:09 | 只看该作者
你接的那CAN收发器是什么作用?不是MCU已经有CAN接口?还要外接一个收发器?

使用特权

评论回复
5
cuyebiren|  楼主 | 2023-11-11 17:42 | 只看该作者
gyh974 发表于 2023-11-11 14:09
你接的那CAN收发器是什么作用?不是MCU已经有CAN接口?还要外接一个收发器? ...


CAN 物理层网络是靠 CAN 收发器互联的,MCU 一般只有 CAN 控制器,MCU 的 CAN 要想工作必须外接收发器和 CAN 总线互联,就像 MCU 的以太网模块要外接 phy 芯片一样。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

39

帖子

0

粉丝