搜档网
当前位置:搜档网 › 零死角玩转stm32-中级篇8、CAN(Looback)

零死角玩转stm32-中级篇8、CAN(Looback)

零死角玩转stm32-中级篇8、CAN(Looback)
零死角玩转stm32-中级篇8、CAN(Looback)

0、友情提示

《零死角玩转STM32》系列教程由初级篇、中级篇、高级篇、系统篇、四个部分组成,根据野火STM32开发板旧版教程升级而来,且经过重新深入编写,重新排版,更适合初学者,步步为营,从入门到精通,从裸奔到系统,让您零死角玩转STM32。M3的世界,与野火同行,乐意惬无边。

另外,野火团队历时一年精心打造的《STM32库开发实战指南》将于今年10月份由机械工业出版社出版,该书的排版更适于纸质书本阅读以及更有利于查阅资料。内容上会给你带来更多的惊喜。是一本学习STM32必备的工具书。敬请期待!

8、CAN(Looback)

8.1 实验描述及工程文件清单

实验描述can测试实验(中断模式和回环),并将测试信息通过USART1 在超级终端中打印出来。

硬件连接PB8-CAN-RX

PB9-CAN-TX

用到的库文件startup/start_stm32f10x_hd.c

CMSIS/core_cm3.c

CMSIS/system_stm32f10x.c

FWlib/stm32f10x_gpio.c

FWlib/stm32f10x_rcc.c

FWlib/stm32f10x_usart.c

FWlib/stm32f10x_can.c

FWlib/misc.c

用户编写的文件USER/main.c

USER/stm32f10x_it.c

USER/led.c

USER/usart.c

USER/can.c

8.2 CAN简介

CAN是控制器局域网络(Controller Area Network, CAN)的简称,是由研发和生产汽车电子产品著称的德国BOSCH公司开发的,并最终成为国际标准(ISO118?8)。是国际上应用最广泛的现场总线之一。在北美和西欧,CAN

总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以CAN为底层协议专为大型货车和重工机械车辆设计的J1939协议。

近年来,其所具有的高可靠性和良好的错误检测能力受到重视,被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐射强和振动大的工业环境。

野火STM32开发板的CPU(cpu型号为:STM32F103VET6)自带了一个CAN控制器。具体I/O定义为PB8-CAN-RX、PB9-CAN-TX、。板载的CAN外接了一个TJA1050 CAN收发器,外部的CAN设备可以作为一个设备节点挂接到板载的CAN收发器中,实现CAN通信,多个CAN节点通信图如下:

野火STM32开发板中CAN硬件原理图如下:

在本实验中并没有用得到双CAN通信,只是用了CAN的回环测试,这样我们就不需要挂接外部的CAN节点。有关双CAN通信的实验,大家可参考野火STM32光盘自带的例程《16-野火M3-CAN(Mutual)》当我们用CAN的回环测试时,硬件会在内部将TX和RX连接起来,实现内部的收和发,从而达到测试的目的。

8.3 代码分析

首先在工程中添加需要用到的头文件:

FWlib/stm32f10x_gpio.c

FWlib/stm32f10x_rcc.c

FWlib/stm32f10x_usart.c

FWlib/stm32f10x_can.c

FWlib/misc.c

还要将c文件对应的头文件添加进来,在库头文件stm32f10x_conf.h中实现:

1./* Includes ------------------------------------------------------------------*/

2./* Uncomment the line below to enable peripheral header file inclusion */

3./* #include "stm32f10x_adc.h" */

4./* #include "stm32f10x_bkp.h" */

5.#include "stm32f10x_can.h"

6./* #include "stm32f10x_crc.h" */

7./* #include "stm32f10x_dac.h" */

8./* #include "stm32f10x_dbgmcu.h" */

9./* #include "stm32f10x_dma.h" */

10./* #include "stm32f10x_exti.h" */

11./*#include "stm32f10x_flash.h"*/

12./* #include "stm32f10x_fsmc.h" */

13.#include "stm32f10x_gpio.h"

14./* #include "stm32f10x_i2c.h" */

15./* #include "stm32f10x_iwdg.h" */

16./* #include "stm32f10x_pwr.h" */

17.#include "stm32f10x_rcc.h"

18./* #include "stm32f10x_rtc.h" */

19./* #include "stm32f10x_sdio.h" */

20./* #include "stm32f10x_spi.h" */

21./* #include "stm32f10x_tim.h" */

22.#include "stm32f10x_usart.h"

23./* #include "stm32f10x_wwdg.h" */

24.#include "misc.h"/* High level functions for NVIC and SysTick (add-

on to CMSIS functions) */

OK,库环境已经配置好,接下来我们就开始分析main函数吧:

1./**

2. * @brief Main program.

3. * @param None

4. * @retval : None

5. */

6.int main(void)

7.{

8./* config the sysclock to 72M */

9. SystemInit();

10.

11./* USART1 config */

12. USART1_Config();

13./* LED config */

14. LED_GPIO_Config();

15. printf( "\r\n 这个一个CAN(回环模式和中断模式)测试程序...... \r\n" );

16. USER_CAN_Init();

17. printf( "\r\n CAN 回环测试初始化成功...... \r\n" );

18. USER_CAN_Test();

19. printf( "\r\n CAN 回环测试成功...... \r\n" );

20.while (1)

21. {

22. }

23.}

