基于stm32can通讯已在实际项目中应用.docx

上传人:b****6 文档编号:12815673 上传时间:2023-06-08 格式:DOCX 页数:58 大小:254.38KB
下载 相关 举报
基于stm32can通讯已在实际项目中应用.docx_第1页
第1页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第2页
第2页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第3页
第3页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第4页
第4页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第5页
第5页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第6页
第6页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第7页
第7页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第8页
第8页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第9页
第9页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第10页
第10页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第11页
第11页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第12页
第12页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第13页
第13页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第14页
第14页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第15页
第15页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第16页
第16页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第17页
第17页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第18页
第18页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第19页
第19页 / 共58页
基于stm32can通讯已在实际项目中应用.docx_第20页
第20页 / 共58页
亲,该文档总共58页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于stm32can通讯已在实际项目中应用.docx

《基于stm32can通讯已在实际项目中应用.docx》由会员分享,可在线阅读,更多相关《基于stm32can通讯已在实际项目中应用.docx(58页珍藏版)》请在冰点文库上搜索。

基于stm32can通讯已在实际项目中应用.docx

基于stm32can通讯已在实际项目中应用

与本程序代码相关部分的原理图及PCB,基于STM32F103VET6,已在项目中应用。

开头篇:

STM32的CAN波特率计算

STM32里的CAN支持2.0A,2.0B,带有FIFO,中断等,这里主要提一下内部的时钟应用。

bxCAN挂接在APB1总线上,采用总线时钟,所以我们需要知道APB1的总线时钟是多少。

我们先看看下图,看看APB1总线时钟:

APB1时钟取自AHB的分频,而AHB又取自系统时钟的分频,系统时钟可选HSI,HSE,PLLCLK,这个在例程的RC设置里都有的,然后再看看有了APB1的时钟后,如何算CAN的总线速率,先看下图:

有了上边的这个图,基本就清楚了:

                      总线时钟MHz  (3+TS1+TS2)*(BRP+1)

======================================================================

下面是我的计算:

CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;

CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;

注意//#defineCAN_BS1_3tq                ((uint8_t)0x02)/*!

<3timequantum*/

CAN_InitStructure.CAN_BS2=CAN_BS2_5tq;

CAN_InitStructure.CAN_Prescaler=4;//2

nominalbittime(3+5+1)tq=9tq

关于分频系数,查看system_stm32f10x.c下面的staticvoidSetSysClockTo72(void)函数:

/*HCLK=SYSCLK*/

/*PCLK2=HCLK*/

/*PCLK1=HCLK/2*/

所以can时钟72MHZ/2/4=9Mhz,tq=1/36Mhz

波特率为1/nominalbittime=9/9=1MHZ

=====================================================================

voidCAN_Configuration(void)

{

CAN_InitTypeDef        CAN_InitStructure;

CAN_FilterInitTypeDef  CAN_FilterInitStructure;

/*CANregisterinit*/

CAN_DeInit();

CAN_StructInit(&CAN_InitStructure);

/*CANcellinit*/

CAN_InitStructure.CAN_TTCM=DISABLE;

CAN_InitStructure.CAN_ABOM=DISABLE;

CAN_InitStructure.CAN_AWUM=DISABLE;

CAN_InitStructure.CAN_NART=DISABLE;

CAN_InitStructure.CAN_RFLM=DISABLE;

CAN_InitStructure.CAN_TXFP=DISABLE;

CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;

CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;

CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;

CAN_InitStructure.CAN_BS2=CAN_BS2_8tq;

CAN_InitStructure.CAN_Prescaler=200;

CAN_Init(&CAN_InitStructure);

/*CANfilterinit*/

CAN_FilterInitStructure.CAN_FilterNumber=0;

CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;

CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;

CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;

CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;

CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;

CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

CAN_FilterInit(&CAN_FilterInitStructure);

}

注意//#defineCAN_BS1_3tq                ((uint8_t)0x02)/*!

<3timequantum*/

波特率10K,公式:

72MHZ/2/200/(1+9+8)=0.01,即10Kbps  

正文篇:

程序代码

/*Includes------------------------------------------------------------------*/

#include"stm32f10x.h"

#include"platform_config.h"

#include"stm32f10x_rcc.h"

