历史上的今天
返回首页

历史上的今天

今天是:2025年03月26日(星期三)

正在发生

2020年03月26日 | stm32---CAN通信

2020-03-26 来源:eefocus

can.c


#include "can.h"

 

/*************************************************************

函数名:CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)

功能:CAN初始化

变量:

//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq

//tbs2:时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;

//tbs1:时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq

//brp :波特率分频器.范围:1~1024;  tq=(brp)*tpclk1

//波特率=Fpclk1/((tbs1+tbs2+1)*brp);

//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;

//Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);

//则波特率为:36M/((8+9+1)*4)=500Kbps

//返回值:0,初始化OK;

//    其他,初始化失败;

**************************************************************/

void CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    CAN_InitTypeDef CAN_InitStructure;

    CAN_FilterInitTypeDef CAN_FilterStructure;

#if CAN_RX0_INT_ENABLE 

    NVIC_InitTypeDef        NVIC_InitStructure;

#endif

    //1*开启CAN时钟和对应引脚时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    

    //2*引脚初始化配置

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入模式

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStructure);

    

    //3*CAN初始化配置

    CAN_InitStructure.CAN_Prescaler = brp; //分频系数为brp+1

    CAN_InitStructure.CAN_Mode=mode; //模式设置

    CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围

    CAN_InitStructure.CAN_BS2=tbs2; //Tbs2范围

    CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳跃宽度的

    CAN_InitStructure.CAN_ABOM=DISABLE; //软件自动离线管理

    CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒

    CAN_InitStructure.CAN_NART=ENABLE;  //使用报文自动传输

    CAN_InitStructure.CAN_RFLM=DISABLE;  //报文不锁定,新的覆盖旧的

    CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式

    CAN_InitStructure.CAN_TXFP=DISABLE;//优先级由报文标识符决定 

    CAN_Init(CAN1,&CAN_InitStructure);

    

    //4*过滤器初始化配置

    CAN_FilterStructure.CAN_FilterNumber =0; //过滤器0

    CAN_FilterStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //掩码模式,缺点是有误差,报表模式缺点是可识别ID少

    CAN_FilterStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位

    CAN_FilterStructure.CAN_FilterIdHigh=0x0000; //32位ID

    CAN_FilterStructure.CAN_FilterIdLow = 0x0000;

    CAN_FilterStructure.CAN_FilterMaskIdHigh=0x0000; //32位掩码

    CAN_FilterStructure.CAN_FilterMaskIdLow=0x0000;

    CAN_FilterStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0;//过滤器0关联到FIFO0(邮箱0)

    CAN_FilterStructure.CAN_FilterActivation=ENABLE;//激活过滤器0

    CAN_FilterInit(&CAN_FilterStructure);//滤波器初始化

 

    #if CAN_RX0_INT_ENABLE 

    CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);              //FIFO0消息挂号中断允许.            

 

    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    #endif

}

 

    #if CAN_RX0_INT_ENABLE  //使能RX0中断

    //中断服务函数                

    void USB_LP_CAN1_RX0_IRQHandler(void)

    {

        CanRxMsg RxMessage;

        int i=0;

        CAN_Receive(CAN1, 0, &RxMessage);

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

        printf("rxbuf[%d]:%drn",i,RxMessage.Data[i]);

    }

    #endif

    

 

//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)   

//len:数据长度(最大为8)                     

//msg:数据指针,最大为8个字节.

//返回值:0,成功;

//       其他,失败;

u8 CAN_Send_Msg(u8 *msg,u8 len)