首先我们调用库SystemInit();函数将我们的系统时钟设置为72MHZ,紧接着初始化串口USART1_Config();和LED LED_GPIO_Config();,因为在本实验中我们需要用到串口来打印一些调试信息,用LED来显示程序的运行状态。有关这三个函数的详细讲解,请参考前面章节的教程,这里不再详述,其中USART1_Config();和

LED_GPIO_Config();是由用户实现的应用函数,并非库函数。

USER_CAN_Init();实现了CAN I/O 端口的初始化和中断优先级的初始化(因为等下要用到CAN 的中断模式)。在can.c中实现:

1./*

2. * 函数名:CAN_Init

3. * 描述:CAN初始化,包括端口初始化和中断优先级初始化

4. * 输入:无

5. * 输出 : 无

6. * 调用:外部调用

7. */

8.void USER_CAN_Init(void)

9.{

10. CAN_NVIC_Configuration();

11. CAN_GPIO_Config();

12.}

USER_CAN_Init();调用了两个内部函数CAN_NVIC_Configuration();和CAN_GPIO_Config();,见名知义就可知道这两个函数的功能是什么啦,他们也均在can.c中实现:

1./*

2. * 函数名:CAN_NVIC_Configuration

3. * 描述:CAN RX0 中断优先级配置

4. * 输入:无

5. * 输出 : 无

6. * 调用:内部调用

7. */

8.static void CAN_NVIC_Configuration(void)

9.{

10. NVIC_InitTypeDef NVIC_InitStructure;

11.

12./* Enable CAN1 RX0 interrupt IRQ channel */

13. NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

14. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 主优先级为0

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

16. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

17. NVIC_Init(&NVIC_InitStructure);

18.}

在CAN_GPIO_Config(void)这个函数中我们要注意一点:CAN的RX脚要设置为上拉输入,TX脚要设置为复用推挽输出,其他就跟配置普通I/O口一样。

1./*

2. * 函数名:CAN_GPIO_Config

3. * 描述:CAN GPIO 和时钟配置

4. * 输入:无

5. * 输出 : 无

6. * 调用:内部调用

7. */

8.static void CAN_GPIO_Config(void)

9.{

10. GPIO_InitTypeDef GPIO_InitStructure;

11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);

12./* CAN1 Periph clock enable */

13. RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

14.

15./* Configure CAN pin: RX */// PB8

16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入

18. GPIO_Init(GPIOB, &GPIO_InitStructure);

19.

20./* Configure CAN pin: TX */// PB9

21. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

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

23. GPIO_Init(GPIOB, &GPIO_InitStructure);

24.

25.//#define GPIO_Remap_CAN GPIO_Remap1_CAN1 本实验没有用到重映射I/O

26. GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);

27.}

当我们将CAN初始化好之后,接下来就是重头戏了。我们调用

USER_CAN_Test();函数。这个函数里面包含了CAN的回环和中断两种测试,在can.c 中实现:

1./*

2. * 函数名:CAN_Test

3. * 描述:CAN 回环模式跟中断模式测试

4. * 输入:无

5. * 输出 : 无

6. * 调用:外部调用

7. */

8.void USER_CAN_Test(void)

9.{

10./* CAN transmit at 100Kb/s and receive by polling in loopback mode */

11.TestRx = CAN_Polling();

12.if (TestRx == FAILED)

13. {

14. LED1( OFF ); // LED1 OFF

15. }

16.else

17. {

18. LED1( ON ); // LED1 ON;

19. }

20./* CAN transmit at 500Kb/s and receive by interrupt in loopback mode */

21. TestRx = CAN_Interrupt();

22.if (TestRx == FAILED)

23. {

24. LED2( OFF ); // LED2 OFF;

25. }

26.else

27. {

28. LED2( ON ); // LED2 ON;

29. }

30.}

在这个函数中通过板载的LED的状态来显示回环和中断模式测试是否成功。其中回环模式测试调用了CAN_Polling();这个函数,通信速率为100Kb/s。中断模式测试调用了CAN_Interrupt();这个函数,通信速率为500Kb/s。

下面我们来重点分析下CAN_Polling();和CAN_Interrupt();这两个函数,这两个函数也在can.c中实现:

1./*

2. * 函数名:CAN_Polling

3. * 描述:配置 CAN 的工作模式为回环模式

4. * 输入:无

5. * 输出 : -PASSED 成功

6. * -FAILED 失败

7. * 调用:内部调用

8. */

9.TestStatus CAN_Polling(void)

10.{

11. CAN_InitTypeDef CAN_InitStructure;

12. CAN_FilterInitTypeDef CAN_FilterInitStructure;

13. CanTxMsg TxMessage;

14. CanRxMsg RxMessage;

15. uint32_t i = 0;

16. uint8_t TransmitMailbox = 0;

17.

18./* CAN register init */

19. CAN_DeInit(CAN1);

20. CAN_StructInit(&CAN_InitStructure);

21.

22./* CAN cell init */

23. CAN_InitStructure.CAN_TTCM=DISABLE;

24. CAN_InitStructure.CAN_ABOM=DISABLE;

25. CAN_InitStructure.CAN_AWUM=DISABLE;

26. CAN_InitStructure.CAN_NART=DISABLE;

27. CAN_InitStructure.CAN_RFLM=DISABLE;

28. CAN_InitStructure.CAN_TXFP=DISABLE;

29. CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack; // 回环模式

30. CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;

31. CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;

32. CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;

33. CAN_InitStructure.CAN_Prescaler=5; // 分频系数为5

34. CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN

35.

36./* CAN filter init */

37. CAN_FilterInitStructure.CAN_FilterNumber=0;

38. CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;

39. CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;

40. CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;

41. CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;

42. CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;

43. CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;

44. CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;

45. CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

46. CAN_FilterInit(&CAN_FilterInitStructure);

47.

48./* transmit */

49. TxMessage.StdId=0x11; // 设定标准标识符(11位,扩展的为29位)

50. TxMessage.RTR=CAN_RTR_DATA; // 传输消息的帧类型为数据帧(还有远程帧)

51. TxMessage.IDE=CAN_ID_STD; // 消息标志符实验标准标识符

52. TxMessage.DLC=2; // 发送两帧,一帧8位

53. TxMessage.Data[0]=0xCA; // 第一帧数据

54. TxMessage.Data[1]=0xFE; // 第二帧数据

55.

56. TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);