#include"stm32f10x_flash.h"

#include"stm32f10x_usart.h"

#include"stm32f10x_gpio.h"

#include"stm32f10x_tim.h"

#include"stdio.h"

ErrorStatusHSEStartUpStatus;

voidUart1_PutChar(u8ch);

unsignedintj;//j=2-8

/*Privatetypedef-----------------------------------------------------------*/

typedefenum{FAILED=0,PASSED=!

FAILED}TestStatus;//状态量

__IOuint32_tret=0;//用于中断返回的传递变量

volatileTestStatusTestRx;

CanTxMsgTxMessage;

CanRxMsgRxMessage;

unsignedcharread_temp;

unsignedcharopen_temp,stop_temp,top_temp;

uint16_tCCR1_Val=0;

#definestart50

#defineaccelerate10

#definePeriod999

#definePrescaler9

//doublepercent=0.9;

vu32counter=0;

vu32compare;

uint16_tHigh_fre=900;

unsignedintTulun_i=0;//500次作为一个脉冲

GPIO_InitTypeDefGPIO_InitStructure;

NVIC_InitTypeDefNVIC_InitStructure;

TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;

TIM_OCInitTypeDefTIM_OCInitStructure;

//Privatefunctions函数---------------------------------------------------------*/

voidUART_Init(void);

ErrorStatusHSEStartUpStatus;

voidRCC_Configuration(void);//申明时钟初始化函数

voidGPIO_Configuration(void);//申明IO初始化函数

voidNVIC_Configuration(void);//申明中断管理器初始化函数

voidCAN_Configuration(void);//申明CAN初始化函数

voidCAN_TX(unsignedcharadd,unsignedchardata1,unsignedchardata2);//申明CAN发送函数

TestStatusCAN_RX(void);//申明带返回参数的CAN接收函数

voidLED_RESET(void);

voidPWM_startN(void);

voidPWM_start(void);

/******Mainprogram***********/

intmain(void)

{

u32n;

/*系统时钟初始化*/

RCC_Configuration();

/*中断管理器初始化*/

NVIC_Configuration();

/*IO初始化*/

GPIO_Configuration();

UART_Init();//初始化串口函数

/*CAN初始化*/

CAN_Configuration();

TIM_TimeBaseStructure.TIM_Period=Period;

TIM_TimeBaseStructure.TIM_Prescaler=Prescaler;

TIM_TimeBaseStructure.TIM_ClockDivision=0;

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

GPIO_ResetBits(GPIOA,GPIO_Pin_4);

while

(1)

{

CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//开接收中断

for(n=0;n<10000;n++);//延时

if(ret==1)

{

for(j=0;j<8;j++)//发送8组数据到串口

{

Uart1_PutChar(RxMessage.Data[j]);

}

open_temp=RxMessage.Data[0];

top_temp=RxMessage.Data[1];

stop_temp=RxMessage.Data[2];

switch(open_temp)

{

case01:

PWM_start();break;

case02:

PWM_startN();break;

default:

GPIO_ResetBits(GPIOA,GPIO_Pin_2);

GPIO_ResetBits(GPIOA,GPIO_Pin_1);break;

}

ret=0;

}

}

}

/*开始输出PWM*/

voidPWM_start(void)

{

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse=1000-CCR1_Val;

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

TIM_OC3Init(TIM2,&TIM_OCInitStructure);

TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable);

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Disable;

TIM_OCInitStructure.TIM_Pulse=1000-CCR1_Val;

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

TIM_OC2Init(TIM2,&TIM_OCInitStructure);

TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Disable);

/*PWM1Modeconfiguration:

Channel2*/

GPIO_ResetBits(GPIOA,GPIO_Pin_1);

TIM_ARRPreloadConfig(TIM2,ENABLE);

switch(top_temp)

{

case01:

High_fre=100;break;

case02:

High_fre=500;break;

case03:

High_fre=900;break;

default:

break;}

switch(stop_temp)

{

case01:

compare=100000;break;

case02:

compare=200000;break;

case03:

compare=50000;break;

default:

break;}

TIM_Cmd(TIM2,ENABLE);

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

/*TIM2enablecounter*/

}

/*停止输出PWM*/

voidPWM_startN(void)

