历史上的今天
返回首页

历史上的今天

今天是:2024年09月02日(星期一)

正在发生

2018年09月02日 | stm32 CAN通信 TJA1040

2018-09-02 来源:eefocus

1

CAN协议特点

1.多主控制 
所有单元都可以发送消息,根据标识符(Identifier简称ID)决定优先级。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作

2.系统的柔软性 
与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变

3.通信速度较快,通信距离远 
最高 1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps)

4.具有错误检测、错误通知和错误恢复功能 
所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制 
结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)

5.故障封闭功能 
CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去

6. 连接节点多 
CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制

总线拓扑 
总线电平分为显性电平和隐性电平两种。“显性”具有“优先”的意味,只要有一个单元输出显性电平,总线上即为显性电平。并且,“隐性”具有“包容”的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平 
1

帧的种类

帧的种类及用途 
1

数据帧的构成 
1

帧起始:数据帧开始 

仲裁段:该帧优先级 

控制段:数据的字节数及保留位 

数据段:数据的内容,可发送0~8个字节的数据 

CRC段:检查帧的传输错误 

ACK段:确认正常接收 

帧结束:数据帧结束


遥控帧的构成 

遥控帧没有数据帧的数据段 
1

错误帧 
1

错误标志:包括主动错误标志和被动错误标志两种。主动错误标志为6位的显性位;被动错误标志为6位的隐性位 

错误界定符:由8位的隐性位构成


过载帧 
2

过载标志:6位的显性位(与主动错误标志的构成相同) 

过载界定符:8位的隐性位(与错误界定符的构成相同)


帧间隔 

帧起始 
标准、扩展格式相同。1位的显性位 
1

仲裁段 
1 
扩展帧的仲裁段有29位,可以出现2^29种报文。标准帧的仲裁段是11位,可以出现2^11种报文。扩展帧能扩展更多的CAN节点,更好地支持上层协议

控制段 
1

数据长度码和字节数的关系: 
2
“D”为显性电平;“R”为隐性电平

数据段 
数据段可包含0~8个字节的数据。从MSB(最高位)开始输出 
1

CRC段 
由15位的CRC顺序和1位的CRC界定符(用于分隔的位)构成 
1

ACK段 
由ACK槽(ACK Slot)和ACK界定符2位构成 
1

帧结束 
由7位的隐性位构成 
1

优先级的决定

连续输出显性电平最多的单元可继续发送

1

数据帧和遥控帧的优先级 
具有相同ID 的数据帧和遥控帧在总线上竞争时,仲裁段的最后一位(RTR)为显性位的数据帧具有优先权,可继续发送

1

标准格式和扩展格式的优先级 
标准格式的RTR位为显性位的具有优先权,可继续发送

1

bxCAN工作模式

bxCAN有3个主要的工作模式:初始化、正常和睡眠模式

初始化模式 
设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认

正常模式 
软件对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’的确认

睡眠模式 
软件对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式

测试模式

通过对CAN_BTR寄存器的SILM和LBKM配置

静默模式(CAN_Mode_Silent) 
通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式 
1

环回模式(CAN_Mode_LoopBack) 
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式 
1

环回静默模式(CAN_Mode_Silent_LoopBack) 
通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式 
1

超过8字节数据发送

可以采取拆包、组包方法。记录包id和是否为结尾包标识。接收方如果未接收完整个包,直到接收完整包再进行处理 
详细参考:uavcan

CAN配置步骤


1.使能CAN时钟 

2.使能GPIO端口时钟 

3.GPIO端口模式设置 

4.配置CAN工作模式、波特率等 

5.配置CAN筛选器 

6.选择CAN中断类型,开启中断 

7.初始化NVIC外设 

8.编写CAN中断处理函数 

9.CAN发送和接收消息 

10.CAN状态获取


1

硬件设计

1

2

举例

1
2

typedef struct

{

    uint32_t StdId; //标准标识符

    uint32_t ExtId; //扩展标识符

    uint8_t IDE; //标识符选择

    uint8_t RTR; //远程发送请求

    uint8_t DLC; //发送数据长度

    uint8_t Data[8]; //数据字节

} CanTxMsg;


void CAN_transmit(u8 *data, u8 len)

{

    u8 i = 0, box;

    CanTxMsg msg = {0};


    msg.StdId = 0x12;

    msg.ExtId = 0x12;

    msg.IDE = CAN_Id_Standard; //使用标准标识符

    msg.RTR = CAN_RTR_Data; //数据帧

    msg.DLC = len;


    for(i = 0; i < len; i++)

    {

        msg.Data[i] = data[i];

    }


    box = CAN_Transmit(CAN1, &msg);


    while(CAN_TransmitStatus(CAN1, box) == CAN_TxStatus_Failed);


    return;

}


u8 CAN_receive(u8 *data)