57. i = 0;

58.// 用于检查消息传输是否正常

59.while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFF))

60. {

61. i++;

62. }

63.

64. i = 0;

65.// 检查返回的挂号的信息数目

66.while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFF))

67. {

68. i++;

69. }

70./* receive */

71. RxMessage.StdId=0x00;

72. RxMessage.IDE=CAN_ID_STD;

73. RxMessage.DLC=0;

74. RxMessage.Data[0]=0x00;

75. RxMessage.Data[1]=0x00;

76. CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

77.

78.if (RxMessage.StdId!=0x11)

79. {

80.return FAILED;

81. }

82.if (RxMessage.IDE!=CAN_ID_STD)

83. {

84.return FAILED;

85. }

86.if (RxMessage.DLC!=2)

87. {

88.return FAILED;

89. }

90.if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)

91. {

92.return FAILED;

93. }

94.//printf("receive data:0X%X,0X%X",RxMessage.Data[0], RxMessage.Data[1]);

95.return PASSED; /* Test Passed */

96.}

在分析这两个函数之前,我们先来看下下面这幅图,截图来自《STM32参考手册中文》。

上图中左边的Control / Sdatus / Configuration的具体细节我们先不管它,先放着。这个图中有三个专业名词,我们先解释下:

1-> Tx Mailboxes(发送邮箱)

STM32的CAN中共有3个发送邮箱供软件来发送报文。发送调度器根据优先级决定哪个邮箱的报文先被发送。

2->Accepttance Filters( 接收过滤器 )

STM32的CAN中共有14个位宽可变/可配置的标识符过滤器组,软件通过对它们编程,从而在引脚收到的报文中选择它需要的报文,而把其它报文丢弃掉。

3-> Receive FIFO( 接收FIFO )

STM32的CAN中共有2个接收FIFO,每个FIFO都可以存放3个完整的报文。它们完全由硬件来管理。在CAN回环测试实验中我们把要发送的数据放在Tx Mailboxes中,数据集经过Accepttance Filters发送到

Receive FIFO,再将接收到的数据存到相应的缓冲区中,通过比较接收和发送的数据是否相同来验证我们的实验是否正确。实验过程看起来很简单:发送 -> 过滤 -> 接收 -> 比较。但只是宏观上把握罢了,这期间还需要做许多的工作。现在我们再回到CAN_Polling(void)这个函数中,看看这一过程我们到底做了些什么:

1-> CAN 寄存器初始化,全部初始化为默认值。

2->CAN cell 初始化。具体可参考源码,代码里面有详细注释。

3->CAN 过滤器初始化。

4->发送数据。这其中包括了设置设定标准标识符、传输消息的帧类型、要发送多少帧、邮箱中的帧数据是什么等。具体可参考源码,代码里面

有详细注释。

5->接收数据。要初始化接收邮箱,用于接收数据,比较报文中设定的标准标识符是否相等等、最后比较发送的数据和接收的数据是否相等。具

体可参考源码,代码里面有详细注释。

6->最后返回TestStatus信息,PASSED 表示成功,FAILED 表示失败。

在阅读这部分代码时,需要参考《STM32参考手册中文》第21章<控制器局域网bxcan>,这样对理解代码有很大的帮助。刚开始的时候我们也没太大必要完全去搞懂每一句代码是什么意思,先在宏观上把握他,看下这段代码是否真的工作了,一步一步去修改它,测试它,看看实验会发生什么效果。这样学习的时间长了,理解就自然深刻了,以前那些你觉得很纳闷的问题,那些瓶颈问题都会瞬间解决,一下子豁然开朗。其实这也是我的一种学习方法。量变了,质变还会远吗?

CAN的中断模式跟回环模式是类似的,具体的大家自行阅读代码吧。唯一一个不同的是我们需要在stm32f10x_it.c中添加CAN的中断服务程序:

1./*

2. * 函数名:USB_LP_CAN1_RX0_IRQHandler

3. * 描述:USB中断和CAN接收中断服务程序,USB跟CAN公用I/O,这里只用到CAN的中断。

4. * 输入:无

5. * 输出 : 无

6. * 调用:无

7. */

8.void USB_LP_CAN1_RX0_IRQHandler(void)

