宏定义偷懒型set,get

本文介绍了C语言预处理器中的一些高级用法,如使用##操作符连接标识符和#操作符将参数转换为字符串等。通过具体示例展示了如何利用这些特性来简化代码并提高编程效率。
之前看到有这么一个写法
#define DEF_SET_GET(varType,varName,funName)          \
private : varType varName;                             \
public : void set##funName(const varType varName);      \
public : const varType get##funName(void)  ;


太偷懒了=。=、、我居然不晓得有这种用法。##表示把funName与set相连成为一个新的变量。

例如:

#define getName(test) s##test
char *student = "wang er";
printf(getName(tudent));

这里就相当于直接打印了student。前提是这个student要被定义过。


类似于##的还有#号能将传入的参数转化成字符串

#define PRINT( n ) printf( "token" #n " = %d\n", game##n )
int token9 = 9;
int game9 = 99;
PRINT(9);

这个会打印 

token9 = 99;


其实还有#@能把参数转化成字符。不过只有在Windows下能用。也就不多说了。新技能get√

#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); } }在进行高频触发时会出现异常的频闪(不规律的可能三分钟出现一次,也有可以一分钟出现多次,异常频闪),找出可能出现这种情况的原因,并给出解决方案
最新发布
09-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值