{

    u8 i = 0;

    CanRxMsg msg = {0};


    if(CAN_MessagePending(CAN1, CAN_FIFO0) == 0)

    {

        return 0;

    }


    CAN_Receive(CAN1, CAN_FIFO0, &msg);


    for(i = 0; i < msg.DLC; i++)

    {

         data[i] = msg.Data[i];

    }


    return msg.DLC;

}


#ifdef CAN_IT

void USB_LP_CAN1_RX0_IRQHandler()

{

    u8 data[8], len;


    if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) == SET)

    {

        len = CAN_receive(data);


        CAN_transmit(data, len);


        led1 = ~led1;  

    }


    CAN_ClearFlag(CAN1, CAN_IT_FMP0);

}

#endif


typedef struct

{

    uint16_t CAN_Prescaler; //波特率分频器

    uint8_t CAN_Mode; //测试模式

    uint8_t CAN_SJW; //重新同步跳跃宽度

    uint8_t CAN_BS1; //时间段1

    uint8_t CAN_BS2; //时间段2

    FunctionalState CAN_TTCM; //时间触发通信模式

    FunctionalState CAN_ABOM; //自动离线管理

    FunctionalState CAN_AWUM; //自动唤醒模式

    FunctionalState CAN_NART; //禁止报文自动重传 

    FunctionalState CAN_RFLM; //接收FIFO锁定模式

    FunctionalState CAN_TXFP; //发送FIFO优先级

} CAN_InitTypeDef;


typedef struct

{

    uint16_t CAN_FilterIdHigh;

    uint16_t CAN_FilterIdLow;

    uint16_t CAN_FilterMaskIdHigh;

    uint16_t CAN_FilterMaskIdLow;

    uint16_t CAN_FilterFIFOAssignment; //过滤器位宽设置

    uint8_t CAN_FilterNumber;

    uint8_t CAN_FilterMode; //过滤器模式

    uint8_t CAN_FilterScale; //过滤器位宽设置

    FunctionalState CAN_FilterActivation; //过滤器激活

} CAN_FilterInitTypeDef;


void CAN_init()

{

    GPIO_InitTypeDef gpio11 = 

    {

        GPIO_Pin_11,

        GPIO_Speed_50MHz,

        GPIO_Mode_IPU

    };  


    GPIO_InitTypeDef gpio12 = 

    {

        GPIO_Pin_12,

        GPIO_Speed_50MHz,

        GPIO_Mode_AF_PP

    };  


    CAN_InitTypeDef can = {0};

    CAN_FilterInitTypeDef can_filter = {0};


    NVIC_InitTypeDef nvic = 

    {

        USB_LP_CAN1_RX0_IRQn,

        2,

        2,

        ENABLE

    };


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);


    GPIO_Init(GPIOA, &gpio11);

    GPIO_Init(GPIOA, &gpio12);


    can.CAN_Prescaler = 4;

    can.CAN_Mode = CAN_Mode_LoopBack; //环回模式

    can.CAN_SJW = CAN_SJW_1tq; //占用1个时间单元

    can.CAN_BS1 = CAN_BS1_9tq; //占用9个时间单元

    can.CAN_BS2 = CAN_BS2_8tq; //占用8个时间单元

    can.CAN_TTCM = DISABLE; //详见上图

    can.CAN_ABOM = DISABLE;

    can.CAN_AWUM = DISABLE;

    can.CAN_NART = ENABLE;

    can.CAN_RFLM = DISABLE;

    can.CAN_TXFP = DISABLE;

    CAN_Init(CAN1, &can);


    can_filter.CAN_FilterIdHigh = 0;

    can_filter.CAN_FilterIdLow = 0;

    can_filter.CAN_FilterMaskIdHigh = 0;

    can_filter.CAN_FilterMaskIdLow = 0;

    can_filter.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器被关联到FIFO0

    can_filter.CAN_FilterNumber = 0;

    can_filter.CAN_FilterMode = CAN_FilterMode_IdMask; //过滤器组x的2个32位寄存器工作在标识符屏蔽位模式

    can_filter.CAN_FilterScale = CAN_FilterScale_32bit;  //过滤器位宽为单个32位

    can_filter.CAN_FilterActivation = ENABLE; //过滤器被激活

    CAN_FilterInit(&can_filter);


#ifdef CAN_IT

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);


    NVIC_Init(&nvic);

#endif

}


int main(void)

{

    CAN_init();


    for(i = 0; i < 8; i++)

    {

        txbuf[i] = i;

    }

    while(1)

    {

        led1 = ~led1;


        CAN_transmit(txbuf, 8);


        res = CAN_receive(rxbuf);

        if(res)

        {

            for(i = 0; i < 8; i++)

            {

                rxbuf[i] = rxbuf[i] + 0x30;

            }

            printf("CAN_receive len %d, %s\n", res, rxbuf);

        }


        delay_ms(1000);

    }

}


推荐阅读

史海拾趣

Bipolarics Inc公司的发展小趣事