9.{

10. CanRxMsg RxMessage;

11.

12. RxMessage.StdId=0x00;

13. RxMessage.ExtId=0x00;

14. RxMessage.IDE=0;

15. RxMessage.DLC=0;

16. RxMessage.FMI=0;

17. RxMessage.Data[0]=0x00;

18. RxMessage.Data[1]=0x00;

19.

20. CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

21.

22.if((RxMessage.ExtId==0x1234) && (RxMessage.IDE==CAN_ID_EXT)

23. && (RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xDECA))

24. {

25. ret = 1;

26. }

27.else

28. {

29. ret = 0;

30. }

31.}

8.4 实验现象

将野火STM32开发板供电(DC5V),插上JLINK,插上串口线(两头都是母的交叉线),打开超级终端,配置超级终端为115200 8-N-1,将编译好的程序下载到开发板,可看到LED1和LED2全亮,超级终端打印出如下信息:

STM32的can总线实验心得要点

STM32的can总线实验心得 (一) 工业现场总线 CAN 的基本介绍以及 STM32 的 CAN 模块简介 首先通读手册中关于CAN的文档,必须精读。 STM32F10xxx 参考手册Rev7V3.pdf https://www.sodocs.net/doc/cf8446324.html,/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 个数据字节发送时间戳 管理 · 中断可屏蔽

推荐-stm32中定时器产生不同PWM的基本思路 精品

