基于STM32的CAN通讯,已在实际项目中应用

合集下载

基于STM32单片机的分布式智能配电终端设计

基于STM32单片机的分布式智能配电终端设计

基于STM32单片机的分布式智能配电终端设计摘要:本文基于STM32单片机设计了一种分布式智能配电终端,旨在解决传统配电系统中存在的信息不对称、操作不便等问题。

通过该终端,用户可以实现对电力系统的监测、控制、保护等多种功能,实现配电系统的自动化、智能化。

在系统设计中,我们使用了基于CAN总线的分布式控制架构,以及基于嵌入式系统的设计方法,使得该终端具有可靠性、稳定性和实用性。

最后,通过实验验证了该终端的性能和可行性。

关键词:STM32单片机;分布式智能配电终端;CAN总线;嵌入式系统引言:随着信息技术和自动化技术的不断发展,电力系统的自动化、智能化已经成为发展趋势。

传统的配电系统中存在着信息不对称、操作不便等问题,给配电系统的安全和稳定带来了很大的隐患。

因此,设计一种高可靠性、稳定性和实用性的分布式智能配电终端,对于实现配电系统的自动化和智能化具有重要意义。

目前,单片机技术已经成为智能电力系统中不可或缺的组成部分。

STM32单片机是一款功能强大、性能稳定的单片机芯片,具有低功耗、高速度、高精度等特点,适用于各种工业控制、智能家居等领域。

一.传统配电系统的问题与不足(一)信息不对称传统配电系统中,信息流动不畅,各个环节之间缺乏有效的信息传递和处理,导致信息不对称。

例如,传统的配电系统中,电力信息需要手动收集,而且数据精度低,容易出现错误,使得对电力系统的监测和保护变得困难。

此外,对于故障信息的传递和处理也存在问题。

由于缺乏有效的通讯手段,故障信息往往需要经过多次传递才能到达责任部门,导致故障响应时间较长,影响配电系统的安全和稳定。

(二)操作不便传统配电系统的操作往往需要人工干预,人工操作控制,效率低下,存在安全隐患。

例如,传统配电系统的开关操作需要人工进行,操作不便,容易出现误操作或操作不当,造成安全事故。

此外,对于配电系统的监测和保护,也需要人工干预,无法实现自动化和智能化,效率低下,使得配电系统的运行效率和稳定性下降。

选煤厂智能除尘系统设计与应用分析

选煤厂智能除尘系统设计与应用分析

选煤厂智能除尘系统设计与应用分析河北省煤炭洗选工程技术研究中心河北唐山063012摘要:选煤厂除尘不仅是环境保护、职业安全与劳动保护的要求,也是智能化选煤厂建设、质量标准化选煤厂考核的重要内容。

传统的选煤厂除尘设计,只重视原煤干法筛分环节,对选煤厂全工艺流程的梳理及除尘设计重视不够。

选煤厂智能除尘理念,包括电厂及煤化工的输煤系统除尘设计、施工及使用效果使得除尘系统更上一个新台阶。

为针对选煤厂喷雾降尘系统存在的降尘率不高、实时性差、控制灵活度不够的问题,本文所阐述的除尘系统以STM32微控制器为核心,基于CAN总线通讯完成对分布在选煤厂各降尘点的喷雾控制器的控制。

实际系统测试结果表明,该智能除尘系统能够有效降低选煤厂粉尘浓度,降尘率约达93%,保障选煤厂安全生产。

关键词:智能除尘;喷雾降尘;CAN总线通讯;STM32控制器;Keil ARM引言近年来,选煤厂的粉尘治理已经引起设计、生产、研发制造部门的高度重视,一些除尘新技术、新工艺、新设备不断涌现。

尤其在选煤厂选煤过程中会产生许多细微粉尘颗粒,其中粉尘直径小于7.7微米的粒子会以游离态悬浮于空气中,粉尘直径小于5微米的粒子为可呼吸性粉尘,危害员工健康。

选煤厂设备粘附粉尘后会加速设备老化、缩短设备使用周期,严重时会诱发设备故障。

当选煤厂空气粉尘浓度达到一定浓度时会有爆炸的潜在危险,造成严重的安全生产事故。

因此,研究并设计选煤厂喷雾降尘系统具有重要意义。

国内外学者针对选煤厂降尘展开一系列研究。

