OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6371|回复: 5

stm32f103主板编写can接收程序

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2021-7-19
在线时间
0 小时
发表于 2021-7-19 09:41:21 | 显示全部楼层 |阅读模式
2金钱
有大神给个例子参考下呗,急求!!!

最佳答案

查看完整内容[请看2#楼]

/***********F103C6T6 CAN接收部分******************/ /* can.h函数 */ /*****************************************************/ #include "can.h" u8 CAN_RX_BUF[8]; unsigned char CAN_RX_FLAG = 0; void CAN_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitSturcture; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
104
金钱
104
注册时间
2021-6-2
在线时间
25 小时
发表于 2021-7-19 09:41:22 | 显示全部楼层
/***********F103C6T6 CAN接收部分******************/
/*                        can.h函数                                       */
/*****************************************************/
#include "can.h"

u8 CAN_RX_BUF[8];

unsigned char CAN_RX_FLAG = 0;

void CAN_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitSturcture;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
       
        //CAN_RX PB8
        GPIO_InitSturcture.GPIO_Pin = CAN_RX_Pin;
        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
       
        //CAN_TX PB9
        GPIO_InitSturcture.GPIO_Pin  =CAN_TX_Pin;
        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
       
        GPIO_Init(CAN_GPIO_PORT,&GPIO_InitSturcture);
}

void CAN_NVIC_Config(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
       
        NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       
        NVIC_Init(&NVIC_InitStructure);
}

void CAN_Mode_Init(u32 tsjw,u32 tbs1,u32 tbs2,u16 brp,u32 mode)
{
        CAN_InitTypeDef CAN_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
       
        GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);
       
        CAN_DeInit(CAN1);
        CAN_StructInit(&CAN_InitStructure);
       
        CAN_InitStructure.CAN_SJW = tsjw;
        CAN_InitStructure.CAN_BS1 = tbs1;
        CAN_InitStructure.CAN_BS2 = tbs2;
        CAN_InitStructure.CAN_Mode = mode;
        CAN_InitStructure.CAN_Prescaler = brp;
        CAN_InitStructure.CAN_NART  =ENABLE;
        CAN_InitStructure.CAN_ABOM = DISABLE;
        CAN_InitStructure.CAN_AWUM = DISABLE;
        CAN_InitStructure.CAN_RFLM = ENABLE;
        CAN_InitStructure.CAN_TTCM = DISABLE;
        CAN_InitStructure.CAN_TXFP = DISABLE;
       
        CAN_Init(CAN1,&CAN_InitStructure);
}

void CAN_Filter_Init(void)
{
        CAN_FilterInitTypeDef CAN_FilterInitStructure;
       
        CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)0x1001<<3)&0xFFFF0000)>>16;
        CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)0x1001<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
        CAN_FilterInitStructure.CAN_FilterNumber = 0;
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
       
        CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
        CAN_FilterInit(&CAN_FilterInitStructure);
}

void Can_Init(void)
{
        CAN_GPIO_Config();
        CAN_NVIC_Config();
        CAN_Mode_Init(CAN_SJW_1tq,CAN_BS1_3tq,CAN_BS2_2tq,12,CAN_Mode_Normal);
        //CAN_Mode_Normal  CAN_Mode_LoopBack
        CAN_Filter_Init();
}