在stm32中利用定时器TIM调制PWM的几种方法: 说说我的学习经历:从开始接触到现在有好几个月了,但是学习还是比较的费劲,而且速度也比较的缓慢,当然相比之前还是有很大的进步,记得刚刚学习的时候,建工程都是大四学长手把手教的。废话不多说先来讲讲定时器的配置: STM32F10系列最少3个、做多有8个定时器,都是16位定时器,且相互之间是独立的,计数范围为0x0000-0xffff,最大计数值为65535.可以用于测量输入信号的脉冲长度或者产生输出波形(输出比较和PWM)分为通用定时器,高级定时器,以及看门狗定时器 下面主要讲通用定时器的配置问题: 以定时器TIM1为例:先进行函数的配置 void timer1_config() { TIM_TimeBaseInitTypDef TIM_TimeBaseStructure; //开定时器1外设时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM1,ENABLE); //计时50000次时间为50000/10M=500ms TIM_TimeBaseStructure.TIM_Period=50000 ; TIM_TimeBaseStructure.TIM_Prescaler = 720-1;//720分频 TIM_TimeBaseStructure.TIM_ClockDivision =0;//时钟分割为0; //计数模式向上计数 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure)//初始化TIM1 TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);//开启定时器中断 TIM_Cmd(TIM1,ENABLE); //使能定时器 } 关于时间的计算问题: 外设系统时钟的频率为72M,进行720分频以后,频率f=72M/720=100khz. 如果要定时0.1s 则计数值为10000,计算公式为:时间(t)=计数值(n)/频率(f).注意计数值n介于0到65535之间 有定时器则一定会有中断发生,所以要配置中断优先级,对于中断优先 级函数配置如下: V oid nvic_config() { NVIC_InitTypDef NVIC_InitStructure; //抢占优先级为1位,从优先级为3位 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ; NVIC_InitStructure.NVIC_IRQChannel=TIM1_IRQn; //定义定时器1为请求通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占式优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority=2; //从优先级为2 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断优先级 NVIC_Init(&NVIC_InitStructure); //初始化中断 } 对于优先级中的抢占式和从优先级做如下解释: 抢占式优先级:是可以抢占的中断,比如正在执行的优先级为10的中断,突然来了一个优

正确认识纯化水系统的“死角

正确认识系统的“死角” 死角检查是系统进行安装确认(IQ)时的一项重要内容。在制药流体工艺系统(如制药用水系统、制药工艺配液系统、CIP/SIP系统)中,任何死角的存在均可能导致整个系统的污染。 死角过大所带来的风险主要如下: ?为微生物繁殖提供了“温床”并导致“生物膜”的形成,引起微生物指标、TOC指标或内毒素指标超标,导致水质指标不符合药典要求; ?系统消毒或灭菌不彻底导致的二次微生物污染; ?系统清洗不彻底导致的二次颗粒物污染或产品交叉污染。 因此,中国2010版GMP要求“管道的设计和安装应避免死角、盲管”。 《美国机械工程师协会生物加工设备标准》2014版对于死角有准确的定义,《ASMEBPE》(2014)规定:“死角”是指当管路或容器使用时,能导致产品污染

的区域(deadleg: an area of entrapment in a vessel or piping run that could lead tocontamination of the product.)。 1976年,美国FDA在CFR212法规上第一次采用量化方法进行死角的质量管理,工程上俗称“6D”规则,其含义为“当L/d<6时,证明此处无死角”,其中L指“流动侧主管网中心到支路盲板(或用点阀门中心)的距离”,d为支路的直径。随后的研究表明,“3D”规则更符合洁净流体工艺系统的微生物控制要求,其中L的含义变更为“流动侧主管网管壁到支路盲板(或用点阀门中心)的距离”(图1)。 图1 死角的发展 更加准确的死角量化定义来自于《ASMEBPE》规范(图2),该定义明确规定:L是指“流动侧主管网内壁到支路盲板(或用点阀门中心)的距离”,D是指“非流动侧支路管道的内径”。

05_STM32F4通用定时器详细讲解精编版

STM32F4系列共有14个定时器,功能很强大。14个定时器分别为: 2个高级定时器:Timer1和Timer8 10个通用定时器:Timer2~timer5 和 timer9~timer14 2个基本定时器: timer6和timer7 本篇欲以通用定时器timer3为例,详细介绍定时器的各个方面,并对其PWM 功能做彻底的探讨。 Timer3是一个16位的定时器,有四个独立通道,分别对应着PA6 PA7 PB0 PB1 主要功能是:1输入捕获——测量脉冲长度。 2 输出波形——PWM 输出和单脉冲输出。 Timer3有4个时钟源: 1:内部时钟(CK_INT ),来自RCC 的TIMxCLK 2:外部时钟模式1:外部输入TI1FP1与TI2FP2 3:外部时钟模式2:外部触发输入TIMx_ETR ,仅适用于TIM2、TIM3、TIM4,TIM3,对应 着PD2引脚 4:内部触发输入:一个定时器触发另一个定时器。 时钟源可以通过TIMx_SMCR 相关位进行设置。这里我们使用内部时钟。 定时器挂在高速外设时钟APB1或低速外设时钟APB2上,时钟不超过内部高速时钟HCLK ,故当APBx_Prescaler 不为1时,定时器时钟为其2倍,当为1时,为了不超过HCLK ,定时器时钟等于HCLK 。 例如:我们一般配置系统时钟SYSCLK 为168MHz ,内部高速时钟 AHB=168Mhz ,APB1欲分频为4,(因为APB1最高时钟为42Mhz ),那么挂在APB1总线上的timer3时钟为84Mhz 。 《STM32F4xx 中文参考手册》的424~443页列出与通用定时器相关的寄存器一共20个, 以下列出与Timer3相关的寄存器及重要寄存器的简单介绍。 1 TIM3 控制寄存器 1 (TIM3_CR1) SYSCLK(最高 AHB_Prescaler APBx_Prescaler

STM32高级定时器日记之PWM

STM32高级定时器PWM实用程序 文章来源:本站原创作者:佚名 该文章讲述了STM32高级定时器PWM实用程序. 高级定时器与通用定时器比较类似,下面是一个TIM1 的PWM 程序,TIM1是STM32唯一的高级定时器。共有4个通道有死区有互补。 先是配置IO脚: GPIO_InitTypeDef GPIO_InitStructure; /* PA8设置为功能脚(PWM) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /*PB13 设置为PWM的反极性输出*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure); /*开时钟PWM的与GPIO的*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /*配置TIM1*/ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; void Tim1_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_DeInit(TIM1); //重设为缺省值 /*TIM1时钟配置*/ TIM_TimeBaseStructure.TIM_Prescaler = 4000; //预分频(时钟分 频)72M/4000=18K TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数TIM_TimeBaseStructure.TIM_Period = 144; //装载值18k/144=125hz 就是说向上加的144便满了 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置了时钟分割不

管道死角盲管规则

6D、3D、2D、管道死角/盲管规则,以及零死角阀门介绍 6D、3D、2D、管道死角/盲管规则以及零死角阀门介绍 关于管道死角/盲管的定义和要求,不同法规和指南有不同的要求,这些要求如下: 1、1976 CFR 212规范为6D,指主管道中心到支管阀门中心的距离应小于支管直径的6倍。 2、1993 美国高纯水检查指南为6D,指主管道中心到支管阀门密封点的长度应小于支管直径的6倍。 3、2001 ISPE水和蒸汽基准指南为3D,指主管外壁到支管阀门密封点的长度应小于支管直径的3倍。 4、2009 ASME BPE为2D,指主管内壁到阀门密封点的长度应小于支管直径的2倍。 5、WHO 建议为,应避免大于分支管径倍的盲管。 6、2010版中国GMP指南: 为了避免将来造成混乱,本指南建议死角长度从管的外壁来考虑。我们建议避免对于最大可允许的死角做硬性规定。 最后,在不考虑死角长度的情况下,水质必须满足要求。工程设计规范要求死角长度最小,有很多好的仪表和阀门的设计是尽量减少死角的。 我们应该认识到如果不经常冲洗或消毒,任何系统都能会存在死角。各种规定和提法甚至测量的方法不尽相同,但是目前的所有提法都不是“法规”而是工程的建议和标准。TheTruth about the 3D/6D Rule 3D/6D规则的真相 The installation of pipework leads to recurrent discussions about how deadlegs can be prevented and about the maximum length outgoing pipes/pipe tees mayhave for the sensor. There is less throughflow in dead legs. Hence, it isharder to clean them and during thermal sanitisation it takes longer until these"branches" have also reached the required temperature. In calls fortender and tests the 3D/6D rule is often used for the specification, but notalways in the completely correct way. In order to further explain this, pleaseread following the history of this rule. 管道的安装一再引起关于如何防止死管的讨论,以及探头安装位置连出的支管最大长度问题的讨论。在死管中水流较少,因此很难对其进行清洁,并且在高温消毒中会需要很长时间使得这些“支管”也能达到所需的温度。在设计和测试中,3D/6D规则通常用作标准,但并不总是用的完全正确。为了进一步解释这个问题,请阅读以下关于此规则的历史。The rule for the prevention of dead legs (in a WFI system) is mentionedfor the first time in the draft of the FDA Guides for Large VolumeParenterals (LVP), 21 CFR in 1972.

stm32高级定时器使用教程

STM32 高级定时器-PWM简单使用 2010-04-14 14:49:29| 分类:STM32 | 标签:|举报|字号大中小订阅高级定时器与通用定时器比较类似,下面是一个TIM1 的PWM 程序,TIM1是STM32唯一的高级定时器。共有4个通道有死区有互补。 先是配置IO脚: GPIO_InitTypeDef GPIO_InitStructure; /* PA8设置为功能脚(PWM) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /*PB13 设置为PWM的反极性输出*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /*开时钟PWM的与GPIO的*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /*配置TIM1*/ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure;

管道死角盲管规则

6D、3D、2D、1.5D管道死角/盲管规则,以及零死角阀门介绍 6D、3D、2D、1.5D管道死角/盲管规则以及零死角阀门介绍 关于管道死角/盲管的定义和要求,不同法规和指南有不同的要求,这些要求如下: 1、1976 CFR 212规范为6D,指主管道中心到支管阀门中心的距离应小于支管直径的6倍。 2、1993 美国高纯水检查指南为6D,指主管道中心到支管阀门密封点的长度应小于支管直径的6倍。 3、2001 ISPE水和蒸汽基准指南为3D,指主管外壁到支管阀门密封点的长度应小于支管直径的3倍。 4、2009 ASME BPE为2D,指主管内壁到阀门密封点的长度应小于支管直径的2倍。 5、WHO 建议为1.5D,应避免大于分支管径1.5倍的盲管。 6、2010版中国GMP指南: 为了避免将来造成混乱,本指南建议死角长度从管的外壁来考虑。我们建议避免对于最大可允许的死角做硬性规定。 最后,在不考虑死角长度的情况下,水质必须满足要求。工程设计规范要求死角长度最小,有很多好的仪表和阀门的设计是尽量减少死角的。

我们应该认识到如果不经常冲洗或消毒,任何系统都能会存在死角。各种规定和提法甚至测量的方法不尽相同,但是目前的所有提法都不是“法规”而是工程的建议和标准。 TheTruth about the 3D/6D Rule 3D/6D规则的真相 The installation of pipework leads to recurrent discussions about how deadlegs can be prevented and about the maximum length outgoing pipes/pipe tees mayhave for the sensor. There is less throughflow in dead legs. Hence, it isharder to clean them and during thermal sanitisation it takes longer until these"branches" have also reached the required temperature. In

STM32通用定时器_15-1-6

通用定时器的相关配置 1、预装入(Preload) 预装入实际上是设置TIMx_ARR寄存器有没有缓冲,根据“The auto-reload register is preloaded。Writing to or reading from the auto-reload register accesses the preload register。”可知: 1)如果预装入允许,则对自动重装寄存器的读写是对预装入寄存器的存取,自动重装寄存器的值在更新事件后更新; 2)如果预装入不允许,则对自动重装寄存器的读写是直接修改其本身,自动重装寄存器的值立刻更新; 3)设置方式:TIMx_CR1 →ARPE(1) 2、更新事件(UEV) 1)产生条件:①定时器溢出 ②TIMx_CR1→ UDIS = 0 ③或者:软件产生,TIMx_EGR→ UG = 1 2)更新事件产生后,所有寄存器都被“清零”,注意预分频器计数 器也被清零(但是预分频系数不变)。若在中心对称模式下或DIR=0(向上计数)则计数器被清零;若DIR=1(向下计数)则计数器取TIMx_ARR的值。 3)注意URS(复位为0)位的选择,如下:

如果是软件产生更新,则URS→1,这样就不会产生更新请求 和DMA请求。 4)更新标志位(UIF)根据URS的选择置位。 5)可以通过软件来失能更新事件: 3、计数器(Counter) 计数器由预分频器的输出时钟(CK_CNT)驱动,TIMx_CR1→CEN = 1 使能,注意:真正的计数使能信号(CNT_EN)在 CEN 置位后一个周期开始有效。 4、预分频器(Prescaler) 预分频器用来对时钟进行分频,分频值由TIMx_PSC决定,计数器的时钟频率CK_CNT= fCK_PSC / (PSC[15:0] + 1)。 根据“It can be changed on the fly as this control register

STM32的PWM精讲

STM32的PWM精讲 通过对TM1定时器进行控制,使之各通道输出插入死区的互补PWM输出,各通道输出频率均为17.57KHz。其中,通道1输出的占空比为50%,通道2输出的占空比为25%,通道3输出的占空比为12.5%。各通道互补输出为反相输出。 TM1定时器的通道1到4的输出分别对应PA.08、PA.09、PA.10和PA.11 引脚,而通道1到3的互补输出分别对应PB.13、PB.14和PB.15引脚,中止输入引脚为PB.12。将这些引脚分别接入示波器,在示波器上观查相应通道占空比的方波[12]。 配置好各通道后,编译运行工程;点击MDK的Debug菜单,点击Start/Stop Debug Session;通过示波器察看 PA.08、PA.09、PA.10、PB.13、PB.14、PB.15 的输出波形,其中PA.08和PB.13为第一通道和互补通道,PB.09和PB.14为第二通道和其互补通道,PB.10和PB.15为第三通道和其互补通道;第一通道显示占空比为50%,第二通道占空比为25%,第三通道占空比为12.5%。 第2章STM32处理器概述 STM32F103xx增强型系列产品中内置了多达3个同步的标准定时器。每个定时器都有一个16位的自动加载递加/递减计数器、一个16位的预分频器和4个独立的通道,每个通道都可用于输入捕获、输出比较、PWM和单脉冲模式输出,在最大的封装配置中可提供最多12个输入捕获、输出比较或PWM通道。它们还能通过定时器链接功能与高级控制定时器共同工作,提供同步或事件链接功能。 在调试模式下,计数器可以被冻结。任一个标准定时器都能用于产生PWM 输出。每个定时器都有独立的DMA请求机制。 2.4.2 高级控制定时器[22] 高级控制定时器(TM1)由一个16位的自动装载计数器组成,它由一个可编程预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较,PWM,嵌入死区时间的互补PWM等)。 使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒至几个毫秒的调节。高级控制(TIM1)和通用(TMx)定时器是完全