国内学者借鉴国外降尘原理,基于气溶胶力学、稳态均匀流程力学、颗粒群两相流模型等建立降尘模型,并应用单片机技术、PLC技术、微控制器技术以及传感器技术建立降尘控制系统,达到喷雾降尘的目的。

同时为增加选煤厂喷雾降尘系统的智能性,研究就地控制、远程控制、智能控制等多种模式,促进选煤厂降尘系统向智能化、信息化方向发展。

1智能除尘系统总体设计方案选煤厂智能除尘系统总体设计方案见图1,在选煤厂粉尘指定点设置喷雾控制器1-n,用于就地控制该范围内的降尘设备并实时采集粉尘数据。

基于STM32的CAN总线通信设计

基于STM32的CAN总线通信设计

基于STM32的CAN总线通信设计近年来,CAN(Controller Area Network)总线通信在汽车电子控制系统和工业领域得到了广泛应用。

作为一种高可靠性、高实时性的通信协议,CAN总线能够实现多节点之间的高效数据传输。

STM32系列微控制器作为嵌入式系统设计领域的重要成员,具备强大的处理能力和丰富的外设资源,被广泛用于CAN总线通信的设计和应用。

本文将介绍,包括硬件设计和软件编程两个方面。

首先,我们将讨论如何选择合适的STM32微控制器和CAN收发器。

其次,我们将详细描述硬件连接和接口电路设计。

最后,我们将介绍CAN总线通信软件的编程方法和实现。

在硬件设计方面,选择合适的STM32微控制器和CAN收发器是至关重要的。

STM32系列微控制器具备不同的处理能力和资源配置,应根据具体应用需求来选择。

CAN收发器是将STM32与CAN总线连接的重要部件,需要根据通信速率和总线特性选择合适的收发器。

在硬件连接和接口电路设计方面,需要参考STM32的引脚分配和电气特性,正确连接CAN收发器和其他外设。

同时,还需要考虑如何提供稳定的电源和适当的信号滤波电路,以保证CAN总线通信的可靠性和稳定性。

在软件编程方面,首先,需要在STM32的开发环境中配置CAN总线通信所需的外设和时钟。

然后,根据具体需求设置CAN总线的通信速率、帧格式和过滤器等参数。

接下来,编写CAN总线发送和接收数据的代码。

在发送数据时,需要将数据打包成CAN帧的格式,并将其发送到CAN总线;在接收数据时,需要监听CAN总线上的数据帧,并将接收到的数据解码处理。

此外,为了提高CAN总线通信的可靠性,还可以加入错误检测和纠错代码。

在实际应用中,广泛应用于汽车电子控制系统和工业自动化领域。

在汽车电子控制系统中,CAN总线通信可以实现各个控制单元之间的数据交换和协调工作,提高整车系统的性能和安全性。

例如,发动机控制单元、制动系统控制单元和防抱死系统控制单元可以通过CAN总线通信实现数据的快速传输和实时响应。

STM32上的CAN通讯是什么?CAN模式功能的详细分析

STM32上的CAN通讯是什么?CAN模式功能的详细分析

STM32上的CAN通讯是什么?CAN模式功能的详细分析CAN模式一.工作模式通过CAN_MCR寄存器控制INRQ和SLEEP 1.初始化INRQ=1 SLEEP=0 软件初始化应该在硬件 2.正常INRQ=0 SLEEP=0 在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文 3.睡眠SLEEP=1 bxCAN可工作在低功耗的睡眠模式二.测试模式通过CAN_BTR寄存器控制LBKM和SILM 1. 静默可以接受不能发送2. 循回可以发送不能接受3.环回静默只能自发自收三.调试模式STM32标识符筛选器在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的优先级相关的。

因此,节点在接收报文时-根据标识符的值-决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。

为满足这一需求,bxCAN为应用程序提供了14个位宽可变的、可配置的过滤器组(13~0),以便只接收那些软件需要的报文。

硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用一定的CPU 开销。

STM32普通型芯片的CAN 有14组过滤器组(互联型有28组过滤器组),用以对接收到的帧进行过滤。

每组过滤器包括了2个可配置的32位寄存器:CAN_FxR1和CAN_FxR2。

对于过滤器组,通过设置CAN_FM0R的FBMx位, 1.屏蔽位模式这样CAN_FxR0中保存的就是标识符匹配值,CAN_FxR2中保存的是屏蔽码,即CAN_FxR2中如果某一位为1,则CAN_FxR1中相应的位必须与收到的帧的标志符中的相应位吻合才能通过过滤器。