{

    u16 i=0;

    u8 mbox;

    

    CanTxMsg TxMessage; 

    TxMessage.StdId=0x12; //标准ID,设置为扩展时自动变0

    TxMessage.ExtId=0x12; //扩展ID

    TxMessage.IDE=0; //决定是标准(1)还是扩展模式(0)

    TxMessage.RTR=0; //表明是数据帧(0)还是遥控帧(1),当是遥控帧时TxMessage.Data为0

    TxMessage.DLC=len; //数据长度(最大为8) 

    for(i=0;i        TxMessage.Data[i] = msg[i];

    

    mbox = CAN_Transmit(CAN1,&TxMessage); //发送数据,返回所使用邮箱的号码,如果没有空邮箱返回 CAN_NO_MB

    i=0;

    while((CAN_TransmitStatus(CAN1,mbox)==CAN_TxStatus_Failed)&&(i<0xfff)) i++; //发送完退出,未发送完i自加到0xfff时强制退出

    if(i>=0xfff) return 1; //失败

    return 0; //成功

}

 

 

//can口接收数据查询

//buf:数据缓存区;     

//返回值:0,无数据被收到;

//       其他,接收的数据长度;

u8 CAN_Receive_Msg(u8 *buf)

{

    u32 i;

    CanRxMsg RxMessage; //结构体定义

    if(CAN_MessagePending(CAN1,CAN_FIFO0)==0) return 0; //邮箱为空

    CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);

    for(i=0;i        buf[i] = RxMessage.Data[i];

    return RxMessage.DLC;//返回接收的数据长度

}

can.h


#ifndef _can_H

#define _can_H

 

#include "system.h"

 

 

void CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);

u8 CAN_Send_Msg(u8 *msg,u8 len);

u8 CAN_Receive_Msg(u8 *buf);

 

#endif

main.c


#include "system.h"

#include "SysTick.h"

#include "led.h"

#include "usart.h"

#include "can.h"

#include "key.h"

int main()

{

    u8 i,j,key;

    u8 mode=0; //默认是正常模式

    u8 res;

    u8 tbuf[8],char_buf[8];

    u8 rbuf[8];

    

    SysTick_Init(72);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组

    LED_Init();

    USART1_Init(9600);

    KEY_Init();

    

    CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_Normal);

    

    while(1)

    {   

        key =KEY_Scan(0);

        if(key==KEY_UP) //切换模式

        {

            mode = !mode; //模式切换,正常模式0x00,环回模式0x01

            CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,mode);

            if(mode==0) 

                printf("Normal Modern");//正常模式

            else

                printf("LoopBack Modern");//环回模式

        }

        else if(key==KEY_DOWN)//发送接收数据

        {

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

            {

                tbuf[j] = j;

                char_buf[j] = tbuf[j]+0x30;//加0x30变ASC码

            }

            res = CAN_Send_Msg(tbuf,8); //返回0成功

            if(res)

                printf("Send Failedrn");

            else

                printf("发送数据:%srn",char_buf);

        }

        res = CAN_Receive_Msg(rbuf); //返回0失败,非0为接收数据长度

        if(res) //res不为0就可进入

        {

            for(j=0;j            {

                char_buf[j] = rbuf[j]+0x30; //加0x30变ASC码

            }

            printf("接收数据:%srn",char_buf);

        }

        i++;

        if(i%20==0)

        {

            led1=!led1;

        }

        

        delay_ms(10);

            

    }

}

推荐阅读

史海拾趣

DFI公司的发展小趣事

DFI深知产品质量对于企业的重要性。因此,公司从设计到生产,都实施了严格的质量管理。在产品设计阶段,DFI的专责团队会对电路、机构和零组件进行严格的测试与检验,确保每个专案的设计和质量都具备一致的高质量。在生产阶段,所有产品出货前都必须通过完整的产品内部检验,以确保产品的可靠性和耐久性。这些质量管理措施使DFI的产品在市场上享有良好的口碑,也为公司赢得了众多客户的信任。

Devar Inc公司的发展小趣事

智能家居是电子行业的一个重要发展方向,Devar Inc公司也积极拓展这一领域。公司推出了一系列智能家居产品,如智能音箱、智能照明、智能安防等。这些产品不仅具备远程控制、语音控制等便捷功能,还通过Devar的AI技术实现了智能学习和智能联动。例如,智能音箱可以根据用户的习惯和喜好,为用户推荐音乐、新闻等内容;智能照明则可以根据环境光线和用户需求自动调节亮度和色温。

光大芯业公司的发展小趣事

在公司的成长过程中,光大芯业始终坚持以技术为核心,不断寻求技术上的突破。他们积极与国内外知名科研院所开展技术合作,引进先进的技术和设备,提升自身的研发能力。其中,与浙江大学微电子研究所的合作,成功开发出了开关电源管理芯片SDC7500,这一成果不仅填补了国内市场的空白,也展示了光大芯业在技术创新方面的实力。