stm32定时器的区别

STM32高级定时器、通用定时器(TIMx) 、基本定时器(TIM6和TIM7) 区别? 高级定时器TIM1和TIM8、通用定时器(TIM2,TIM3,TIM4,TIM5) 、基本定时器(TIM6和TIM7) 区别? TIM1和TIM8主要特性TIM1和TIM8定时器的功能包括: ● 16位向上、向下、向上/下自动装载计数器 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 ● 多达4个独立通道:─ 输入捕获─ 输出比较─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 ● 死区时间可编程的互补输出 ● 使用外部信号控制定时器和定时器互联的同步电路 ● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器 ● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态 ● 如下事件发生时产生中断/DMA:─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获─ 输出比较─ 刹车信号输入 ● 支持针对定位的增量(正交)编码器和霍尔传感器电路 ● 触发输入作为外部时钟或者按周期的电流管理 TIMx主要功能通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括: ● 16位向上、向下、向上/向下自动装载计数器 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值 ● 4个独立通道:─ 输入捕获─ 输出比较─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 ● 使用外部信号控制定时器和定时器互连的同步电路 ● 如下事件发生时产生中断/DMA:─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获─ 输出比较 ● 支持针对定位的增量(正交)编码器和霍尔传感器电路 ● 触发输入作为外部时钟或者按周期的电流管理 TIM6和TIM7的主要特性TIM6和TIM7定时器的主要功能包括: ● 16位自动重装载累加计数器 ● 16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1~65536之间的任意数值分频 ● 触发DAC的同步电路注:此项是TIM6/7独有功能. ● 在更新事件(计数器溢出)时产生中断/DMA请求 强大,高级定时器应该是用于电机控制方面的吧

STM32的CAN总线中继器设计及应用_潘铜