CAN_FxR2中为0的位表示CAN_FxR1中的相应位可不必与收到的帧进行匹配。

2.标识符列表模式此时CAN_FxR1和CAN_FxR2中的都是要匹配的标识符,收到的帧的。

stm32 canopen 例子

stm32 canopen 例子

stm32 canopen 例子摘要:1.引言2.STM32微控制器简介3.CANopen协议简介4.STM32 CANopen例子概述5.硬件设计6.软件设计7.总结正文:1.引言随着工业自动化和物联网技术的不断发展,嵌入式系统在各领域得到了广泛应用。

其中,STM32系列微控制器凭借出色的性能和低功耗特点,成为了嵌入式领域的热门选择。

CANopen协议作为一种基于CAN总线的通信协议,具有良好的实时性和可靠性,在工业自动化领域有着广泛的应用。

本文将介绍一个基于STM32的CANopen例子,以供参考。

2.STM32微控制器简介STM32系列微控制器是意法半导体公司推出的一款基于ARM Cortex-M 内核的32位闪存微控制器。

它具有高性能、低功耗、多功能、易扩展等特点,广泛应用于嵌入式系统领域。

3.CANopen协议简介CANopen协议是基于CAN总线的通信协议,由德国的Robert Bosch GmbH公司开发。

它是一种用于实时控制的开放式串行通信协议,具有多主控制结构、高可靠性、实时性好等特点。

CANopen协议在工业自动化领域得到了广泛应用,特别是在工业控制器和现场设备之间的通信。

4.STM32 CANopen例子概述本文将以一个简单的STM32 CANopen例子为例,介绍如何实现基于STM32的CANopen通信。

该例子采用STM32F103C8T6微控制器,具备两个CAN通道,分别用于发送和接收数据。

硬件方面,通过扩展CAN收发器及相关的外围器件,实现CANopen通信;软件方面,编写相应的程序实现CANopen协议的帧传输、数据处理等功能。

5.硬件设计硬件设计主要包括微控制器、CAN收发器、外围器件等的选型和连接。

首先,选用STM32F103C8T6微控制器作为核心控制器,通过SPI接口与CAN 收发器(如TJA1020)进行通信。

其次,根据需要选择其他外围器件,如电源模块、晶振模块、复位模块等。

stm32f429的can2通信教程实例

stm32f429的can2通信教程实例

stm32f429的can2通信教程实例STM32F429是一款基于ARM Cortex-M4内核的高性能微控制器,具有丰富的外设资源,包括多个CAN接口。

在本教程中,我们将重点介绍如何使用STM32F429的CAN2接口进行通信。

下面是一个教程实例,详细说明了CAN2通信的步骤。

1.硬件准备:首先,我们需要准备一些硬件设备,包括一块STM32F429开发板、两个CAN收发器和一根CAN总线电缆。

将CAN收发器连接到开发板的CAN2接口,并将CAN总线电缆连接到两个CAN收发器上。

2.软件设置:接下来,我们需要进行一些软件设置,包括配置CAN2引脚和CAN2控制器。

在STM32CubeMX软件中选择我们的目标芯片型号(STM32F429),然后打开"Pinout & Configuration"选项卡。

在该选项卡中,我们可以看到引脚配置图,找到CAN2的引脚(例如:CAN2_RX和CAN2_TX),并将它们连接到正确的引脚上。

完成引脚配置后,点击"Project"选项卡,然后点击"Generate Code"按钮生成代码。

3.初始化CAN2控制器:在生成的代码中,我们可以找到一个名为"main.c"的源文件。

打开这个文件,在其中找到"MX_CAN1_Init(void)"函数,并将其改为"MX_CAN2_Init(void)"函数,以便初始化CAN2控制器。

在该函数中,我们需要进行一些配置,包括设置波特率、使能接收中断和使能CAN2控制器。

波特率设置应与通信系统中的所有设备一致,以确保数据的正确传输。

4.发送CAN2数据:现在,我们可以开始编写代码来发送CAN2数据。

首先,在main.c 文件中定义一个名为"CAN2_TxMessage"的全局变量,用于存储要发送的数据。

STM32的can总线实验心得

STM32的can总线实验心得(一) 工业现场总线 CAN 的基本介绍以及 STM32 的 CAN 模块简介首先通读手册中关于CAN的文档,必须精读。

STM32F10xxx 参考手册Rev7V3.pdf/bbs/redirect.php?tid=255&goto=lastpost#lastpos t需要精读的部分为 RCC 和 CAN 两个章节。