在市场竞争日益激烈的背景下,Bipolarics Inc意识到单打独斗难以取得长久发展。于是,公司开始积极寻求与其他企业的战略合作。通过与一家知名的芯片制造商合作,Bipolarics Inc成功将其双极性晶体管技术应用于更广泛的领域,进一步提升了产品的竞争力。同时,这种合作也带来了双方在技术研发和市场推广方面的资源共享,推动了双方的共同发展。

ATM [Advanced Technical Materials]公司的发展小趣事

在20世纪初期,电子技术和机械自动化的发展为ATM的出现奠定了基础。1939年,美国的Luther Simjian提出了ATM的设计雏形,并成功说服一家公司制作了样板试验产品。然而,由于当时的技术限制和公众接受度不高,这些早期ATM并未得到广泛应用。

Gold Peak Group公司的发展小趣事
定期对控制电路进行检查和维护,确保接触器、继电器等元件的性能良好,触点无粘连或损坏。
弘凯光电(BRIGHTEK)公司的发展小趣事

作为一家有社会责任感的企业,弘凯光电始终致力于环保和可持续发展。公司秉承“质量第一”的方针,不仅注重产品的品质和性能,还积极推广环保理念,致力于生产高质量、环保的LED产品。此外,公司还积极参与社会公益活动,回馈社会,为建设环保节能型社会贡献自己的力量。

以上五个故事,基于弘凯光电在电子行业中的发展历程和公开信息,尽量以事实为依据,避免了主观评价。这些故事展示了弘凯光电在技术创新、市场拓展、社会责任等方面的努力和成就,也反映了公司在电子行业中的崛起和影响力。

E-T-A [E-T-A Circuit Breakers]公司的发展小趣事

随着技术的不断进步和市场的日益成熟,E-T-A公司的产品线也逐渐扩展。公司不仅继续深耕断路器领域,还推出了包括保护控制器、流量和液位传感器等一系列新产品。同时,公司也开始积极拓展全球市场,通过设立分支机构和办事处,为全球客户提供更便捷的服务和支持。

Clever Little Box公司的发展小趣事

Clever Little Box公司成立于1964年,当时正值电子行业的蓬勃发展时期。创始人凭借对音频和电子技术的深厚理解,以及对市场的敏锐洞察,决定成立这家公司,专注于音频和电子组件的分销。创业初期,公司面临着资金短缺、市场竞争激烈等诸多挑战,但创始人凭借坚定的信念和不懈的努力,逐渐在市场中站稳了脚跟。

问答坊 | AI 解惑

苹果腰斩售价抢滩中国市场

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 苹果公司罕见地放低了身价,期望以平价亲近中国消费者。昨日,苹果借在中国推出新款电脑大幅下调高端笔记本的入门价格,降价幅度超过7000元。最低配置款售价仅为8498元,这是苹果公司首次把价 ...…

查看全部问答>

华清远见武汉华嵌联手ARM大型讲座圆满举行!

2010年4月24日下午,华清远见武汉华嵌中心联手ARM公司在武汉大学举办了一场大型的关于“ARM+Linux+Android”的嵌入式盛宴,由ARM公司技术专家和武汉华嵌知名技术专家联袂奉献,本次讲座的技术主题是目前嵌入式市场上最风靡也是许多大型企业正在使用 ...…

查看全部问答>

wince应用程序

最近弄wince要求:按键按下,LCD弹出窗口, 按键驱动我已经弄好: 发送信息部分贴出来: while (1) {         __try {             we = WaitForSingleObject(pPWR->I ...…

查看全部问答>

3000 元定做一个嵌入式开发方案并付诸实现

       项目的详细需求不方便在论坛中写出来,要求接包方有丰富的嵌入式开发经验,对电脑主板、主板上主要的元器件、RAM、ROM 以及WINDOWS操作系统非常熟悉,因为项目涉及到将操作系统与电脑硬件的结合…… 符合我要求的工程 ...…

查看全部问答>

Windows Mobile5用RIL_DIAL拨号接通后听不到声音

Windows Mobile5用RIL_DIAL拨号,对方接通后听不到这边声音,为什么? 以前曾在多普达机器上没问题,这台华硕P535不行。 是不是要打开听筒?如果是的话怎么打开? 请赐教!…

查看全部问答>

时间戳记数器TSC

时间戳记数器TSC 端口地址是多少? 怎样使用? 目的是在dos下获得准确时间控制 用汇编或qb或c都行…

查看全部问答>

wince 5 中的图标变为黑色的,有没有遇到过这个问题,怎么解决?

在wince 5中修改显示分辨率中,发现wince 5 中的图标变为黑色的,有没有遇到过这个问题,怎么解决? 谢谢!…

查看全部问答>

探路者:关于3014LED的图形分析

流明斯的3014说明书上附带的图,请教下如何看懂这两个图,请解析下谢谢哈 包括横坐标纵坐标的解析哦; 这个图更难看懂,一个发光角度的问题; 这个代码65ABCDE是啥意思,后面的数字代表什么;请详细说说啊,需要啊…

查看全部问答>

求msp430下载软件simple insidepro

如题。xdwll88@126.com.  谢谢!…

查看全部问答>