*基金项目:西安工程大学研究生创新基金资助(chx100813)。 STM32的CAN 总线中继器设计及应用 * 潘铜,叶小荣,张娜,范建峰 (西安工程大学电子信息学院,西安710048) 摘要:CA N 中继器是系统组网的关键,通过中继器可以扩展节点的数量和实现不同波特率之间的通信。本文充分利用ST M 32F105内部集成双bxCAN 控制器的特性,设计出一款基于ST M 32的单芯片CAN 总线中继器,并将其应用到齐玛印花机上。实践证明该方法有效可行,不仅实现了齐玛印花机的改造,还降低了系统设备的成本。关键词:CA N 总线;中继器;ST M 32F105;齐玛印花机中图分类号:T P336 文献标识码:A Design an d Application of CAN Bus Repeater Based on STM32 Pan Tong ,Ye Xiaorong ,Zhang Na ,Fan Jianfeng (Elect ronic Information College ,Xi 'an Polytechnic University ,Xi an 710048,China ) Abstract :CAN repeater is the key to netw orking .The repeater can expand the num ber of nodes and realize communication betw een dif -ferent baud rates .M aking full use of internal integrated dual CAN controllers of S TM 32f105,the paper designs a single -chip CAN bus repeater based on STM32.The repeater can be applied to the Zimmer printing machine .The result proves that the method is effective and feasible ,not only realizing the transformation of Zimmer printing machine but also reducing the cost of system equipment .Key words :CAN bus ;repeater ;STM32F105;Zimmer printing machine 引 言 CAN 总线是一种多主方式的串行通信总线,具有优良的稳定性、实时性、远程通信能力以及超强的硬件CRC 纠错等特性;CAN 总线技术的应用不再仅限于汽车行业,而是扩展到了机械、纺织、控制等行业,并被公认为是最有前途的现场总线之一。然而由于受制于CAN 收发器,CAN 总线通信距离和网络中节点数被分别限制在10km 和110个之内。但是在稍大型的CAN 总线系统中,这往往是不够的,这时就需要用CAN 总线中继器对CAN 总线网络进行扩展。 CAN 中继器是系统组网的关键技术设备之一,使用中继器可以提高网络设计的灵活性,并且通过中继器还可以连接两个不同波特率的CAN 总线网络;在两个网络间进行数据转发,极大地扩展其使用范围。基于此,本文设计出一款基于ST M 32的CA N 总线中继器,并将其应用到齐玛印花机上,完成圆网印花机通信系统的工程改造。 1 系统整体方案及硬件实现 以往的CAN 中继器设计大多采用M CU 加CAN 控制器的双芯片或多芯片解决方案。例如,参考文献[1]使用1片M CU 加2路CAN 控制器的结构实现中继器;参考文献[2]使用双M CU 结构设计CA N 总线中继器;参考文献[3]使用独立双CAN 控制器作为2路CAN 接口的控制器来设计CA N 中继器。上述方案电路复杂,MCU 与CA N 控制器通过外部总线连接,数据吞吐速度慢,整体可靠性也比较差。 意法半导体的STM 32是以A RM Cortex -M 3为内核的32位微处理器,主频可高达72M H z ,内置Flash 和SRAM ,其容量可分别高达512KB 和64K B ;内部集成双bxCA N 控制器。它支持CAN 协议V2.0A 和V2.0B ,波特率最高可达1M b /s ,具有3个发送邮箱和2个3级深度的FIFO ,能够以最小的CPU 负荷来高效处理大量收到的报文。基于此,选用STM 32F105作为主控制器,设计出一款基于STM 32的CAN 总线中继器。其整体方案如图1所示。 由于STM 32F105内部集成了双路CA N 控制器,CA N 中继器的节点电路变得十分简单,其硬件电路如图

STM32学习笔记通用定时器PWM输出

STM32学习笔记(5):通用定时器PWM输出 2011年3月30日TIMER输出PWM 1.TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。 STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。 1.1PWM输出模式 STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下: 110:PWM模式1-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 111:PWM模式2-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。 由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。 而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。 1.2PWM输出管脚 PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如

STM32 高级定时器-PWM简单使用

STM32 高级定时器-PWM简 单使用 高级定时器与通用定时器比较类似,下面是一个TIM1 的PWM 程序,TIM1是STM32唯一的高级定时器。共有4个通道有死区有互补。 先是配置IO脚: GPIO_InitTypeDef GPIO_InitStructure; /* PA8设置为功能脚(PWM) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /*PB13 设置为PWM的反极性输出*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /*开时钟PWM的与GPIO的*/ RCC_APB2PeriphClockCmd(RCC_A PB2Periph_TIM1,ENABLE); RCC_APB2PeriphClockCmd(RCC_A PB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_A PB2Periph_GPIOB, ENABLE); /*配置TIM1*/ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; void Tim1_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_DeInit(TIM1); //重设为缺省值 /*TIM1时钟配置*/ TIM_TimeBaseStructure.TIM_Prescaler = 4000; //预分频(时钟分频)72M/4000=18K TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数 TIM_TimeBaseStructure.TIM_Period = 144; //装载值18k/144=125hz 就是说向上加的144便满了 TIM_TimeBaseStructure.TIM_ClockDivision =

STM32-PWM输出总结讲课讲稿

学习后发现stm32的定时器功能确实很强大,小总结一下方便以后使用的时候做参考。Stm32定时器一共分为三种:tim1和tim8是高级定时器,6和7是基本定时器,2—5是通用定时器。从名字就可以看得出来主要功能上的差异。今天我主要是用定时器做pwm输出,所以总结也主要是针对pwm方面的。 先大致说下通用和高级定时器的区别。通用的可以输出四路pwm信号互不影响。高级定时器可以输出三对互补pwm信号外加ch4通道,也就是一共七路。 所以这样算下来stm32一共可以生成4*5+7*2=30路pwm信号。接下来还有功能上的区别:通用定时器的pwm信号比较简单,就是普通的调节占空比调节频率(别的不常用到的没去深究);高级定时器的还带有互补输出功能,同时互补信号可以插入死区,也可以使能刹车功能,从这些看来高级定时器的pwm天生就是用来控制电机的。 Pwm输出最基本的调节就是频率和占空比。频率当然又和时钟信号扯上了关系。高级定时器是挂接到APB2上,而通用定时器是挂接到APB1上的。APB1和APB2的区别就要在于时钟频率不同。APB2最高频率允许72MH,而APB1最高频率为36MHZ。这样是不是通用定时器只最高36MHZ频率呢,不是的;通用定时器时钟信号完整的路线应该是下面这样的:AHB(72mhz)→APB1分频器(默认2)→APB1时钟信号(36mhz)→倍频器(*2倍)→通用定时器时钟信号(72mhz)。 在APB1和定时器中间的倍频器起到了巨大的作用,假如红色字体的“APB1分频器”假如不为1(默认是2),倍频器会自动将APB1时钟频率扩大2倍后作为定时器信号源,这个它内部自动控制的不用配置。设置这个倍频器的目的很简单就是在APB1是36mhz的情况下通用定时器的频率同样能达到72mhz。我用的库函数直接调用函数SystemInit(); 这个函数之后时钟配置好了:通用定时器和高级定时器的时钟现在都是72mhz(你也可以自己再配置一下RCC让他的频率更低,但是不能再高了)。定时器接下来还有一个分频寄存器:TIMX_PSC 经过他的分频后,才是定时器计数的频率。所以真正的时钟频率应该是72mhz/(TIMX_PSC-1),我们设为tim_frepuency下面还会用到。 stm32的时钟频率弄得确实是很饶人的,所以关键就是先要把思路理清楚。时钟的频率弄好了下面终于可以开说重点PWM了。当然还少不了频率:pwm主要就是控制频率和占空比的:这两个因素分别通过两个寄存器控制:TIMX_ARR和TIMX_CCRX。ARR寄存器就是自动重装寄存器,也就是计数器记到这个数以后清零再开始计,这样pwm的频率就是tim_frequency/(TIMX_ARR-1)。在计数时会不停的和CCRX寄存器中的数据进行比较,如果小于的话是高电平或者低电平,计数值大于CCRX值的话电平极性反相。所以这也就控制了占空比。 下面是定时器1的配置代码: GPIO_InitTypeDef GPIO_InitStructure2; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //第一步:配置时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB|RCC_APB2Periph_TIM1 ,ENABLE); //第二步,配置goio口 /********TIM1_CH1 引脚配置*********/

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

与本程序代码相关部分的原理图及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;//2 nominal 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;

相关主题