硬件配置:
- Hardware board: NUCLEO-F302R8
- Clock Config:
- Sysclk: 64MHz
- TIM1 clock: 128MHz
- Timer1 ARR set to 6400, up counting, to get 128M/6400 = 20KHz update rate
代码
Timer ISR:
/**
* @brief This function handles TIM1 update and TIM16 interrupts.
*/
void TIM1_UP_TIM16_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */
if (LL_TIM_IsActiveFlag_UPDATE(TIM1)) {
LL_TIM_ClearFlag_UPDATE(TIM1);
counter++;
JSInterface_Sample();
}
/* USER CODE END TIM1_UP_TIM16_IRQn 0 */
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */
/* USER CODE END TIM1_UP_TIM16_IRQn 1 */
}
Segger RTT interface
#include "JSInterface.h"
#include "SEGGER_RTT.h"
#include "stdint.h"
#include "stdbool.h"
#define JS_RTT_Channel 1
extern uint16_t counter;
#pragma pack(push, 1)
typedef struct {
// int32_t i32V1;
// int32_t i32V2;
uint16_t u16V1;
uint16_t u16V2;
} Sample_Buffer_t;
#pragma pack(pop)
Sample_Buffer_t sampleBuffer;
char* rttUpBuffer[1024];
uint8_t sampleDivisorCounter = 0;
uint8_t sampleDivisor = 1;
bool enableJS = true;
void JSInterface_Init(void)
{
// SEGGER_RTT_ConfigUpBuffer(JS_RTT_Channel, "JScope_I4I4I2I2", rttUpBuffer, sizeof(rttUpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
SEGGER_RTT_ConfigUpBuffer(JS_RTT_Channel, "JScope_I2I2", rttUpBuffer, sizeof(rttUpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
}
void JSInterface_Sample(void)
{
// sampleDivisorCounter++;
// if (enableJS && sampleDivisorCounter >= sampleDivisor) {
// sampleBuffer.i32V1 += 4;
// sampleBuffer.i32V2 += 8;
sampleBuffer.u16V1 += 1;
sampleBuffer.u16V2 = counter;
SEGGER_RTT_Write(JS_RTT_Channel, &sampleBuffer, sizeof(sampleBuffer));
// sampleDivisorCounter = 0;
// }
}
问题
使用HSS模式时,观察到的结果跟预期的是一致的,初测周期是3.28s,也就是20KHz的计数频率( 65536 / 20000 ≈ 3.2 s 65536/20000 \approx 3.2s 65536/20000≈3.2s):
<,
>
然而当使用RTT模式时,得到的结果却不一样 (Period = 6.54s):
<,
>
以放大后的采样点来看,采样频率是10KHz:
这就有点尴尬了。。。。
从细节来看,虽然显示的采样点是100us,但是每次采样的值都差一,也就是采样频率应该是跟中断频率一致的:
<,
>
也就是说实际上程序能采到20KHz,但是显示的时候把你的分辨率给改了。。。。
顺便吐槽一下JScope的人机交互,缩放的时候到处跑,不能稍微做好一点么。。。。
再把中断频率改成16KHz, 还是显示10KHz:
<,
>
再把中断改成5KHz,周期还是6.52s:
<,
>
所以RTT模式下不用管时间轴就对了!
解决
在某个时刻突然脑子灵光一现,想起来说明文档UM08028 J-Scope里好像有一些关于时间的描述:
Type | Supported Sizes | Note |
---|---|---|
t | 4 | Indicates that every packet is preceded by a 32bit value containing a timestamp in µs |
b | 1 | Specifies a boolean value |
f | 4 | Specifies a 32bit floating point value |
i | 1,2,4 | Specifies a signed 8-, 16- or 32bit value |
u | 1,2,4 | Specifies a unsigned 8-, 16- or 32bit value |
嗯,想想也对,RTT模式下主机很难知道实际的采样频率到底是多少,所以自己加上时间就对了!
<,
>