EDN首页   博客首页

1

关于投票
STM32质量报告和可靠性报告
在ST网站可以下载这些报告:http://www.st.com/mcu/familiesdocs-110.html#Quality%20-%20Product%20Documentation

在STM32数据手册中有有关电磁兼容性和ESD的参数。
系统分类: 单片机
用户分类: 资料文档
标签: STM32 质量 可靠性 电磁兼容性
来源: 原创
发表评论 阅读全文(355) | 回复(0)

2

关于投票
关于使用STM32的USART模块实现Modbus协议的讨论
香水城 发表于 2008-6-12 10:49 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

楼主: 请教Modbus高手makesoft:实现Modbus协议一定需要超时检测吗?

首先声明,我对Modbus不熟悉,尤其是如何实现它,最近才从网上下载了协议研究了一下,特此向高手请教。搞清楚这些问题,才能有效地在芯片中实现相应的功能,满足大家的需要。

此帖的目的是继续另一帖的讨论:建议STM32的芯片加上串口超时功能,很好用的一个功能


这里是我的实现描述:
Modbus的请求数据包都是由下面几部分构成:
一、从机地址;固定为一个字节
二、功能代码;固定为一个字节
三、功能参数;长度依不同功能代码而不同
四、数据域;长度在功能参数中定义
五、校验码;固定为两个字节

下面以功能代码=0x03的数据包交换说明如何使用STM32进行数据传送:
1、主机发送8字节:
  从机地址:  1字节
  功能代码:  1字节 = 0x03
  起始地址:  2字节
  读取数目:  2字节 = N
  CRC校验码: 2字节
2、从机先接收2字节,当得知功能代码为0x03时,再继续接收6个字节
3、从机发送 N*2+4字节 = (1字节功能码+1字节数据长度+N*2字节数据+2字节校验码)
4、主机接收从机发出的(N*2+4)字节数据。因为主机知道N的数值,所以主机知道从机响应的数据包的长度

这里可以看到,如果没有FIFO,需要在上述第2阶段从机接收主机请求时分为两个步骤进行;而在其他的阶段使用DMA的效率不比使用FIFO差,而且在第4阶段,如果数据包长度大于FIFO深度时,使用DMA的效率更高!



根据我的理解,Modbus协议是主从结构,即主机发送请求给从机,从机收到请求后根据要求返回主机需要的数据或状态。主机的发送和接收都是主动的,它随时知道发送或接收数据的长度;而从机的发送是被动的,只有在接收到主机的请求后才能发送指定的数据或状态。

因此,主机没有必要通过超时检测来判断帧的开始和结束。对于从机讲,在接收第一个请求帧时,它一定知道帧的开始,同时根据我上面描述的步骤,它也可以很容易的知道帧的结束。既然可以判断出第一个帧的开始和结束,那么随后的帧就不难区分了。

所以,我希望makesoft能够对你的注解(“关键是你没有延时无法判断什么时候是一个帧的开始和结束”)加以解释,“延时判断”真的很关键吗?谢谢!

签名:


makesoft 发表于 2008-6-12 11:00 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

2楼: 因为MODBUS RTU方式没有帧头和帧未特定的字节

这样在程序中间无法判断一个帧的开始和结束,一般都是用超时来判断的。

在没有错误的情况下,直接从接收的第一个字节来判定应该是没有问题的,但当字节在传输过程中丢失或者是畸变的时候,程序就吊死在那里了。



签名:



makesoft 发表于 2008-6-12 11:02 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

3楼: RTU帧特性是这样表述的

 

点击看大图

签名:


makesoft 发表于 2008-6-12 11:04 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

4楼: 其实在低速率情况下,字节逐一中断并不特别占用CPU时间

还是可以容忍的
我现在的项目超时是用SYSTICK实现的,感觉问题也不大

签名:


makesoft 发表于 2008-6-12 11:05 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

5楼: 另外说明一下不是什么“高手”

 

签名:


香水城 发表于 2008-6-12 12:02 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

6楼: 找到一个在STM32下实现Modbus要求的超时检测的折衷办法

这个方法是使用UART接收信号去复位一个定时器的计数器,如果UART的RX线上长时间没有电平变化,定时器的计数器将连续计数,最终达到设置在输出比较寄存器中的超时数值并触发中断,从而达到超时检测的目的。

该方法占用一个I/O口和一个定时器,好在STM32的资源很丰富,哈哈。


另一个方法是使用UART自身的IDLE检测中断,即在RX线上超过一个字符传送时间而没有检测到启始位时产生的中断,再进一步判断是否有超时。

* - 本贴最后修改时间:2008-6-12 16:46:32 修改者:香水城

签名:


John_light 发表于 2008-6-12 12:15 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

7楼: 是这个东西吗?

