【STM8手持示波仪】软件模块设计
经过前期的实验,对示波表的工作过程有了一个大概的了解,在此基础上提出如下的软件结构,与大家商讨。如有不当和幼稚的地方还请大家多多指正为谢。一、按键功能定义。
按照SMHO的硬件设计,有12个按键可供利用,我对这些按键的功能有如下的定义:
1、MODE按键 在AC/DC耦合、自动量程、手动量程功能间切换
2、冻结波形按键
3、时基+、时基-
4、垂直灵敏度+、垂直灵敏度-
5、触发电平+、触发电平-
6、波形显示 上移、下移、左移、右移
二、软件模块划分
共分为如下模块,每个模块都需要提供一个初始化函数
1、液晶驱动模块: 提供画点、画直线、显示ASCII字符串、显示Bitmap接口共上层使用,为了提高效率,在MCU内开辟显示缓存,画点等操作直接在MCU内显存中操作,操作完成后在同步更新MCU显存和LCD显存;
2、按键驱动模块:完成底层硬件的按键扫描,提供获取按键值、按键类型的接口;
3、ADC采样模块:ADC数据采样,用TIM1更新事件触发ADC采样,ADC采样结束中断存储结果。(应根据当前系统运行状态选择是否将数据存入缓冲区,缓冲大小160*2,大家讨论多少点合适)
4、电平触发模块:外部触发电路向单片机提供中断信号,用该信号启动一次ADC采样过程。
5、数据处理模块:一次ADC采样结束后,将缓冲区中数据用于计算峰峰值、有效值、周期、频率。
6、波形显示模块:提供显示波形、波形上移、波形下移、波形左移、波形右移、显示频率、周期、峰峰值、有效值、显示通道信息等接口;
7、程控模块:提供增大增益、减小增益、增大扫速、减小扫速、增大触发电平、减小触发电平接口;增益调节通过外部程控放大电路实现、扫速控制通过控制TIM1的更新频率来控制扫速。输出PWM信号用于调节触发电平)
(PS:TIM1的更新事件用于触发ADC采样,还能用于产生PWM信号吗?如果能,低扫速时产生的PWM会不会太低?如果不能原来选择的PWM信号输出引脚可能需要修改)
待续... 整个架构,建议采用简单的分时处理
这样才能处理好显示和ADC采集的矛盾 1、MODE按键 在AC/DC耦合、自动量程、手动量程功能间切换
加一个触发模式.单次;上升,下降沿触发.
加一个通道选择.
2、冻结波形按键
最好是RUN/STOP两个功能.
(PS:TIM1的更新事件用于触发ADC采样,还能用于产生PWM信号吗?如果能,低扫速时产生的PWM会不会太低?如果不能原来选择的PWM信号输出引脚可能需要修改)
我建议ADC能否连续采样,定时器定时去读取采样结果. 回【1楼】 dvhome
我的想法是:采集--- 处理----显示-----采集----
这就是你说的分时处理吧? 不是
我说顺序是:
采集
处理一部分
显示一部分
采集
处理一部分
显示一部分
…… 加一个触发模式.单次;上升,下降沿触发.
现在有硬件触发电路了,硬件触发电路可以实现这些功能吗?如果可以加这个模式没问题。
我建议ADC能否连续采样,定时器定时去读取采样结果.
这样做可行吗?这样做的好处是什么?如果定时器读取采样结果时,正好ADC采样到一半那么本次读取的结果不就不准确了吗? 【4楼】 dvhome
你的意思是还没有采集完数据,就开始处理和显示了吗?这样就需要几个并行的任务,怎么实现呢?
各部分代码在16MHz下需要的时间如下:
完成整个屏幕的刷新10ms
adc 200k采样 1000点 5ms
峰峰值、周期计算等应小于2ms
这样算来,按我的处理方式在高速采样时也能做到每秒更新50次以上 【4楼】 dvhome
会不会在处理和显示的时候,漏掉了一部分数据,造成数据的不连续呢?
如果采集完一批以后,再处理和显示的话,这批数据就连续了.最多就是两批数据之间是不连续的.对于有触发的显示来说,这并不重要.
【5楼】 ifree64
我建议ADC能否连续采样,定时器定时去读取采样结果.
这样做可行吗?这样做的好处是什么?如果定时器读取采样结果时,正好ADC采样到一半那么本次读取的结果不就不准确了吗?
-----这是有可能的,但是如果是正好ADC采样到一半,那就读取前一次采样的数据了.这是对示波是没有影响的. 举个例子:
ADC过程 时钟中断响应
采样开始
采样结束
存数据 读数据
... ...
采样开始 读上次数据
采样结束
存数据
... ...
采样开始
采样结束 读上次数据
存数据
... ...
采样开始
采样结束
存数据 读数据 我的想法是采用定时器来做ADC扫描(或者是触发方式),这个优先级是最高的
利用每次扫描的间隔来做显示的处理
因为我们的示波显示区域是固定的,因此这个部分可以用定时器来分部分更新,这个优先级低
我之所以提出这样的方式,是考虑这样能否实现采集的连续性
如果ADC扫描间隔时间太短,没有办法利用间隔时间来做显示更新,那就按照 ifree64 的方式做吧 ADC扫描间隔确实可以做很少量的工作,但是LCD太慢了,一次LCD读写操作时间大于ADC扫描间隔。
为了不影响LCD显示,我的LCD驱动写指令、数据代码甚至关中断了,否则就会看到LCD非常闪。 谢谢【8楼】 ywl0409 老黄牛
这样我就可以用其他定时器来定时读取adc结果,TIM1用于产生PWM信号了。
但如果不考虑TIM1输出PWM波形这个功能,连续采样定时读取的方式有没有比定时触发转换优越的地方呢? 突然想到,不能使用连续ADC采样定时读取的方式,理由如下:
假设ADC采样时钟6MHz,那么每次ADC转换时间为2.3us,连续采样,则采样点的值分别是t0+n*2.3时刻的值;如果定时读取为2.5us读一次,也就是400k采样率,我们分别(不考虑中断的误差)在t0+n*2.5时刻读取
2.5us定时中断 5us定时中断
1、f(t0+2.3u) t0+2.5读取
2、f(t0+4.6u) t0+5.0读取 t0+5
3、f(t0+6.9u) t0+7.5
4、f(t0+9.2u) t0+10 t0+10
5、f(t0+11.5u) t0+12.5
6、f(t0+13.7u) t0+15 t0+15
7、f(t0+16) t0+17.5
8、f(t0+18.3) t0+20 t0+20
9、f(t0+ 20.7) t0+22.5
10、f(t0+23) t0+25 t0+25
11、f(t0+25.3) t0+27.5
12、f(t0+27.6)
13、f(t0+29.9) t0+30 t0+30
……
从上表可看出本是按2.5us采样周期采样数据,但前11个数据实际是2.3u的采样间隔,第12个数据与第11个数据却有4.6us的采样间隔。这就不是实际要求的2.5us采样周期了,严格来说这是不正确的。当然再以低扫速读取数据时,相对误差会比较小。但我觉得用定时触发转换可以避免这样的误差,就没有理由舍弃好的方法。
对于5us中断,前5个数据4.6us采样间隔;第6个数据间隔6.9us ifree64下面是myavr 提出的关于IO分配的意见,你评估一下,使用普通IO与带输入捕获的哪一个更好一些。
<fontvcolor=blue>
CH2_INPUT PI0 //通道2逻辑输入
----------------------------------------------------------
逻辑通道输入直接采用普通IO口输入吗?用输入捕捉的IO是否好一点? 【12楼】 ifree64
是的,看来,从时间的准确方面,还是要定时去转换. 回13楼
IO分配上,由于上次考虑不周,有些IO分配有不合理的地方。
比如PWM信号产生,考虑到我上面提出的问题,可能要使用TIM2或TIM3的输出端
CH2通道,使用普通IO可能确实不方便,但我现在也不能给肯定的答复。输入捕捉应该与测量外接信号周期功能有关,但是对逻辑测试功能是否有帮助还待大家讨论。我觉得是否引脚有电平变化时产生中断的功能就可以了?
我还没有用过逻辑分析仪,所以对CH2通道功能认识不足,可不可以给点资料补一下课。 【15楼】 ifree64
这样通道二的功能先不管它,使用普通IO即可。
你再考虑一下AD采样的问题! 【15楼】 ifree64
【16楼】 smallsnail 燕 青
其实只要把CH2通道放到一个有输入捕获的IO口就行了,如果不用捕获功能的话直接把该IO口初始化成为普通IO口即可 同意my_avr的看法 信号的输入捕捉功能:
因对于脉冲信号有上升延和下降沿,同样触发有低电平触发、高电平触发、上升沿触发、下降沿触发。STM8S的定时器输入捕捉功能可以在硬件上支持上述的信号触发。
1、对于触发方式:
对于边沿方式我们可以选择Timer IACP的标准触发模式(Trigger standard mode),对于电平触发,我们可以选择Timer ICAP的门控触发模式(Trigger gated mode);
2、对于信号滤波:
输入信号的毛刺可以通过配置输入捕获IO的滤波器(the input filter duration)来解决;
3、捕捉方式:
Timer触发,开始计数,以Timer Clk为计数单位,电平的有效时间就是两次触发的间隔计数时间。
4、信号捕捉的效率:
因为STM8S的单一输入捕捉口不能同时设置两种触发方式,即一次设定上升延、下降沿,高电平、低电平。需要先设定一种触发模式,在进入中断后在在中断服务程序中修改触发模式。为此我们通过将一个定时器的两个不同输入捕获引脚同时连接同一个信号,利用双触发模式来计算电平在低时的时间和在高时的时间。
这里会涉及两种处理方法,一是中断方式,另一是查询方式。
因STM8S进入中断固定压栈是9个字节,消耗9个CPU时钟周期,因此单纯的用中断方式来得到电平变换的时间间隔有点浪费。建议可以不开输入捕捉中断,使用查询输入捕捉标志位,都影子寄存器的方式来实现。
下面是STM8S的输入捕捉的一些数据:
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_433828.jpg
(原文件名:t1.jpg)
定时器的时钟我们是知道的
触发信号计数的结构流程:
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_433829.jpg
(原文件名:t2.jpg)
单一电平有效计数的寄存器操作流程:
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_433830.jpg
(原文件名:ICAP.jpg) 综合以上几位的意见,那就把CH2改到带有输入捕获功能的引脚上。
但前提是先完成CH1的基本功能,波形显示正常后,才进行CH2的功能开发!
另ifree64 AD采样的问题现在怎么处理了? 【12楼】 ifree64
>>>从上表可看出本是按2.5us采样周期采样数据,但前11个数据实际是2.3u的采样间隔,第12个数据与第11个数据却有4.6us的采样间隔。这就不是实际要求的2.5us采样周期了,严格来说这是不正确的。当然再以低扫速读取数据时,相对误差会比较小。但我觉得用定时触发转换可以避免这样的误差,就没有理由舍弃好的方法。
建议用定时器来触发ADC采样,然后在采样结束中断中将数据存入ring buffer。 用AVR时,一般都是把ADC设置成T0 溢出,开始转换,用ADC转换结束中断输出数据,做标记,并可以设置下次采样信息。只要调T0就可以设置采样率。
轻轻松松数据自然来。
STM8 应该也可以这样做。
TM1触发ADC转换,ADC转换结束中断输出数据,缓冲满了就停止采样。 回楼上,是的,我就是这样做的。
不过现在的问题是TIM1用于触发ADC采样了,再用于生成PWM波就有点不方便了。因为修改采样率时,将影响到产生PWM信号的频率。
为此建议对产生PWM信号频率的引脚进行修改。
TIM1 用于控制ADC采样率
TIM3_CH1
TIM3_CH2用于输出PWM信号调节触发电平和波形平移
TIM2_CH1
TIM2_CH2用于逻辑通道的输入捕获。
另请教Grant,按你给出的资料,输入捕获可用于测量外接信号的周期,这对UART、I2C、SPI等的分析有用吗?
如果这样分配的话,没有硬件资源来产生2KHz的基准信号,只有采用剩余的74HC04来做2Khz的基准信号了。原电路图的BEEP也需改IO接口,用软件模拟方法产生信号(另:蜂鸣器在这里有什么用?) 貌似只有TIM1才有输入捕获,也只有TIM1才可以触发ADC转换 TIM2/TIM3也有输入捕获,但只有TIM1才可以触发adc转换。
电平平移的PWM频率和探头补偿的PWM信号频率相差太多,貌似不能用同一个定时器来同时生成,这样如果用TIM2来捕获,TIM3来产生PWM,就要差一路信号。遗憾的是最强大的TIM1用于ADC触发后,不方便作为其他功能使用了。 硬件方法用
TIM2有3路PWN信号:
触发 PWN可调
平移 PWN可调
频率补偿信号 50%PWN 硬件分频,出2K。
有常规的8分频IC,少用,忘记了。
TIM3作为输入捕获用。 是否可以使用ADC_ETR触发信号来触发adc转换.
而ADC_ETR触发信号的输入,可以,由一个定时器中断来产生. Re 23楼
TIM2_CH1
TIM2_CH2用于逻辑通道的输入捕获。
另请教Grant,按你给出的资料,输入捕获可用于测量外接信号的周期,这对UART、I2C、SPI等的分析有用吗?
如果这样分配的话,没有硬件资源来产生2KHz的基准信号,只有采用剩余的74HC04来做2Khz的基准信号了。原电路图的BEEP也需改IO接口,用软件模拟方法产生信号(另:蜂鸣器在这里有什么用?)
不是测量外接信号周期,是测量外接信号的每个电平时间。每个高电平要多长时间,每个低电平要多长时间都出来了,不就还原了信号?
测量外接信号的周期性的PWM信号用的是另一个模式,叫PWM input signal measurement,直接就是读出周期和占空比。其实是上面用法的一个特例。
Beep功能是使用一个独立的计数器产生一个1K、2K、4K的信号,使用内容128K 低速时钟。
一个定时器具有4个OCMP,在OCMP中关掉IO电平翻转不就是4个计数器功能吗。也就是随便找个16bit Timer,就可以完成四个定时的功能,不是吗?这个与传统的51是完全不同。STM8208RBT6应该是由3个16为定时器,足够使用了。 ifree64在考虑一下【28楼】 Grant的意见,给出最终的修改稿。
我们的进度有点慢,O(∩_∩)O~ 谢谢 Grant
对定时器的使用我是这样打算的。
1、TIM1
工作于向上计数模式,设置TIM1_ARR以控制TIM1的更新事件产生频率,用更新事件触发ADC转换。
ADC转换也可以用OCiREF信号触发,但是比较匹配时定时器并不自动清零,所以无法产生周期的触发信号。又因为PWM模式下TIM1_ARR确定信号频率,TIM1_CCRi确定信号占空比;在TIM1_ARR控制ADC采样率后,就无法用于产生PWM信号了。
2、TIM2
用于输入捕获,完成通道2的逻辑功能;TIM2有3个输出脚,但如果要使用BEEP功能就要占用掉一个输出脚,只剩下2个输出脚了。
3、TIM3
TIM3_CH1、TIM3_CH2用于产生PWM信号,参考手册给出TIM2/TIM3都有3个OCMP,但是STM8208RBT6没找到TIM3_CH3引脚。
算来算去,差了一路PWM。问题就在于TIM1用作ADC触发后,它的输出比较模式还能不能用于产生频率一定得PWM信号(TIM1_ARR可能改变到使UEV事件频率很低的情况下)。 【31楼】 ifree64
如果这样的话,差一路PWM。
探头的校准信号使用剩余的7404产生。
如何?
如果同意,跟帖写出最新的IO分配。
然后硬件人员更新原理图,并绘制PCB。
谢谢! 32楼smallsnail燕青
我中午已经在第三版原理图一贴给出了IO分配修改意见。贴过来吧
IO分配还需要重新改进一下。综合各位的意见,大家看看下面的修改方案可行吗?
LCD部分
D0~D7 PB0~PB7 // 使用1个并行口 (修改理由,将CAN留出来或用于通道2监听CAN)
CSA PE6
CSB PE7
E PC1
RW PC2
DI PC3
RES PC4
BL PF4
DSO部分
OFFSET_PWM PD0(TIM3_CH1) // 电平平移PWM
COMP_PWM PD2(TIM3_CH2) // 比较器PWM
GAIN2 PG7 // 前端增益控制 输入1
GAIN1 PG6 // 前端增益控制 输入1
RELAY_ATT PE4 // 前端增益控制继电器
COMP_INT PF3 // 比较器输出
RELAY_ACDC PI0 // ACDC耦合控制继电器
CH2_INPUT PA3/PD3(TIM2_CH2/TIM2_CH3) //通道2逻辑输入(连2个IO)
ADC_INPUT PF0(AIN10) // 通道1模拟量输入
KEY部分
KEY_0 PD7 // 行线、列线使用了不同的IO
KEY_1 PD6
KEY_2 PD5
KEY_3 PG2
KEY_4 PG3
KEY_5 PG4
KEY_6 PG5
其他
BEEP PD4(BEEP) //蜂鸣器输出
UART1_TX PA4(UART1_TX)
UART1_RX PA5(UART1_RX)
UART1_CK PA6(UART1_CK)
本方案将I2C、SPI、CAN的IO都留出来了,但探头补偿信号没有资源了。可以考虑用74hc04来生成
CAL_PWM //探头补偿信号PWM 【33楼】 ifree64
32楼smallsnail燕青
我中午已经在第三版原理图一贴给出了IO分配修改意见
----------------------------------------------------
好的,谢谢! 还未见过有BEEP的示波器。对于示波器来说要个蜂鸣器有什么用
TIM2_CH1不是可以出2Khz的频率吗?刚好就是补偿了。 【35楼】 ZealotNH 发仔
还未见过有BEEP的示波器。对于示波器来说要个蜂鸣器有什么用
TIM2_CH1不是可以出2Khz的频率吗?刚好就是补偿了。
----------------------------------
谢谢提醒,已更改! 燕 青在画原理图吗?如果你在画的话我就不画了,免得重复劳动 【37楼】 my_avr
燕 青在画原理图吗?如果你在画的话我就不画了,免得重复劳动
-----------------------------------------------------
没有画,在加班呢,这两天公司有两块板子要完工,没有时间画这块了。
你完善一下,然后发到置顶帖里,我再更新到楼主位,谢谢。 好的,我在你的基础上完成,明天发出来 唉我都连续加了几晚班~
没什么生意,但做技术的还是这么忙。 我没太仔细对过IO的分配,看33楼
UART1_CK PA6(UART1_CK) 这个口留出做什么功能?
IO重复,可以考虑考虑IO Remap是否可以解决? 请问:为什么留IIC接口?接存储器吗?如果是接存储器的话,可用SPI口的存储器,SPI还可以用于芯片间的通信(以后的事了),IIC的速度太慢了,这两个口是否可以省了
回Grant:UART1_CK PA6(UART1_CK) 这个口留出做什么功能?这是个串口同步通信的时钟?STM32上也有,我用过,可以作为一个类似SPI口的通信方式去通信,这里已经有了SPI口了,貌似可以省了。
我在正在做STM32的USB通信呢,可惜了STM8没USB口,这就给以后和PC机通信带来麻烦了(只能用串口了)
多按键的是否可以用摇杆,199板子上的那种,应该不贵的,我觉得按键是否可以画在主板上,用比较高的那种,液晶用铜拄升上来,直接用长的排针连在主板上,这样会更可靠。用线连是不可靠的,我画板很少用线连。可以根据结构用不同的针和座去连。
家里装的是长城的宽带,是比电信的便宜,720一年,还不限时,过年的时候才装的,可惜两个星期前就根本不能上网了,虽然以前也长吊线。打电话喊人修,每次都说来过了,修好了,可是根本没有人来过,至少是没修好,看来星期日只有去网吧上网了 我自己在家做了个小ADC程序,可是看到楼上的ifree64写的程序都不好意思拿出来了,拿出来也没什么意思了。看来我以前说的ADC让我来做,是实现不了的了。 那我就听ifree64,Grant分任务吧。 Grant:如果用IAR什么版本才能用STLINK?5.20可以吗?有在IAR4.42A下用STLINK的驱动吗? 回:myworkmail
留IIC等接口的目的就是反正会有些IO口会留下来,那么就把这些具有特殊功能的IO口留出来,也许以后会派上什么用场,没有什么特别的目的。
软件任务的分配上,我争取明天晚上之前把系统的流程图和每个模块的接口和各模块之间关系的图画出来(这方面我的经验不足,还要请大家指教),到时候再分配吧。 to ifree64 :
我有一处不明白:
COMP_INT PF3 //比较器输出
比较器输出即触发输入放到PF3是否合适?PF3不能触发ADC进行转换吧? 理论上我们使用探头补偿时,应该不会使用到输入捕获吧? PA6(UART1_CK) 这个口肯定是没什么用了,这是个串口同步通信的时钟,STM32上也有,我用过,可以作为一个类似SPI口的通信方式去通信,这里已经有了SPI口了,可以省了。 主程序流程
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_434995.png
(原文件名:主程序流程.png)
点击此处下载 ourdev_434996.pdf(文件大小:41K) (原文件名:主程序流程.pdf) ADC中断处理流程
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_435000.png
(原文件名:ADC中断处理流程.png)
点击此处下载 ourdev_435001.pdf(文件大小:32K) (原文件名:ADC中断处理流程.pdf) ADC状态转换图
enum ADC_State{
STOP = 0,
WaitTrigger,
Tiriggered,
ADC_Buff_Full
};
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_435002.png
(原文件名:ADC状态转化图.png)
点击此处下载 ourdev_435003.pdf(文件大小:33K) (原文件名:ADC状态转化图.pdf) 触发中断处理流程,我打算使用通过2次触发中断间的时间间隔来计算信号周期,大家看合适吗?
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_435006.png
(原文件名:触发中断处理流程.png)
点击此处下载 ourdev_435007.pdf(文件大小:25K) (原文件名:触发中断处理流程.pdf) 按键处理流程
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_435033.png
(原文件名:按键处理.png)
点击此处下载 ourdev_435034.pdf(文件大小:35K) (原文件名:按键处理.pdf) 粗略看了一下流程图,有个不明白的地方:ADC缓存保存的是用来画波形的数据还是待平均的数据? ADC保存的是采样的原始数据。进行处理后再显示,处理中也可以考虑实现自动量程。 这样可以做到多少的深度?? 回dvhome
目前LCD驱动用掉了1.5K的内存,这样用于ADC的部分至少还有4K可用。 MARK
页:
[1]