{

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse=1000-CCR1_Val;

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

TIM_OC2Init(TIM2,&TIM_OCInitStructure);

TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Disable;

TIM_OCInitStructure.TIM_Pulse=1000-CCR1_Val;

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

TIM_OC3Init(TIM2,&TIM_OCInitStructure);

TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Disable);

/*PWM1Modeconfiguration:

Channel2*/

GPIO_ResetBits(GPIOA,GPIO_Pin_2);

TIM_ARRPreloadConfig(TIM2,ENABLE);

switch(top_temp)

{

case01:

High_fre=100;break;

case02:

High_fre=500;break;

case03:

High_fre=900;break;

default:

break;}

switch(stop_temp)

{

case01:

compare=100000;break;

case02:

compare=200000;break;

case03:

compare=50000;break;

default:

break;}

TIM_Cmd(TIM2,ENABLE);

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

/*TIM2enablecounter*/

}

 

voidTIM2_IRQHandler(void)

{

staticunsignedinti=0;

staticunsignedintj=0;

if(TIM_GetITStatus(TIM2,TIM_IT_Update)!

=RESET)

{

if(counter

{

if(i<(High_fre-start)/accelerate)

{

TIM2->CCR2=1000-(start+i*accelerate);

TIM2->CCR3=1000-(start+i*accelerate);

Tulun_i++;

counter++;

if(Tulun_i==500)

{

i++;

Tulun_i=0;

}

}

else

{

TIM2->CCR2=1000-High_fre;

TIM2->CCR3=1000-High_fre;

counter++;

}

}

if(counter==compare)

{

TIM2->CCR2=1000-(start+i*accelerate-j*accelerate);

TIM2->CCR3=1000-(start+i*accelerate-j*accelerate);

Tulun_i++;

if(Tulun_i==500)

{

j++;

Tulun_i=0;

}

if(j==i)

{

TIM2->CCR2=1000;

TIM2->CCR3=1000;

if(Tulun_i==0)

{

TIM_Cmd(TIM2,DISABLE);

TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE);

i=0;

j=0;

counter=0;

}

}

}

TIM_ClearITPendingBit(TIM2,TIM_IT_Update);

}

}

/*关LED*/

voidLED_RESET(void)

{

GPIO_WriteBit(GPIOB,GPIO_Pin_0,(BitAction)0x00);//关LED

GPIO_WriteBit(GPIOB,GPIO_Pin_1,(BitAction)0x00);

}

 

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

Configuresthedifferentsystemclocks.

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

voidRCC_Configuration(void)

{

ErrorStatusHSEStartUpStatus;

/*RCCsystemreset(fordebugpurpose)*/

RCC_DeInit();//时钟控制寄存器全部恢复默认值

/*EnableHSE*/

RCC_HSEConfig(RCC_HSE_ON);//外部高速时钟源开启(8M晶振)

/*WaittillHSEisready*/

HSEStartUpStatus=RCC_WaitForHSEStartUp();//等待外部时钟就绪

if(HSEStartUpStatus==SUCCESS)//如果时钟启动成功

{

/*HCLK=SYSCLK*/

RCC_HCLKConfig(RCC_SYSCLK_Div1);//定义AHB设备时钟为系统时钟1分频

/*PCLK2=HCLK*/

RCC_PCLK2Config(RCC_HCLK_Div1);//定义AHB2设备时钟为HCLK时钟1分频

/*PCLK1=HCLK/2*/

RCC_PCLK1Config(RCC_HCLK_Div2);//定义AHB1设备时钟为HCLK时钟2分频

/*Flash2waitstate*/

FLASH_SetLatency(FLASH_Latency_2);//设定内部FLASH的的延时周期为2周期

/*EnablePrefetchBuffer*/

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能FLASH预存取缓冲区

/*PLLCLK=8MHz*9=72MHz*/

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//配置PLL时钟为外部高速时钟的9倍频

/*EnablePLL*/

RCC_PLLCmd(ENABLE);//使能PLL时钟

/*WaittillPLLisready*/

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)//等待PLL时钟设置完成准备就绪

{

}

/*SelectPLLassystemclocksource*/

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//使用PLL时钟作为系统时钟源

/*Waitt

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 笔试

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2