为什么需要精读 RCC 呢?因为我们将学习 CAN 的波特率的设置,将要使用到RCC 部分的设置,因此推荐大家先复习下这部分中的几个时钟。

关于 STM32 的 can 总线简单介绍bxCAN 是基本扩展 CAN (Basic Extended CAN) 的缩写,它支持 CAN 协议 2.0A 和 2.0B 。

它的设计目标是,以最小的 CPU 负荷来高效处理大量收到的报文。

它也支持报文发送的优先级要求(优先级特性可软件配置)。

对于安全紧要的应用,bxCAN 提供所有支持时间触发通信模式所需的硬件功能。

主要特点· 支持 CAN 协议 2.0A 和 2.0B 主动模式· 波特率最高可达 1 兆位 / 秒· 支持时间触发通信功能发送· 3 个发送邮箱· 发送报文的优先级特性可软件配置· 记录发送 SOF 时刻的时间戳接收· 3 级深度的2个接收 FIFO· 14 个位宽可变的过滤器组-由整个 CAN 共享· 标识符列表· FIFO 溢出处理方式可配置· 记录接收 SOF 时刻的时间戳可支持时间触发通信模式· 禁止自动重传模式· 16 位自由运行定时器· 定时器分辨率可配置· 可在最后 2 个数据字节发送时间戳管理· 中断可屏蔽· 邮箱占用单独 1 块地址空间,便于提高软件效率(二) STM32 CAN 模块工作模式STM32 的 can 的工作模式分为:/* CAN operating mode */#define CAN_Mode_Normal ((u8)0x00) /* normal mode */#define CAN_Mode_LoopBack ((u8)0x01) /* loopback mode */#define CAN_Mode_Silent ((u8)0x02) /* silent mode */#define CAN_Mode_Silent_LoopBack ((u8)0x03) /* loopback combined with silent mode */在此章我们的 Mini-STM32 教程中我们将使用到CAN_Mode_LoopBack和CAN_Mode_Normal两种模式。

stm32应用与全案例实践

stm32应用与全案例实践STM32是意法半导体推出的一款微控制器,具有强大的计算性能和实时性能,被广泛应用于物联网、智能家居、消费电子、汽车等领域。

在STM32的应用中,有一些经典的案例,下面我们来看看这些案例。

1.制作DIY游戏机DIY游戏机是一个有趣的项目,可以让孩子们学会编程和电子知识。

通过使用STM32,可以构建一个基于Raspberry Pi的游戏机,它具有128x64 OLED屏幕、A/B按钮、D-pad 和杆。

使用STM32还可以实现双人游戏,通过串口连接两台游戏机。

2.智能家居应用STM32可以用来控制智能家居设备,例如智能灯、智能窗帘、智能门锁等。

通过使用STM32的无线通信模块,可以实现智能家居设备的远程控制和监控。

此外,还可以使用STM32的语音识别功能和人机交互界面,为用户提供更方便的智能家居体验。

3.汽车电子应用STM32广泛应用于汽车电子中,例如车载导航、车载娱乐、车载传感器等。

STM32可以通过在汽车内部安装传感器,监测车辆的速度、转向、温度、湿度等数据,并且可以将这些数据传输到车载导航和娱乐系统中进行处理。

此外,STM32还可以用于汽车安全系统,例如自动紧急制动、自动驾驶等。

4.工业自动化应用STM32可以应用于工业自动化中,例如机器人控制、PLC控制、工业传感器等。

STM32可以通过与其他工业设备进行通信,实现自动化流程的控制和监测。

此外,STM32还可以与云平台和数据采集系统进行整合,为工业自动化系统提供更完善的数据处理和分析功能。

总之,STM32是一个功能强大的微控制器,可以应用于多个领域,提供丰富的功能和应用场景。

对于学习STM32的人来说,了解这些案例可以帮助他们更好地理解STM32的应用。

基于STM32单片机的物料搬运小车

基于STM32单片机的物料搬运小车物料搬运小车作为自动化物流系统不可或缺的一环,广泛应用于仓库、车间等大型物料存储、运输和分拣场所。

本文将介绍一种基于STM32单片机的物料搬运小车的设计。

1.硬件设计本物料搬运小车采用STM32F103RET6单片机作为控制核心,通过CAN总线与上位机或其他设备通信。