以下内容摘自NXP LPC2119/2129/2194/2292/2294的User Manual:
The CTI interrupt (U0IIR3:1=110) is a second level interrupt and is set when the UART0 Rx FIFO contains at least one character and no UART0 Rx FIFO activity has occurred in 3.5 to 4.5 character times. Any UART0 Rx FIFO activity (read or write of UART0 RSR) will clear the interrupt. This interrupt is intended to flush the UART0 RBR after a message has been received that is not a multiple of the trigger level size. For example, if a peripheral wished to send a 105 character message and the trigger level was 10 characters, the CPU would receive 10 RDA interrupts resulting in the transfer of 100 characters and 1 to 5 CTI interrupts
(depending on the service routine) resulting in the transfer of the remaining 5 characters.

签名:

练拳不练功,到老一场空。
╭~~~╮╭~﹌╮
(=^o^=)(o'_'o)
(~)ǒ(~)(~)ǒ(~)

hotpower 发表于 2008-6-12 13:15 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

8楼: 好帖~~~学习学习~~~

 

最基本的工业控制总线MODBUS(转帖)

签名:

●█〓██▄▄▄▄▄▄ ●●●●●●→ ''''╭WWWW╮
▄▅██████▅▄▃▂ 传播非典灌水四方 ( ●_●)
██████████████ '''',,,;,;,;'''/▇\''
◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤ 俺的地盘俺做主/MMMM\
菜农浇灌的水田


俺的地盘俺做主

jinjing999 发表于 2008-6-12 14:29 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

9楼: 我知道

Modbus协议接收的数据组是不固定的,而且串口接收到数据后也要马上返回数据,因此该协议规定如果接到一组数据后,停止1.5个字节时间,不再有数据接收,就认为这组数据接收完毕。注意1.5字节的时间跟波尔特率有关系。

一般的实现方法,一但接收到数据,马上打开一个定时器,而且定时器要开中断,定时的时间是当前波特率下1.5字节所需要的时间。如果一组数据没有接收完毕,直接复位定时器,一旦没有数据传送,定时器就不再复位,一直等到定时器中断,这样就认为一组数据接收完毕。

如果串口判断接收端口没有电平的时间,就可以很轻松实现这个功能。楼主Modbus协议就是这比较难实现


香水城 发表于 2008-6-12 16:47 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

10楼: 哈哈,没想到我的一块砖头引来这么多美玉,这么多高手

谢谢各位,我知道怎么做了。

签名:


netjob 发表于 2008-6-12 17:01 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

11楼: 上次已经说过了,可以用定时器来实现超时。

ATMEL 的ARM7/9 串口也没有 超时功能,

NXP的ARM7/9 串口就有有 超时功能,

正确是叫 字符超时指示(CTI) 很多人利用此作为判断帧结束的标志!






 


cecoyzy 发表于 2008-6-12 17:59 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

12楼: 回楼上的:ATMEL 的ARM7串口有 超时功能

 


mr.king 发表于 2008-6-12 19:12 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

13楼: 12楼对的

 


栏杆 发表于 2008-6-12 19:21 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

14楼: mark

mark"正确是叫 字符超时指示(CTI) 很多人利用此作为判断帧结束的标志!
"


香水城 发表于 2008-6-12 20:39 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

15楼: 楼上所说的mark是否就是传输线上一个连续的高电平?

在STM32中,这是一个IDLE条件,又专门的状态标志位指示这个状态,并可以产生中断。这就是我在6楼说的第二种方法中提到的IDLE检测中断。

签名:


netjob 发表于 2008-6-12 23:36 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

16楼: ATMEL 中是有超时! 谢谢cecoyzy提醒!

USART 中断使能寄存器:
TIMEOUT: 超时中断使能
.....
USART 通道状态寄存器:
TIMEOUT: 接收器超时


lihuyong 发表于 2008-6-13 00:13 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

17楼: MODBUS-RTU模式 必须 使用超时检测

参考一下FreeModbus的源代码,里面有怎么处理的,比较符合MODBUS的协议要求

利用定时器的超时溢出来判断帧的开始以及结束

每接受一个字符,定T35,如果到点了,那么接收一帧完毕,接着进行帧处理


neaphy 发表于 2008-6-14 22:26 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

18楼: IDLE检测中断+DMA

"另一个方法是使用UART自身的IDLE检测中断,即在RX线上超过一个字符传送时间而没有检测到启始位时产生的中断,再进一步判断是否有超时。"


用这个方法+DMA效果最好



id001 发表于 2008-7-9 19:32 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

19楼: 对18楼操作的疑问?



刚没有数据发过来的时候,USART线上是一直IDLE的。所有USART空闲时将不断的引起IDLE中断。

那你什么时候开的IDLE中断??????


speed_2008 发表于 2008-7-10 13:30 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

20楼: 开启IDLE中断的时间选择在已经接受到至少一个字节以后

系统分类: 单片机
用户分类: 性能分析
标签: STM32 USART ModBus 讨论
来源: 整理
发表评论 阅读全文(336) | 回复(0)

2

关于投票
使用STM32的单个普通定时器产生4路不同频率的方波
STM32的普通定时器有四路输出:TIMx_CH1、TIMx_CH2、TIMx_CH3和TIMx_CH4,可以使用输出比较的方法产生不同频率的方波输出,简单的方法是:

1)设置计数器为向上计数模式,将自动重装载寄存器设置为0xFFFF;这样计数器会循环计数。

2)每个定时器通道设置为输出比较模式,并设置比较匹配时对应的输出管脚翻转输出。

3)按照输出波形的半波周期计算出一个数值称作Half_Cyc。例如:定时器的时钟频率是72MHz,需要产生3456Hz的方波,则Half_Cyc = 72M/(3456*2) = 41667;如需要产生200kHz的方波,则Half_Cyc = 72M/(200k*2) = 180。

4)设置每个通道在输出比较匹配时产生中断,在中断中将比较寄存器的数值读出并加上Half_Cyc的数值,如果计算出的数值超过16位则舍弃超出的部分,再把这个新的数值写回相应的比较寄存器;这样下次比较成功将刚好发生在一个半波周期之后,对应的管脚将被翻转。


上述方法在要求频率不高时十分有效,但如果频率较高时会有频繁的中断产生,这时可以使用DMA加以改善。

上述方法的基础是通过不断改变输出比较的匹配点进而产生管脚翻转输出,我们可以事先计算好这些比较匹配点,并通过DMA在每次匹配时逐次更新比较寄存器的内容:

方法一、使用两个DMA缓冲区,在DMA控制器操作一个缓冲区时,程序计算好另一个缓冲区的数据,然后在DMA传输结束的中断处理中切换DMA操作的缓冲区。

方法二、使用一个大的DMA缓冲区,先计算好半个缓冲区的内容,启动DMA为循环模式并设置它在DMA传送一半和完成时均产生中断;启动DMA后继续计算好另外半个缓冲区的内容,当发生DMA中断时表示有一半缓冲区变空,这时在中断处理中计算好这半个缓冲区。

只要DMA缓冲区开的足够大,方法二可以保证CPU有充足的时间进行数据处理,并且保证不断地输出波形。


声明:以上说明没有经过实际验证,只是一个原理说明,也许还有没考虑周全的地方。
系统分类: 单片机
用户分类: 性能分析
标签: STM32 PWM 定时器 DMA
来源: 原创
发表评论 阅读全文(219) | 回复(0)

2

关于投票
关于IO用作复用功能时的时钟设置注意要点

近来碰到很多客户在使用STM32的外设时,由于IO口被用作复用功能,但是外设的初始化正确,GPIO口初始化正确,外设的时钟也已开启,但是外设无法正常运行。

其中最关键的一项,大多数使用者多没有设置,就是某个IO口被用作外设的接口时,需要开启IO口的复用功能的时钟,即进行外设、IO的时钟使能时,需要如下代码

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx | RCC_APB2Periph_AFIO, ENABLE);    /* GPIOx and AFIO clock enable */
x --- 为对应的GPIO口,如:A、B、C、D、E。

希望用户在使用时,注意该要点!

系统分类: 单片机
用户分类: 产品特性
标签: STM32 复用功能 时钟 GPIO
来源: 原创
发表评论 阅读全文(194) | 回复(0)

1

关于投票
如何使用STM32的PVD对电源的电压进行监控

用户在使用STM32时,可以利用其内部的PVD对VDD的电压进行监控,通过电源控制寄存器(PWR_CR)中的PLS[2:0]位来设定监控的电压值。

PLS[2:0]位用于选择PVD监控电源的电压阀值:
000:2.2V
001:2.3V
010:2.4V
011:2.5V
100:2.6V
101:2.7V
110:2.8V
111:2.9V

在电源控制/状态寄存器(PWR_CSR)中的PVDO标志用来表明VDD是高于还是低于PVD设定的电压阀值。该事件连接到外部中断的第16线,如果该中断在外部中断寄存器中被使能的,该事件就会产生中断。当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。这一特性可用于发现电压出现异常时,执行紧急关闭任务。

点击下载

系统分类: 单片机
用户分类: 实用例程
标签: STM32 PVD 监控 紧急事件
来源: 原创
发表评论 阅读全文(176) | 回复(2)

2

关于投票
如何使用STM32的窗口看门狗
STM32F的窗口看门狗中有一个7位的递减计数器,它会在出现下述2种情况之一时产生看门狗复位:
1)当计数器的数值从0x40减到0x3F时
2)当刷新看门狗时计数器的数值大于某一设定数值时,此设定数值在WWDG_CFR寄存器定义

对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但这有一个隐患,有可能程序跑乱了又跑回到正常的地方,或跑乱的程序正好执行了刷新看门狗操作,这样的情况下一般的看门狗就检测不出来了;如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗也不会滞后刷新看门狗,这样可以检测出程序没有按照正常的路径运行非正常地跳过了某些程序段的情况。
系统分类: 单片机
用户分类: 产品特性
标签: STM32 看门狗 窗口看门狗
来源: 原创
发表评论 阅读全文(143) | 回复(0)
总共 , 当前 /