Cosel公司的发展小趣事

在电子行业,技术创新是企业发展的关键。Cosel公司深知这一点,因此在发展过程中不断引进先进的技术和管理理念。1979年,公司引进了质量控制圈(QC circle)活动,通过全员参与的方式提高产品质量和客户满意度。随后,公司又引进了TQC(全面质量管理)和方针管理,进一步提升了企业的运营效率和产品质量。这些举措使得Cosel公司的产品在市场上获得了良好的口碑。

启珑(CHIPLON)公司的发展小趣事

在电子行业,技术创新是企业发展的关键。Cosel公司深知这一点,因此在发展过程中不断引进先进的技术和管理理念。1979年,公司引进了质量控制圈(QC circle)活动,通过全员参与的方式提高产品质量和客户满意度。随后,公司又引进了TQC(全面质量管理)和方针管理,进一步提升了企业的运营效率和产品质量。这些举措使得Cosel公司的产品在市场上获得了良好的口碑。

Horn公司的发展小趣事

随着汽车、通用工程、液压/气动、珠宝和医疗设备等行业对高精度切削工具需求的增长,Horn公司不断加大研发投入。公司成功开发出超硬切削材料如单晶金刚石(MCD)、多晶金刚石(PCD)和立方氮化硼(PCBN),这些材料的应用极大地提高了切削效率和加工精度。Horn公司的技术创新不仅满足了市场对高质量刀具的需求,还推动了整个切削工具行业的进步。

问答坊 | AI 解惑

980系统图

[ 本帖最后由 fish001 于 2009-12-24 09:12 编辑 ]…

查看全部问答>

摄像头编程类+类调用+例子

本帖最后由 paulhyde 于 2014-9-15 09:18 编辑 using System; using System.Runtime.InteropServices; using System.Drawing.Imaging; using System.Windows.Forms; using System.Drawing; namespace YHhotel.YHhotelWindows //注意这里要 ...…

查看全部问答>

USB Serial Class问题

大虾好,    我知道USB Serial Class是把USB模拟程串口来用,现在我就是想通过USB这个串口来和电脑传数据,但是USB接上去后就成了ACTIVE SYNC了,需要怎样设置或修改才能让它当作个串口和电脑收发数据呢?  …

查看全部问答>

51单片机=====74hc573(锁存器)

51单片机=====74hc573(锁存器) BY: 飞龙  QQ: 9086074    希望认识更多的单片机开发朋友一起交流   第一次做教程不好多多见谅 BLOG: http://hi.baidu.com/alalmn 1.        烧写程序 2.&n ...…

查看全部问答>

AfxMessage,在线等

环境是evc++    SP4   afxmessage里面的参数想用1句话加一个变量来做, 例如,我买个5本书,这里的5就是变化的。 用了一下几种方式都不可以,请教高人帮忙来做, AfxMessageBox(\"我买了\"+CString(number)+\"本书\"); ...…

查看全部问答>

谁能给我提供一份支持SD2.0版本的注册表的文件看看,谢谢

主要就是platform.reg和platform.bib这两个文件,谢谢了, 邮箱longqm1984@163.com 谢谢,,因为我没有看到我的那里有调用我的sdbus.dll和sdmemory.dll的入口处,代码中没有找到,谢谢,。…

查看全部问答>

EE_FPGA V1.0 器件代购总表

注意事项: 1. 红外接口芯片TFDU4100没买到 2. 有源晶振提供一个   交易总价:125元 + 20元(快递费) 淘宝地址:   http://item.taobao.com/auction/item_detail.htm?item_num_id=8252057915   详细清单如下:   ...…

查看全部问答>

求板上各位大虾们帮忙选购倾角传感器

需要做一个模块进行倾角的实时测量,一般在垂直方向上。左右波动30度大概。输出信号接到dsp开发板上,所以输出是模拟和数字的都行。 看到有人用sca60c sca61t        sca100t SCA103T 不知道哪个更适合,或者其他的传感 ...…

查看全部问答>