小车采用驱动电机为两轮驱动,小车平衡重心通过附加支架以及底盘设计来实现。

为了保证小车行驶的精度和稳定性,小车需要进行导轨的安装。

导轨一般采用铝合金材料,但在实际的制造过程中,需对其进行精密加工以及调试。

为了确保小车在复杂、不稳定的环境下能够正常工作,除了硬件设计外,小车的控制程序也非常重要。

本小车采用移动式采集控制方法,由上位机通过CAN总线向小车发送指令、数据,控制小车运动状态。

小车控制程序主要包括三个模块:通讯模块、控制模块和调试模块。

(1)通讯模块通讯模块主要负责与上位机进行通讯,包括数据的接收和发送。

本小车采用CAN总线进行通讯,CAN总线的通讯速度高,且能够保证通讯的可靠性和实时性。

(2)控制模块控制模块主要负责针对小车运动要求,对电机进行控制,使小车能够在一定速度下准确行驶,并做出相应的动作。

其中,速度控制是小车控制程序中一个至关重要的部分。

由于小车的速度控制需要精度较高,因此采用了PI控制方法。

(3)调试模块调试模块主要负责程序中的错误调试以及代码的优化,通过该模块,可以对程序进行定时、打印以及调试等操作。

总之,本文所介绍的基于STM32单片机的物料搬运小车在硬件和软件设计方面都具有一定的可扩展性和灵活性。

随着更先进的控制理论、更高精度的传感器以及更高效的驱动器的不断涌现,小车在未来的发展中将具有更广泛的应用和更强大的性能。

基于STM32的RS232-CAN通信协议转换器设计

基于STM32的RS232-CAN通信协议转换器设计王英志;杨佳;韩太林【摘要】依据RS232接口和CAN总线的特点,设计了RS232接口与CAN总线的协议转换器。

以集成串行接口和CAN总线控制器的STM32F103C8单片机为核心,设计转换器的硬件电路和软件程序,实现RS232和CAN总线通信协议的转换。

本转换器具有通信隔离、防雷电等功能,具有体积小,成本低,便于实现,易于推广等特点,在应用中取得良好效果。

【期刊名称】《制造业自动化》【年(卷),期】2013(000)014【总页数】3页(P141-143)【关键词】协议转换;CAN总线;RS232;STM32F103C8【作者】王英志;杨佳;韩太林【作者单位】长春理工大学电子信息工程学院,长春130022;吉林建筑工程学院电气与电子信息工程学院,长春130021;长春理工大学电子信息工程学院,长春130022【正文语种】中文【中图分类】TP2730 引言目前,RS232接口和CAN总线接口广泛应用于工业设备之间的通信。

它们各有特点,应用在不同领域。

RS232通信距离短,接口容易损坏。

CAN总线具有多点通信、组网方便,传输距离远,通信实时性好,纠错能力强,成本低等特点,能更好地匹配和协调各个控制系统[1]。

基于两种接口特点,本文介绍一种实现RS232接口设备与CAN总线设备进行通信的转换器,更好的解决用户在地域、通信网络、接口协议等方面的矛盾。

1 系统硬件设计RS232-CAN通信协议转换器设计,主要是完成RS232与CAN总线之间的通信协议转换,实现数据的互联通信。

在通信过程中,为了使系统具有通用性和稳定性,对供电电源、通信隔离、防雷电等方面进行了特殊设计。

系统原理框图如图1所示。

图1 系统原理框图1.1 单片机选择选用意法半导体公司ARM Co rtex™-M 3核的32位STM 32F103C8单片机,负责系统的整体运行。

单片机特点为:最大时钟频率为72MHz,3个16位定时器,其内部集成CAN2.0控制器、USART接口和USB2.0全速接口等,调试模式为SWD和JATG接口。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

