D - Circular Sequence

本文介绍了一种算法,用于从给定的圆周DNA序列中找到字典序最小的线性序列。通过将圆周序列展开为两倍长度的线性序列,并比较所有可能的起始位置来实现。

Some DNA sequences exist in circular forms as in the following figure, which shows a circular sequence“CGAGTCAGCT”, that is, the last symbol “T” in
“CGAGTCAGCT” is connected to the first symbol “C”. We always read a circular sequence in the clockwise direction.Since it is not easy to store a circular sequence in a computer as it is, we decided to store it as a linear sequence.However, there can be many linear sequences that are obtained from a circular sequence by cutting any place of the circular sequence.

Hence, we also decided to store the linear sequence that is lexicographically smallest among all linear sequences that can be obtained from a circular sequence. Your task is to find the lexicographically smallest sequence
from a given circular sequence. For the example in the figure, the lexicographically smallest sequence is “AGCTCGAGTC”. If there are two or more linear sequences that are lexicographically smallest, you are to find any one of them (in fact, they are the same).

Input
The input consists of T test cases. The number of test cases T is given on the first line of the input file. Each test case takes one line containing a circular sequence that is written as an arbitrary linear sequence. Since the circular sequences are DNA sequences, only four symbols, ‘A’, ‘C’, ‘G’ and ‘T’, are allowed. Each sequence has length at least 2 and at most 100.

Output
Print exactly one line for each test case. The line is to contain the lexicographically smallest sequence
for the test case.

Sample Input
2
CGAGTCAGCT
CTCC

Sample Output
AGCTCGAGTC
CCCT

