打印
[活动]

【极海APM32F407IG Tiny Board开发板测评】8.CAN通讯实验

[复制链接]
1090|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创# @21小跑堂  

8.CAN通讯实验

CAN 是控制器局域网络 Controller Area Network 的缩写,是德国BOSCH(博世)公司研发的一种串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。CAN协议主要用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束,该协议的健壮性使其同样适用于自动化和工业环境中。
APM32F407IG拥有2个CAN,支持 CAN 协议 2.0A 和 2.0B,例程中有个CAN的例程就是用这两个CAN互相发送接收数据,不过代码是针对MINI Board写的,修改一下让它适配TINY Board
先修改一下工程宏定义把MINI改成TINY

然后将main.c中的APM_MINI全部替换为APM_TINY
查看一下readme文件

先尝试直接连接PB8与PB13 PB9与PB12,测试结果失败,调换rx与tx的接法也还是失败,看来必须要用CAN模块才行

搞了2个TJA1050的CAN模块

按照上面readme里那个示意图进行连接,再次测试OK了

接下来尝试在自己的工程里实现一下,按下按键1 CAN1发送消息CAN2接收消息后打印出来,按下按键2 CAN2发送消息CAN1接收消息后打印出来
代码示例,CAN的相关初始化代码这里就不列举了,参考例程的就行
uint8_t can1_rec_flag = 0;
uint8_t can2_rec_flag = 0;
CAN_RxMessage_T can1rxmsg;
CAN_RxMessage_T can2rxmsg;
void can_senddatas(uint8_t can)
{
    CAN_TxMessage_T TxMessage;
    uint8_t x = 0;
    TxMessage.extID          = 0x1234567;
    TxMessage.typeID         = CAN_TYPEID_EXT;
    if(can == 2)
    {
        TxMessage.stdID          = 0x123;
        TxMessage.typeID         = CAN_TYPEID_STD;
        x = 0x80;
    }
    TxMessage.remoteTxReq    = CAN_RTXR_DATA;
    TxMessage.dataLengthCode = 8;
    TxMessage.data[0]        = 0x01|x;
    TxMessage.data[1]        = 0x02|x;
    TxMessage.data[2]        = 0x03|x;
    TxMessage.data[3]        = 0x04|x;
    TxMessage.data[4]        = 0x05|x;
    TxMessage.data[5]        = 0x06|x;
    TxMessage.data[6]        = 0x07|x;
    TxMessage.data[7]        = 0x08|x;
    if(can == 1)
        CAN_TxMessage(CAN1, &TxMessage);
    else if(can == 2)
        CAN_TxMessage(CAN2, &TxMessage);
}

void can_print_rxmessage(CAN_RxMessage_T *msg)
{
    uint8_t i = 0;
    printf("stdid: %08X\r\n",msg->stdID);
    printf("extid: %08X\r\n",msg->extID);
    printf("datalen: %d\r\n",msg->dataLengthCode);
    printf("data: ");
    while(i<msg->dataLengthCode)
    {
        printf("%02X ",msg->data[i]);
        i++;
    }
    printf("\r\n");
}
int main(void)
{
    APM_TINY_LEDInit(LED2);
    APM_TINY_LEDInit(LED3);
    APM_TINY_PBInit(BUTTON_KEY1,BUTTON_MODE_GPIO);
    APM_TINY_PBInit(BUTTON_KEY2,BUTTON_MODE_GPIO);
    uart_init();
    can_init(CAN_BAUD_500K);
    CAN_EnableInterrupt(CAN1, CAN_INT_F0MP);
    CAN_EnableInterrupt(CAN2, CAN_INT_F0MP);
    NVIC_EnableIRQRequest(CAN1_RX0_IRQn, 0, 0);
    NVIC_EnableIRQRequest(CAN2_RX0_IRQn, 0, 0);
    while (1)
    {
        if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
        {
            yuyy_delay_ms(30);
            if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
            {
                while(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET);
                can_senddatas(1);
            }
        }
        if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
        {
            yuyy_delay_ms(30);
            if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
            {
                while(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET);
                can_senddatas(2);
            }
        }
        if(can1_rec_flag > 0)
        {
            printf("CAN1收到数据\r\n");
            can_print_rxmessage(&can1rxmsg);
            can1_rec_flag = 0;
            APM_TINY_LEDToggle(LED2);
        }
        if(can2_rec_flag > 0)
        {
            printf("CAN2收到数据\r\n");
            can_print_rxmessage(&can2rxmsg);
            can2_rec_flag = 0;
            APM_TINY_LEDToggle(LED3);
        }
    }
}

void CAN1_RX0_IRQHandler(void)
{
    CAN_RxMessage(CAN1, CAN_RX_FIFO_0, &can1rxmsg);
    can1_rec_flag = 1;
}


void CAN2_RX0_IRQHandler(void)
{
    CAN_RxMessage(CAN2, CAN_RX_FIFO_0, &can2rxmsg);
    can2_rec_flag = 1;
}
运行结果





使用特权

评论回复
沙发
caizhiwei| | 2023-7-13 15:26 | 只看该作者
点赞~

使用特权

评论回复
板凳
joengchao| | 2023-7-20 09:38 | 只看该作者
顶~~

使用特权

评论回复
地板
tpgf| | 2023-8-8 10:43 | 只看该作者
开始的时候可以使用回环模式进行测试吗

使用特权

评论回复
5
qcliu| | 2023-8-8 10:52 | 只看该作者
can通讯有握手的机制吗?万一数据丢失怎么办

使用特权

评论回复
6
drer| | 2023-8-8 11:42 | 只看该作者
can通讯数据的接收是只能通过中断来实现的吗

使用特权

评论回复
7
coshi| | 2023-8-8 11:57 | 只看该作者
can通讯方式需要对数据进行校验吗

使用特权

评论回复
8
yuyy1989|  楼主 | 2023-8-8 13:11 | 只看该作者
coshi 发表于 2023-8-8 11:57
can通讯方式需要对数据进行校验吗


CAN报文已经带了CRC校验

使用特权

评论回复
9
kxsi| | 2023-8-8 13:20 | 只看该作者
楼主这里can中printf函数是向哪里打印输出数据啊

使用特权

评论回复
10
yuyy1989|  楼主 | 2023-8-8 13:26 | 只看该作者
kxsi 发表于 2023-8-8 13:20
楼主这里can中printf函数是向哪里打印输出数据啊

printf重定向到了串口

使用特权

评论回复
11
wiba| | 2023-8-8 14:43 | 只看该作者
这个测试使用的是外挂的can模块而不是单片机自己的外设是吗

使用特权

评论回复
12
yuyy1989|  楼主 | 2023-8-8 14:54 | 只看该作者
wiba 发表于 2023-8-8 14:43
这个测试使用的是外挂的can模块而不是单片机自己的外设是吗

需要can收发模块转换,直接IO连线不行

使用特权

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

本版积分规则

149

主题

708

帖子

7

粉丝