与本程序代码相关部分的原理图及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;注意//#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */ CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;CAN_InitStructure.CAN_Prescaler = 4;//2nominal bit time(3+5+1)tq=9tq关于分频系数,查看 system_stm32f10x.c下面的static void SetSysClockTo72(void) 函数:/* HCLK = SYSCLK *//* PCLK2 = HCLK *//* PCLK1 = HCLK/2 */所以can时钟 72MHZ/2/4=9 Mhz,tq=1/36Mhz波特率为 1/nominal bit time= 9/9=1MHZ=====================================================================void CAN_Configuration(void){CAN_InitTypeDef CAN_InitStructure;CAN_FilterInitTypeDef CAN_FilterInitStructure;/* CAN register init */CAN_DeInit();CAN_StructInit(&CAN_InitStructure);/* CAN cell init */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);/* CAN filter init */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);}注意//#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */波特率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"ErrorStatus HSEStartUpStatus;void Uart1_PutChar(u8 ch);unsigned int j; //j=2-8/* Private typedef -----------------------------------------------------------*/ typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus; //状态量__IO uint32_t ret = 0; //用于中断返回的传递变量volatile TestStatus TestRx;CanTxMsg TxMessage;CanRxMsg RxMessage;unsigned char read_temp;unsigned char open_temp,stop_temp,top_temp;uint16_t CCR1_Val=0 ;#define start 50#define accelerate 10#define Period 999#define Prescaler 9//double percent=0.9;vu32 counter=0;vu32 compare ;uint16_t High_fre=900;unsigned int Tulun_i=0; //500次作为一个脉冲GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;//Private functions 函数---------------------------------------------------------*/void UART_Init(void);ErrorStatus HSEStartUpStatus;void RCC_Configuration(void); //申明时钟初始化函数void GPIO_Configuration(void); //申明IO初始化函数void NVIC_Configuration(void); //申明中断管理器初始化函数void CAN_Configuration(void); //申明CAN初始化函数void CAN_TX(unsigned char add,unsigned char data1,unsigned char data2);//申明CAN发送函数TestStatus CAN_RX(void); //申明带返回参数的CAN接收函数void LED_RESET(void);void PWM_startN(void);void PWM_start(void);/****** Main program ***********/int main(void){u32 n;/* 系统时钟初始化 */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){case 01:PWM_start(); break;case 02:PWM_startN();break;default: GPIO_ResetBits(GPIOA, GPIO_Pin_2);GPIO_ResetBits(GPIOA, GPIO_Pin_1); break;}ret = 0;}}}/* 开始输出PWM */void PWM_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_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);/* PWM1 Mode configuration: Channel2 */GPIO_ResetBits(GPIOA, GPIO_Pin_1);TIM_ARRPreloadConfig(TIM2, ENABLE);switch(top_temp){case 01: High_fre=100; break;case 02:High_fre=500 ;break;case 03:High_fre=900 ;break;default:break;}switch(stop_temp){case 01:compare=100000; break;case 02:compare=200000 ;break;case 03:compare=50000 ;break;default:break;}TIM_Cmd(TIM2, ENABLE);TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);/* TIM2 enable counter */}/* 停止输出PWM */void PWM_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_OCPolarity = TIM_OCPolarity_Low;TIM_OC3Init(TIM2, &TIM_OCInitStructure);TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);/* PWM1 Mode configuration: Channel2 */GPIO_ResetBits(GPIOA, GPIO_Pin_2);TIM_ARRPreloadConfig(TIM2, ENABLE);switch(top_temp){case 01: High_fre=100; break;case 02:High_fre=500 ;break;case 03:High_fre=900 ;break;default:break;}switch(stop_temp){case 01:compare=100000; break;case 02:compare=200000 ;break;case 03:compare=50000 ;break;default:break;}TIM_Cmd(TIM2, ENABLE);TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);/* TIM2 enable counter */}void TIM2_IRQHandler(void){static unsigned int i=0;static unsigned int j=0;if (TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET){if(counter<compare){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 */void LED_RESET(void){GPIO_WriteBit(GPIOB, GPIO_Pin_0, (BitAction)0x00); //关LED GPIO_WriteBit(GPIOB, GPIO_Pin_1, (BitAction)0x00);}/*******************************************************************************Configures the different system clocks.*******************************************************************************/void RCC_Configuration(void){ErrorStatus HSEStartUpStatus;/* RCC system reset(for debug purpose) */RCC_DeInit(); //时钟控制寄存器全部恢复默认值/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON); //外部高速时钟源开启(8M晶振)/* Wait till HSE is ready */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分频/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2); //设定内部FLASH的的延时周期为2周期 /* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能FLASH预存取缓冲区/* PLLCLK = 8MHz * 9 = 72 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟为外部高速时钟的9倍频/* Enable PLL */RCC_PLLCmd(ENABLE); //使能PLL时钟/* Wait till PLL is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟设置完成准备就绪 {}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //使用PLL时钟作为系统时钟源 /* Wait till PLL is used as system clock source *//* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08) //返回系统所用时钟源确认为外部高速晶振,8M晶振。

相关文档
最新文档