#include <stdio.h>  
#include <string.h>  
const int maxn = 205;  
char str[maxn], t[maxn];  
int main ( )  
{  
    int T, n;  
    scanf ( "%d", &T );  
    while ( T -- )  
    {  
        int i;
        scanf ( "%s", str );  
        n = strlen ( str );  
        strcpy ( t, str ); 
        strcat ( str, t );//str=2*t
        for (i = 1; i < n; i ++ )  
        {  
            if ( strncmp ( t, str+i, n ) > 0 )
            //str 从第1项开始往后到第N个   与t整体(N项)相比  t>str 时 if成立                        N 限制对比的长度                                  
            {
                strncpy ( t, str+i, n );// 如果成立的话 就把str的值赋给t,          t被全部替换 
            }

        }  
        puts ( t );  
    }  
    return 0;  
} 
所以以下buck稳压代码该怎么改#include “stm32f4xx.h” #include “delay.h” #include “oled.h” #include “stdio.h” #include “stdlib.h” #include “arm_math.h” #include “pid.h” #include “./adc/bsp_adc.h” #include “tim.h” #include “bsp_GeneralTim.h” float pid_out; volatile uint8_t adc_data_ready = 0; volatile uint8_t tim_update_flag ; volatile uint32_t last_adc_value = 0; float Vout_actual = 0.0f; float Target = 12.0f; // 目标输出电压 float voltage1; uint32_t time = 0; // ms 计时变量 // 全局PID控制器 PID_Controller pid; extern __IO uint16_t ADC_ConvertedValue[RHEOSTAT_NOFCHANEL]; extern uint16_t TIM1_Impluse ;//高级定时器占空比 int main(void) { OLED_Init(); Adc_Init(); TIM_Init(); GENERAL_TIM_Init(); // 输入20V→输出15V:kp=0.3-0.6, ki=0.05-0.2, kd=0.01-0.05 //输入35V→输出20V:kp=0.2-0.4, ki=0.02-0.1, kd=0.005-0.02 pid.kp = 0.5f; // 从较小值开始调试 pid.ki = 0.1f; pid.kd = 0.01f; pid.max_output = 100.0f; pid.min_output = 0.0f; pid.integral = 0; pid.prev_error = 0; while(1) { if (adc_data_ready) { // 计算电压 voltage1 = last_adc_value * 3.3f*0.000244140625; Vout_actual = voltage1; adc_data_ready = 0; } // if (tim_update_flag) // { // // // 使用PID计算 // pid_out = pid_control(&pid, Target, Vout_actual); // // 安全更新PWM (限制在0-8400) // TIM1_Impluse = pid_out * 84; // 0-100% -> 0-8400 // TIM1->CCR1 = TIM1_Impluse; //// // 重置标志 // tim_update_flag = 0; // // // } // a=pid_control (5 , 0.25, 0 ,Target ,Vout_actual); // ADC_Read(); // float six = 6; // char str[40]; // sprintf(str,“Vout_actual = %.3f”,Vout_actual); // OLED_ShowString(WORD_WIDTH0,WORD_HIGH1,(u8 )str,WORD_SIZE); // OLED_Refresh_Gram(); // delay_us(100); static char display_buffer[2][40]; snprintf(display_buffer[0], 40, “Vout: %.2fV”, Vout_actual); while(1) { if ( time == 2000 ) / 2000 * 1 ms = 2s 时间到 */ { time = 0; } } snprintf(display_buffer[1], 40, “Duty: %d”, TIM1->CCR1); OLED_ShowString(0, 1, (u8*)display_buffer[0], 12); OLED_ShowString(0, 18, (u8*)display_buffer[1], 12); OLED_Refresh_Gram(); } } #include “stm32f4xx_it.h” #include “oled.h” #include <math.h> #include “./adc/bsp_adc.h” #include “pid.h” #include “bsp_GeneralTim.h” extern uint16_t ADC_ConvertedValue[RHEOSTAT_NOFCHANEL]; extern float voltage1; extern float pid_out; extern float Vout_actual; extern uint16_t TIM1_Impluse ;//高级定时器占空比 extern volatile uint8_t adc_data_ready ; extern volatile uint8_t tim_update_flag ; extern volatile uint32_t last_adc_value; extern volatile uint32_t time; void TIM1_UP_TIM10_IRQHandler(void) { if(TIM_GetITStatus(TIM1,TIM_IT_Update) == SET) { if(adc_data_ready) { float v = ADC_ReadVoltage(); // 处理电压… adc_data_ready = 0; } TIM_ClearITPendingBit(TIM1, TIM_IT_Update); } } void DMA2_Stream0_IRQHandler(void) { // 处理传输完成中断 if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) { // 先读取数据再清除标志 last_adc_value = ADC_ConvertedValue[0]; adc_data_ready = 1; // 清除标志的正确方法 DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); } // 处理半传输中断 if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0)) { DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0); } // 处理传输错误中断 if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TEIF0)) { DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TEIF0); // 这里可以添加错误处理代码 } } void GENERAL_TIM_IRQHandler (void) { if ( TIM_GetITStatus( GENERAL_TIM, TIM_IT_Update) != RESET ) { time++; TIM_ClearITPendingBit(GENERAL_TIM , TIM_FLAG_Update); } } void NMI_Handler(void) { } void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) {} } void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs / while (1) {} } void BusFault_Handler(void) { / Go to infinite loop when Bus Fault exception occurs / while (1) {} } void UsageFault_Handler(void) { / Go to infinite loop when Usage Fault exception occurs */ while (1) {} } void DebugMon_Handler(void) { } void SVC_Handler(void) { } void PendSV_Handler(void) { } void SysTick_Handler(void) { } #include “tim.h” uint16_t TIM1_Impluse = 4200;//预设占空比 float z = 0; const uint32_t spwm[400] = { 4200,4265,4331,4397,4463,4529,4595,4660,4726,4791,4857,4922,4987,5051,5116,5180, 5244,5308,5371,5434,5497,5560,5622,5684,5746,5807,5868,5928,5988,6047,6106,6165, 6223,6280,6337,6394,6450,6505,6560,6615,6668,6721,6774,6826,6877,6927,6977,7026, 7075,7122,7169,7216,7261,7306,7350,7393,7436,7477,7518,7558,7597,7636,7673,7710, 7746,7781,7815,7848,7880,7911,7942,7971,8000,8027,8054,8080,8105,8128,8151,8173, 8194,8214,8233,8251,8268,8283,8298,8312,8325,8337,8348,8358,8366,8374,8381,8387, 8391,8395,8397,8399,8400,8399,8397,8395,8391,8387,8381,8374,8366,8358,8348,8337, 8325,8312,8298,8283,8268,8251,8233,8214,8194,8173,8151,8128,8105,8080,8054,8027, 8000,7971,7942,7911,7880,7848,7815,7781,7746,7710,7673,7636,7597,7558,7518,7477, 7436,7393,7350,7306,7261,7216,7169,7122,7075,7026,6977,6927,6877,6826,6774,6721, 6668,6615,6560,6505,6450,6394,6337,6280,6223,6165,6106,6047,5988,5928,5868,5807, 5746,5684,5622,5560,5497,5434,5371,5308,5244,5180,5116,5051,4987,4922,4857,4791, 4726,4660,4595,4529,4463,4397,4331,4265,4200,4134,4068,4002,3936,3870,3804,3739, 3673,3608,3542,3477,3412,3348,3283,3219,3155,3091,3028,2965,2902,2839,2777,2715, 2653,2592,2531,2471,2411,2352,2293,2234,2176,2119,2062,2005,1949,1894,1839,1784, 1731,1678,1625,1573,1522,1472,1422,1373,1324,1277,1230,1183,1138,1093,1049,1006, 963,922,881,841,802,763,726,689,653,618,584,551,519,488,457,428, 399,372,345,319,294,271,248,226,205,185,166,148,131,116,101,87, 74,62,51,41,33,25,18,12,8,4,2,0,0,0,2,4, 8,12,18,25,33,41,51,62,74,87,101,116,131,148,166,185, 205,226,248,271,294,319,345,372,399,428,457,488,519,551,584,618, 653,689,726,763,802,841,881,922,963,1006,1049,1093,1138,1183,1230,1277, 1324,1373,1422,1472,1522,1573,1625,1678,1731,1784,1839,1894,1949,2005,2062,2119, 2176,2234,2293,2352,2411,2471,2531,2592,2653,2715,2777,2839,2902,2965,3028,3091, 3155,3219,3283,3348,3412,3477,3542,3608,3673,3739,3804,3870,3936,4002,4068,4134 }; //TIM1的GPIO static void TIM_GPIO_Config(void) { GPIO_InitTypeDef TIM_GPIO_InitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);//开钟 /-----------------------------PA8,PA7------------------------------------/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1);//引脚复用 主 PA8,PA7 GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM1);//引脚复用 补 TIM_GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; //模拟模式GPIO_Mode_AN/F TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8; //引脚 TIM_GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //高速 TIM_GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽 TIM_GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOA, &TIM_GPIO_InitStruct); //写入 TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; GPIO_Init(GPIOA, &TIM_GPIO_InitStruct); /-----------------------------------------------------------------------/ /-----------------------------PA9,PB14------------------------------------/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_TIM1);//引脚复用 主 GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_TIM1);//引脚复用 补 TIM_GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; //模拟模式GPIO_Mode_AN/F TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //引脚 TIM_GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //高速 TIM_GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽 TIM_GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOA, &TIM_GPIO_InitStruct); //写入 TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; GPIO_Init(GPIOB, &TIM_GPIO_InitStruct); /-----------------------------------------------------------------------/ /-----------------------------PA10,PB1------------------------------------/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_TIM1);//引脚复用 主 GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM1);//引脚复用 补 TIM_GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; //模拟模式GPIO_Mode_AN/F TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //引脚 TIM_GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //高速 TIM_GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽 TIM_GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOA, &TIM_GPIO_InitStruct); //写入 TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &TIM_GPIO_InitStruct); /-----------------------------------------------------------------------/ // TIM_GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; //模拟模式 pa6死刹 // TIM_GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; //引脚 // TIM_GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //高速 // TIM_GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽 // TIM_GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //浮空 // GPIO_Init(GPIOA, &TIM_GPIO_InitStruct); //写入 } //TIM1 static void TIM_A1_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStruct; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);///使能时钟 //168MHZ->20kHZ 主频/(计数+1)*(预分频系数+1) //168MHz/8 * 1050 = 20khz /-----------------------------基本结构体------------------------------------/ TIM_TimeBaseInitStructure.TIM_Period = (8400-1); //自动重装载值 TIM_TimeBaseInitStructure.TIM_Prescaler=(1-1); //定时器分频 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //1分频 TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; //不需要重复计数 TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure); //初始化TIM /-----------------------------基本结构体------------------------------------/ /-----------------------------输出比较------------------------------------/ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //pwm模式选择 TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; ///使能输出通道 TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable; //使能互补通道 TIM_OCInitStruct.TIM_Pulse = TIM1_Impluse; //预设占空比 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //PWM1和2中的CH和CCR之间值的大小(多用pwm1的模式1) TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High; //当使用了刹车功能时,两路PWM1和2都会被强制禁止,进而输出我们配置的的空闲先状态 TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set; //刹车时输出通道的状态 Set = high TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset; //刹车时互补通道的状态 Reset = low TIM_OC1Init(TIM1, &TIM_OCInitStruct); //使能通道1 TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); /* 使能通道1重载 */ TIM_OCInitStruct.TIM_Pulse = TIM1_Impluse; TIM_OC2Init(TIM1, &TIM_OCInitStruct); TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable); TIM_OCInitStruct.TIM_Pulse = TIM1_Impluse; TIM_OC3Init(TIM1, &TIM_OCInitStruct); TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable); /-----------------------------输出比较------------------------------------/ /-----------------------------死区刹车------------------------------------/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; //开启死区 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; //开启1空闲状态 TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; //不同的锁定级别 (看BDTR寄存器) TIM_BDTRInitStructure.TIM_DeadTime = 20; //刹车时间,(看BDTR寄存器中的DTG[7:0]) //11转换成二进制为0000 1011 死区时间看[7;5]位,此处为000 TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; //允许刹车 //BKIN 测到低电平 比较信号禁止 TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; //高极性 TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能(刹车输入无效) TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); //写入 /-----------------------------死区刹车------------------------------------/ TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); //允许定时器更新中断 | TIM_IT_Trigger TIM_Cmd(TIM1,ENABLE); //使能定时器 TIM_CtrlPWMOutputs(TIM1, ENABLE); //主动输出使能 } static void TIM_A1_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; /-----------------------------中断------------------------------------/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //分组 NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn; //定时器1中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断 NVIC_Init(&NVIC_InitStructure); //写入 /-----------------------------中断------------------------------------/ } void TIM_Init(void) { TIM_A1_NVIC_Config(); TIM_GPIO_Config(); TIM_A1_Mode_Config(); } #include “./adc/bsp_adc.h” __IO uint16_t ADC_ConvertedValue[RHEOSTAT_NOFCHANEL]={0}; extern volatile uint8_t adc_data_ready ; volatile uint8_t current_buffer = 0; static void ADC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /=通道1==/ // 使能 GPIO 时钟 RCC_AHB1PeriphClockCmd(ADC_GPIO_CLK1,ENABLE); // 配置 IO GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //不上拉不下拉 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(ADC_GPIO_PORT1, &GPIO_InitStructure); } void ADC_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; // 1. 使能 DMA 时钟 RCC_AHB1PeriphClockCmd(ADC_DMA_CLK, ENABLE); // 2. 配置 DMA 参数 DMA_InitStructure.DMA_Channel = ADC_DMA_CHANNEL; // DMA 通道 0 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)ADC_ConvertedValue ; // ADC 数据寄存器地址 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // 内存缓冲区地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // 外设到内存 DMA_InitStructure.DMA_BufferSize = RHEOSTAT_NOFCHANEL; // 缓冲区大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据大小:半字(16位) DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存数据大小:半字(16位) DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 高优先级 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; // 禁用 FIFO 模式 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; // FIFO 阈值 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 内存突发传输:单次 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 外设突发传输:单次 // 3. 初始化 DMA DMA_Init(ADC_DMA_STREAM, &DMA_InitStructure); // 4. 使能 DMA 中断(传输完成、传输错误) DMA_ITConfig(ADC_DMA_STREAM, DMA_IT_TC | DMA_IT_TE | DMA_IT_HT, ENABLE); // 5. 使能 DMA 流 DMA_Cmd(ADC_DMA_STREAM, ENABLE); } void ADC_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; // 1. 使能 ADC 时钟 RCC_APB2PeriphClockCmd(ADC_CLK, ENABLE); // 2. 配置 ADC 通用参数 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; // ADC 时钟分频:PCLK2/4 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; // DMA 访问模式 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; // 采样延迟 ADC_CommonInit(&ADC_CommonInitStructure); // 3. 配置 ADC 参数 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // 12位分辨率 ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 扫描模式使能 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换模式 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // 无外部触发 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // 外部触发源 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐 ADC_InitStructure.ADC_NbrOfConversion = RHEOSTAT_NOFCHANEL ; // 转换通道数 ADC_Init(ADC_, &ADC_InitStructure); // 4. 配置 ADC 通道(通道4,PA4) ADC_RegularChannelConfig(ADC_, ADC_Channel_4, 1, ADC_SampleTime_84Cycles); // 5. 使能 ADC DMA ADC_DMACmd(ADC_, ENABLE); // 6. 使能 ADC ADC_Cmd(ADC_, ENABLE); // 7. 启动 ADC 转换 ADC_SoftwareStartConv(ADC_); } static void ADC_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } float ADC_ReadVoltage(void); void Adc_Init(void) { ADC_GPIO_Config(); ADC_DMA_Config(); ADC_Config(); ADC_NVIC_Config(); } // 在bsp_adc.c中实现电压读取 float ADC_ReadVoltage(void) { static uint8_t initialized = 0; if(!initialized) { Adc_Init(); initialized = 1; } // 直接读取ADC原始值 uint16_t raw_value = ADC_ConvertedValue[0]; // 转换为电压值 (假设参考电压3.3V) const float VREF = 3.3f; // STM32F4参考电压 const float zhi = 0.000244140625; // 12位ADC最大值 return (raw_value * VREF) / zhi; } #ifndef __BSP_ADC_H #define __BSP_ADC_H #include “stm32f4xx.h” #define RHEOSTAT_NOFCHANEL 1 /=通道1 IO==/ // ADC IO宏定义 #define ADC_GPIO_PORT1 GPIOA #define ADC_GPIO_PIN1 GPIO_Pin_4 #define ADC_GPIO_CLK1 RCC_AHB1Periph_GPIOA #define ADC_CHANNEL1 ADC_Channel_4 // ADC 序号宏定义 #define ADC_ ADC1 #define ADC_CLK RCC_APB2Periph_ADC1 // ADC DR寄存器宏定义,ADC转换后的数字值则存放在这里 #define RHEOSTAT_ADC_DR_ADDR ((u32)ADC1+0x4c) // ADC DMA 通道宏定义,这里我们使用DMA传输 // DMA 配置 #define ADC_DMA_CLK RCC_AHB1Periph_DMA2 #define ADC_DMA_CHANNEL DMA_Channel_0 #define ADC_DMA_STREAM DMA2_Stream0 void Adc_Init(void); float ADC_ReadVoltage(void); #endif /* __BSP_ADC_H */ #include “pid.h” float pid_control(PID_Controller* pid, float setpoint, float input) { // 计算当前误差 float error = setpoint - input; // 比例项 float p_term = pid->kp * error; // 积分项(带抗饱和) pid->integral += error; // 积分限幅 if(pid->integral > pid->max_output) pid->integral = pid->max_output; else if(pid->integral < pid->min_output) pid->integral = pid->min_output; float i_term = pid->ki * pid->integral; // 微分项(标准实现) float d_term = pid->kd * (error - pid->prev_error); // PID输出 float output = p_term + i_term + d_term; // 输出限幅 if(output > pid->max_output) output = pid->max_output; else if(output < pid->min_output) output = pid->min_output; // 更新误差历史 pid->prev_error = error; return output; } #ifndef __BSP_GENERALTIME_H #define __BSP_GENERALTIME_H #include “stm32f4xx.h” /**通用定时器TIM参数定义,只限TIM2、3、4、5/ // 当需要哪个定时器的时候,只需要把下面的宏定义改成1即可 #define GENERAL_TIM2 1 #define GENERAL_TIM3 0 #define GENERAL_TIM4 0 #define GENERAL_TIM5 0 #if GENERAL_TIM2 #define GENERAL_TIM TIM2 #define GENERAL_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define GENERAL_TIM_CLK RCC_APB1Periph_TIM2 #define GENERAL_TIM_Period (1000-1) #define GENERAL_TIM_Prescaler 71 #define GENERAL_TIM_IRQ TIM2_IRQn #define GENERAL_TIM_IRQHandler TIM2_IRQHandler #elif GENERAL_TIM3 #define GENERAL_TIM TIM3 #define GENERAL_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define GENERAL_TIM_CLK RCC_APB1Periph_TIM3 #define GENERAL_TIM_Period (1000-1) #define GENERAL_TIM_Prescaler 71 #define GENERAL_TIM_IRQ TIM3_IRQn #define GENERAL_TIM_IRQHandler TIM3_IRQHandler #elif GENERAL_TIM4 #define GENERAL_TIM TIM4 #define GENERAL_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define GENERAL_TIM_CLK RCC_APB1Periph_TIM4 #define GENERAL_TIM_Period (1000-1) #define GENERAL_TIM_Prescaler 71 #define GENERAL_TIM_IRQ TIM4_IRQn #define GENERAL_TIM_IRQHandler TIM4_IRQHandler #elif GENERAL_TIM5 #define GENERAL_TIM TIM5 #define GENERAL_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define GENERAL_TIM_CLK RCC_APB1Periph_TIM5 #define GENERAL_TIM_Period (1000-1) #define GENERAL_TIM_Prescaler 71 #define GENERAL_TIM_IRQ TIM5_IRQn #define GENERAL_TIM_IRQHandler TIM5_IRQHandler #endif /函数声明******/ void GENERAL_TIM_Init(void); #endif /* __BSP_GENERALTIME_H */
最新发布
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值