一、治具需求
1、应工厂产线测试RF(无线烟感设备)灵敏度需求,需要开发一个RF灵敏度测试的治具。
2、配合信号发射器,让烟感设备进入RX模式,将RF数据DATA(接收到信号设备发射器的信号,通常为PWM输出)引出到IO口。再通过治具将DATA脚信号当输入捕获,解析PWM信号的频率和占空比来判断灵敏度。
二、功能实现
1、STM8S007硬件连接
TIM1 的channel 1即PC1作为PWM输入捕获信号;
TIM2 的channel 1输出一个1K Hz的, 50%占空比的PWM,模拟作为RF的DATA信号;
2、软件配置
2.1 Tim1 输入捕获配置
需要将捕获输入的信号配置到两个比较器IC1/IC2,参考STM8官方文档。
static void SysClkConfig(void)
{
/*High speed internal clock prescaler: 4*/
//CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_4); // 16M/4 = 4M
CLK_LSICmd(ENABLE);
while (CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == RESET);
CLK_HSICmd(ENABLE);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//16MHZ for system clock /4 = 4MHz
//CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, ENABLE, DISABLE);
while (CLK_GetSYSCLKSource() != CLK_SOURCE_HSI);
//CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
}
#ifdef SUPPORT_RF_RX_TEST
#define Timer_1_Prescaler (16)
#define Timer_1_CntValue (0xFFFE)
#define Timer_1_ReLoadValue (0x00)
/*TIM1 Channel1 output frequency = TIM1CLK / (TIM1 Prescaler * (TIM1_PERIOD + 1))
= 16000000 / (16) = 1M Hz
t = 1/10000 S = 1us
*/
#endif
/**********************************************************************/
//Description: TIM1_Config()
//Parameters:
//Return:
//Date:
//Author: quanwu.xu
/**********************************************************************/
void TIM1_Config(void)
{
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
TIM1_DeInit();
TIM1_TimeBaseInit(Timer_1_Prescaler, TIM1_COUNTERMODE_UP, Timer_1_CntValue, Timer_1_ReLoadValue);//16MHz, 16分频后为1MHz,即1us计数一次,向上最大计数0xFFFE(实际运行是每次中断后会重置计数器)
TIM1_PWMIConfig(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING,
TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x08);//配置DIRECTTI,则IC1的信号是TI1FP1
TIM1_PWMIConfig(TIM1_CHANNEL_2, TIM1_ICPOLARITY_FALLING,
TIM1_ICSELECTION_INDIRECTTI, TIM1_ICPSC_DIV1, 0x08);//配INDIRECTTI,则IC2的信号是TI1FP2
TIM1_SelectInputTrigger(TIM1_TS_TI1FP1); //再设置正确的触发源,即TI1FP1作为触发信号
TIM1_SelectSlaveMode(TIM1_SLAVEMODE_RESET); //从模式控制器需要配置成复位模式,下降沿的时候会重新初始化计数器
TIM1_CCxCmd(TIM1_CHANNEL_1, ENABLE);
TIM1_CCxCmd(TIM1_CHANNEL_2, ENABLE);
TIM1_ITConfig(TIM1_IT_CC1 , ENABLE); //CC1比机器中断
/* Clear CC1 Flag*/
TIM1_ClearFlag(TIM1_FLAG_CC1);
/* Enable TIM1 */
TIM1_Cmd(ENABLE);
}
2.2 Tim2模拟输出PWM,(输出1K, 50%占空比)
#ifdef SUPPORT_RF_RX_TEST
#define Timer_2_Prescaler (160)
#define Timer_2_ReLoadValue (1000-1)
#define Timer_2_PlusValue (500-1)
/*TIM1 Channel1 output frequency = TIM1CLK / (TIM1 Prescaler * (TIM1_PERIOD + 1))
= 16000000 / (160) = 100000 Hz
t = 1/10000 S = 0.1ms
*/
#endif
/**********************************************************************/
//Description: TIM2_Config()
//Parameters:
//Return:
//Date:
//Author: quanwu.xu
/**********************************************************************/
void TIM2_Config(void)
{
GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_SLOW);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_16, Timer_2_ReLoadValue); //16M/16 = 1M 1/1000 000 = 1us, 1us * 500= 500us, Freq = 2K
TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, Timer_2_PlusValue,TIM2_OCPOLARITY_HIGH);
TIM2_Cmd(ENABLE);
}
2.3 中断处理函数。
每次中断,pSystemApiTag->Cc1Value = TIM1_GetCapture1();读到一个周期的计数值1000左右,即对应1K频率,1000us。
pSystemApiTag->Cc2Value = TIM1_GetCapture2();读到一个占空比的计数值,即对应50%,500us。
实际CLK应该存在一定误差:同一个板子反复测试,都再940左右和470左右。
//uint16_t Cc1Value = 0;
//uint16_t Cc2Value = 0;
#define STAND_500us_Vaule ((uint16_t)470)
#define STAND_1000us_Vaule ((uint16_t)940)
#define MAX_RANG(x) (x + 10)
#define MIN_RANG(x) (x - 10)
#define IS_500us_RANG(x) (((x<MAX_RANG(STAND_500us_Vaule))&&(x>MIN_RANG(STAND_500us_Vaule)))?TRUE:FALSE) // 500us
#define IS_1000us_RANG(x) (((x<MAX_RANG(STAND_1000us_Vaule))&&(x>MIN_RANG(STAND_1000us_Vaule)))?TRUE:FALSE) // 1000us
INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
if(pSystemApiTag->StartTestFlag == TRUE)
{
// Cc1Value = TIM1_GetCapture1();
// Cc2Value = TIM1_GetCapture2();
pSystemApiTag->Cc1Value = TIM1_GetCapture1();
pSystemApiTag->Cc2Value = TIM1_GetCapture2();
if(IS_1000us_RANG(pSystemApiTag->Cc1Value) && IS_500us_RANG(pSystemApiTag->Cc2Value))
{
pSystemApiTag->CaptureCnt++;
}
}
TIM1_ClearFlag(TIM1_FLAG_CC1);
TIM1_ClearFlag(TIM1_FLAG_CC2);
}
三、实际应用
1、通过判断 960 < pSystemApiTag->Cc1Value < 980 和 460 < pSystemApiTag->Cc2Value < 480:
即IS_500us_RANG(x)和 IS_1000us_RANG(x)满足,判定是一个正常的PWM波,即Cnt++。
2、再设定一个事件,如按键按下计时2s内有 Cnt > 1990次,则判断RF灵敏度正常。
还可以通过示波器的标准输出1KHz, 50%占空比波形验证。