u8 CAN_Send_Msg(u8* msg,u8 len)
{
        CanTxMsg TxMessage;
        u8 i,mbox;
        u16 cunt = 0;

        TxMessage.StdId = 0x0000;
        TxMessage.ExtId = 0x0000;
        TxMessage.IDE = CAN_ID_STD;
        TxMessage.RTR = CAN_RTR_DATA;
        TxMessage.DLC = len;
        for(i = 0;i < len;i ++)
        {
                TxMessage.Data[i] = msg[i];
        }
        mbox = CAN_Transmit(CAN1,&TxMessage);
       
        while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(cunt<0XFFF))
                cunt++;
        if(cunt >= 0xFFF)
                return 0;
        return 1;
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
        CanRxMsg RxMessage;
        uint8_t i;
       
        if(CAN_GetITStatus(CAN1,CAN_IT_FMP0) != RESET)
        {
                CAN_RX_FLAG = 1;
                CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);
               
                for(i = 0;i < 8;i ++)
                        CAN_RX_BUF[i] = RxMessage.Data[i];
               
                CAN_FIFORelease(CAN1,CAN_FIFO0);
                CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);
        }
}
/***********************man.h**************************/
#include "main.h"   
int main(void)
{         
        NVIC_Configuration();
        LED_Init();
        Delay_Init();
        Usart1_Init(9600);
        Can_Init();
        printf("这里是CAN的测试程序\r\n");
        LED0 = 1;
        while(1)                        //主循环
        {
                if(CAN_RX_FLAG == 1)
                {
                        CAN_RX_FLAG = 0;
                        USART1TxData_hex(CAN_RX_BUF,8);
                }
                //CAN_Send_Msg(send_buf,8);
               
                Delay_Ms(100);
                LED0 = !LED0;
        }
}
can发送开发板用的是C8T6,其中中断、GPIO和CAN_Mode配置都是一样的可直接赋值粘贴,过滤器再发送的时候是不需要设置的,所以改成如下:
void CAN_Filter_Init(void)
{
        CAN_FilterInitTypeDef CAN_FilterInitStructure;
       
        CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
        CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
        CAN_FilterInitStructure.CAN_FilterNumber = 0;
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
       
        CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
        CAN_FilterInit(&CAN_FilterInitStructure);
}
再更改下CAN_Send_Msg函数,因为需要发送数据,所以要设置发送ID,不然C6不能正确接收数据。
u8 CAN_Send_Msg(u8* msg,u8 len)
{
        CanTxMsg TxMessage;
        u8 i,mbox;
        u16 cunt = 0;

        //TxMessage.StdId = 0x0000;
        TxMessage.ExtId = 0x1001;
        TxMessage.IDE = CAN_ID_EXT;
        TxMessage.RTR = CAN_RTR_DATA;
        TxMessage.DLC = len;
        for(i = 0;i < len;i ++)
        {
                TxMessage.Data[i] = msg[i];
        }
        mbox = CAN_Transmit(CAN1,&TxMessage);
       
        while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(cunt<0XFFF))
                cunt++;
        if(cunt >= 0xFFF)
                return 0;
        return 1;
}
/***********************main.h******************/
#include "main.h"   
int main(void)
{       
        u8 send_buf[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
        u8 i = 0x00;
       
        NVIC_Configuration();
        LED_Init();
        Delay_Init();
        Usart1_Init(9600);
        Can_Init();
        printf("这里是CAN的测试程序\r\n");
        LED0 = 1;
        while(1)                        //主循环
        {
//                if(CAN_RX_FLAG == 1)
//                {
//                        CAN_RX_FLAG = 0;
//                        USART1TxData_hex(CAN_RX_BUF,8);
//                }
               
                i++;
               
                send_buf[0] = i;
               
                CAN_Send_Msg(send_buf,8);
               
                Delay_Ms(100);
                LED0 = !LED0;
        }
}
需要注意!!!!两个开发板的CAN_RX和CAN_TX不能直接对接,需要在此之间接上CAN收发器。
回复

使用道具 举报

13

主题

643

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2432
金钱
2432
注册时间
2019-12-28
在线时间
527 小时
发表于 2021-7-19 09:58:08 | 显示全部楼层
可以参考下原子的can例程
回复

使用道具 举报

3

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2021-1-11
在线时间
30 小时
发表于 2021-7-19 10:39:17 | 显示全部楼层
帮 顶

回复

使用道具 举报

6

主题

890

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1481
金钱
1481
注册时间
2020-8-19
在线时间
336 小时
发表于 2021-7-19 10:41:05 | 显示全部楼层
原子不是有吗
回复

使用道具 举报

1

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2021-9-6
在线时间
59 小时
发表于 2021-9-14 15:54:55 | 显示全部楼层
JYun 发表于 2021-7-19 09:41
/***********F103C6T6 CAN接收部分******************/
/*                        can.h函数             ...

正好需要,谢谢大神分享
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 12:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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