#include "trigger.h"
#include "key.h"
#include "pwm.h"
#include "dac.h"
#include "system.h"
#include "SysTick.h"
#include "stm32f10x_conf.h"
#include "usart.h"
//全局变量//
volatile uint8_t trigger_state = 0;
volatile uint8_t trigger_state_2 = 0;
volatile uint8_t trigger_active_ch1 = 0;
volatile uint8_t trigger_active_ch2 = 0;
volatile uint16_t trigger_active_1 = 0;
volatile uint16_t trigger_active_2 = 0;
volatile uint32_t timer1_overflow_count = 0;
// 新增:信号处理状态标志
volatile uint8_t signal_processing_ch1 = 0; // CH1信号处理中标志
volatile uint8_t signal_processing_ch2 = 0; // CH2信号处理中标志
//状态机//
typedef struct {
uint8_t state;
uint64_t start_10us; // 10 μs 格子
uint64_t duration_10us;
uint16_t brightness;
} TriggerChannel;
TriggerChannel ch[2] = {
{0, 0, 0, 0},
{0, 0, 0, 0}
};
// 10 μs 时间戳//
uint64_t get_10us(void){
uint64_t ov1, ov2;
uint64_t cnt;
do {
ov1 = timer1_overflow_count;
cnt = TIM1->CNT;
ov2 = timer1_overflow_count;
} while (ov1 != ov2);
return ((ov1 << 16) + cnt) / 10; // 72 MHz / 720 = 100 kHz → 10 μs
}
//通用定时器单脉冲初始化//
void OnePulseTim_Init(TIM_TypeDef* TIMx, IRQn_Type IRQn){
RCC_APB1PeriphClockCmd(
TIMx == TIM6 ? RCC_APB1Periph_TIM6 :
TIMx == TIM7 ? RCC_APB1Periph_TIM7 : 0, ENABLE);
TIM_TimeBaseInitTypeDef tim = {
.TIM_Prescaler = 720 - 1, // 100 kHz → 10 μs
.TIM_Period = 0xFFFF,
.TIM_CounterMode = TIM_CounterMode_Up
};
TIM_TimeBaseInit(TIMx, &tim);
TIM_SelectOnePulseMode(TIMx, TIM_OPMode_Single);
NVIC_InitTypeDef nvic = {
.NVIC_IRQChannel = IRQn,
.NVIC_IRQChannelPreemptionPriority = 0x00,
.NVIC_IRQChannelSubPriority = 0x00,
.NVIC_IRQChannelCmd = ENABLE
};
NVIC_Init(&nvic);
TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);
TIM_Cmd(TIMx, DISABLE);
}
//启动一次单脉冲//
void FireOnePulse(TIM_TypeDef* TIMx, uint64_t dt_10us, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){
if (dt_10us < 1) dt_10us = 1; // 下限 10 μs
TIM_Cmd(TIMx, DISABLE);
TIMx->CNT = 0;
TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
TIMx->ARR = dt_10us - 1;
// 把 GPIO 信息保存到 CR1 的保留位(偷懒法)//
TIMx->CR1 &= ~0x7000;
TIMx->CR1 |= (GPIOx == GPIOA ? 0x1000 :
GPIOx == GPIOB ? 0x2000 : 0);
TIMx->CR1 |= (GPIO_Pin == GPIO_Pin_11 ? 0x0100 :
GPIO_Pin == GPIO_Pin_1 ? 0x0200 : 0);
TIM_Cmd(TIMx, ENABLE);
}
//时钟 //
void SystemClock_Config(void){
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while (RCC_WaitForHSEStartUp() == ERROR);
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while (RCC_GetSYSCLKSource() != 0x08);
SystemCoreClockUpdate();
}
//触发引脚+TIM1//
void TRIGGER_Init(void){
GPIO_InitTypeDef gpio;
EXTI_InitTypeDef exti;
NVIC_InitTypeDef nvic;
TIM_TimeBaseInitTypeDef tim;
SystemClock_Config();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_AFIO, ENABLE);
//PA9/PA6 浮空输入//
gpio.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_6;
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpio);
//PA11/PB1 推挽输出,默认灭//
gpio.GPIO_Pin = GPIO_Pin_11;
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio);
GPIO_ResetBits(GPIOA, GPIO_Pin_11);
gpio.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOB, &gpio);
GPIO_ResetBits(GPIOB, GPIO_Pin_1);
// EXTI 映射//
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource9);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);
exti.EXTI_Line = EXTI_Line9 | EXTI_Line6;
exti.EXTI_Mode = EXTI_Mode_Interrupt;
exti.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
exti.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti);
nvic.NVIC_IRQChannel = EXTI9_5_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 0x00;
nvic.NVIC_IRQChannelSubPriority = 0x00;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
//TIM1 1 MHz 计时 //
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
tim.TIM_Period = 0xFFFF;
tim.TIM_Prescaler = 72 - 1;
tim.TIM_ClockDivision = 0;
tim.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &tim);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
nvic.NVIC_IRQChannel = TIM1_UP_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 0x02; //低于 EXTI //
nvic.NVIC_IRQChannelSubPriority = 0x00;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
TIM_Cmd(TIM1, ENABLE);
/* 两路单脉冲定时器 */
OnePulseTim_Init(TIM6, TIM6_IRQn);
OnePulseTim_Init(TIM7, TIM7_IRQn);
SysTick_Init(72); //1 ms 节拍//
}
//TIM1 溢出//
void TIM1_UP_IRQHandler(void){
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) {
timer1_overflow_count++;
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}
}
// EXTI 中断//
void EXTI9_5_IRQHandler(void)
{
// PA9 CH1//
if (EXTI_GetITStatus(EXTI_Line9) != RESET) { // CH1
uint8_t level = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9);
EXTI_ClearITPendingBit(EXTI_Line9);
// 检查是否正在处理信号,如果是则忽略新信号
if (signal_processing_ch1) {
return;
}
if ((h1_state == H1_US_FLASH || h1_state == H1_MS_FLASH) && level == 0) {
// 新增:设置信号处理标志
signal_processing_ch1 = 1;
uint64_t dt = (h1_state == H1_US_FLASH) ? flash_time : flash_time * 100;
trigger_active_1 = 1;
TIM_SetCompare1(TIM8, gamma_table[target_brightness]);
FireOnePulse(TIM6, dt, GPIOA, GPIO_Pin_11);
Set_XOR_Inputs(1, 1);
}
else if (h1_state == H1_OFF || h1_state == H1_ON) {
if (h1_state == H1_OFF) {
if (level) { Set_XOR_Inputs(1, 0); trigger_active_ch1 = 0; }
else { Set_XOR_Inputs(0, 0); trigger_active_ch1 = 1; }
} else {
if (!level){ Set_XOR_Inputs(0, 1); trigger_active_ch1 = 1; }
else { Set_XOR_Inputs(1, 1); trigger_active_ch1 = 0; }
}
}
}
//PA6 CH2//
if (EXTI_GetITStatus(EXTI_Line6) != RESET) { // CH2
uint8_t level = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
EXTI_ClearITPendingBit(EXTI_Line6);
// 检查是否正在处理信号,如果是则忽略新信号
if (signal_processing_ch2) {
return;
}
if ((h2_state == H2_US_FLASH || h2_state == H2_MS_FLASH) && level == 0) {
// 新增:设置信号处理标志
signal_processing_ch2 = 1;
uint64_t dt = (h2_state == H2_US_FLASH) ? flash_time_2 : flash_time_2 * 100;
trigger_active_2 = 1;
TIM_SetCompare2(TIM8, gamma_table[target_brightness_2]);
FireOnePulse(TIM7, dt, GPIOB, GPIO_Pin_1);
Set_XOR_Inputs_2(1, 1);
}
//电平模式//
else if (h2_state == H2_OFF || h2_state == H2_ON) {
if (h2_state == H2_OFF) {
if (level) { Set_XOR_Inputs_2(1, 0); trigger_active_ch2 = 0; }
else { Set_XOR_Inputs_2(0, 0); trigger_active_ch2 = 1; }
} else {
if (!level){ Set_XOR_Inputs_2(0, 1); trigger_active_ch2 = 1; }
else { Set_XOR_Inputs_2(1, 1); trigger_active_ch2 = 0; }
}
}
}
}
//主循环非阻塞处理//
void handle_trigger(void)
{
if (trigger_state) {
trigger_state = 0;
ch[0].start_10us = get_10us();
ch[0].duration_10us = (h1_state == H1_US_FLASH) ? flash_time : flash_time * 100;
ch[0].brightness = gamma_table[target_brightness];
ch[0].state = 1;
}
if (trigger_state_2) {
trigger_state_2 = 0;
ch[1].start_10us = get_10us();
ch[1].duration_10us = (h2_state == H2_US_FLASH) ? flash_time_2 : flash_time_2 * 100;
ch[1].brightness = gamma_table[target_brightness_2];
ch[1].state = 1;
}
uint32_t now = get_10us();
for (int i = 0; i < 2; i++) {
if (ch[i].state == 1) {
if ((now - ch[i].start_10us) >= ch[i].duration_10us) {
ch[i].state = 0;
switch (i) {
case 0:
trigger_active_1 = 0;
switch(h1_state) {
case H1_OFF: Set_XOR_Inputs(1, 0); break;
case H1_ON: Set_XOR_Inputs(1, 1); break;
case H1_MS_FLASH:
case H1_US_FLASH: Set_XOR_Inputs(0, 1); break;
}
break;
case 1:
trigger_active_2 = 0;
switch(h2_state) {
case H2_OFF: Set_XOR_Inputs_2(1, 0); break;
case H2_ON: Set_XOR_Inputs_2(1, 1); break;
case H2_MS_FLASH:
case H2_US_FLASH: Set_XOR_Inputs_2(0, 1); break;
}
break;
}
}
}
}
}
//两路独立灭灯中断
void TIM6_IRQHandler(void) // CH1
{
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) {
trigger_active_1 = 0;
// 根据当前模式恢复正确状态
switch(h1_state) {
/* case H1_OFF:
Set_XOR_Inputs(1, 0); // 灭灯状态
break;
case H1_ON:
Set_XOR_Inputs(1, 1); // 亮灯状态
break;*/
case H1_MS_FLASH:
case H1_US_FLASH:
Set_XOR_Inputs(0, 1); // 闪烁模式常态
break;
}
// 新增:清除信号处理标志,允许处理新信号
signal_processing_ch1 = 0;
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
}
}
void TIM7_IRQHandler(void) // CH2
{
if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET) {
trigger_active_2 = 0;
// 根据当前模式恢复正确状态
switch(h2_state) {
/* case H2_OFF:
Set_XOR_Inputs_2(1, 0);
break;
case H2_ON:
Set_XOR_Inputs_2(1, 1);
break;
*/
case H2_MS_FLASH:
case H2_US_FLASH:
Set_XOR_Inputs_2(0, 1);
break;
}
// 新增:清除信号处理标志,允许处理新信号
signal_processing_ch2 = 0;
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
}
}在进行高频触发时会出现异常的频闪(不规律的可能三分钟出现一次,也有可以一分钟出现多次,异常频闪),找出可能出现这种情况的原因,并给出解决方案
最新发布