| @@ -55,7 +55,6 @@ void SVC_Handler(void); | |||
| void DebugMon_Handler(void); | |||
| void PendSV_Handler(void); | |||
| void SysTick_Handler(void); | |||
| void TIM1_UP_TIM10_IRQHandler(void); | |||
| void TIM2_IRQHandler(void); | |||
| void USART1_IRQHandler(void); | |||
| void DMA2_Stream2_IRQHandler(void); | |||
| @@ -39,6 +39,7 @@ uint8_t ArrFlag = 0; /* | |||
| float Acc; /* 加速度 */ | |||
| int32_t AllPulseCNT = 0; | |||
| int32_t BaseCNT = 0; | |||
| int32_t CNT_Only[10] = {0}; | |||
| uint8_t AccITCount = 0; | |||
| @@ -74,29 +75,34 @@ void PVD_Init(void); | |||
| /* USER CODE BEGIN 0 */ | |||
| /* 任务优先级 */ | |||
| #define TASK_Y1Direction 4 | |||
| #define TASK_PulseStart 3 | |||
| #define TASK_DirOutput 4 | |||
| #define TASK_Y1Direction 6 | |||
| #define TASK_PulseStart 5 | |||
| #define TASK_DirOutput 6 | |||
| #define TASK_PulseGetCount 6 | |||
| /* 任务堆栈大小 */ | |||
| #define Task_Y1Direction_SIZE 256 | |||
| #define Task_PulseStart_SIZE 512 | |||
| #define Task_DirOutput_SIZE 256 | |||
| #define Task_PulseGetCount_SIZE 256 | |||
| /* 任务控制块 */ | |||
| OS_TCB Y1Direction_Tsk; | |||
| OS_TCB PulseStart_Tsk; | |||
| OS_TCB DirOutput_Tsk; | |||
| OS_TCB PulseGetCount_Tsk; | |||
| /* 任务栈 */ | |||
| CPU_STK Task_Y1Direction_STK[Task_Y1Direction_SIZE]; | |||
| CPU_STK Task_PulseStart_STK[Task_PulseStart_SIZE]; | |||
| CPU_STK Task_DirOutput_STK[Task_DirOutput_SIZE]; | |||
| CPU_STK Task_PulseGetCount_STK[Task_PulseGetCount_SIZE]; | |||
| /* 任务函数 */ | |||
| void Y1Direction(void *p_arg); | |||
| void PulseStartTsk(void *p_arg); | |||
| void DirOutput(void *p_arg); | |||
| void PulseGetCount(void *p_arg); | |||
| /* USER CODE END 0 */ | |||
| @@ -194,7 +200,21 @@ int main(void) | |||
| (OS_TICK )0, | |||
| (void * )0, | |||
| (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, | |||
| (OS_ERR * )&err); | |||
| (OS_ERR * )&err); | |||
| /* 任务4 */ | |||
| OSTaskCreate((OS_TCB * )&PulseGetCount_Tsk, | |||
| (CPU_CHAR* )"PulseGetCount_Tsk", | |||
| (OS_TASK_PTR)PulseGetCount, | |||
| (void * )0, | |||
| (OS_PRIO )TASK_PulseGetCount, | |||
| (CPU_STK * )&Task_PulseGetCount_STK[0], | |||
| (CPU_STK_SIZE)Task_PulseGetCount_SIZE/10, | |||
| (CPU_STK_SIZE)Task_PulseGetCount_SIZE, | |||
| (OS_MSG_QTY)0, | |||
| (OS_TICK )0, | |||
| (void * )0, | |||
| (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, | |||
| (OS_ERR * )&err); | |||
| /* 掉电数据读取 */ | |||
| ModbusLoadSRAM(); | |||
| @@ -252,7 +272,7 @@ void SystemClock_Config(void) | |||
| RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; | |||
| RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; | |||
| RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; | |||
| RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; | |||
| RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; | |||
| if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) | |||
| { | |||
| @@ -263,7 +283,7 @@ void SystemClock_Config(void) | |||
| /* USER CODE BEGIN 4 */ | |||
| /** | |||
| * @brief 任务1,获取总脉冲数, 脉冲加减速 | |||
| * @brief 任务1, 脉冲加减速 | |||
| * @return 无 | |||
| */ | |||
| void Y1Direction(void *p_arg) | |||
| @@ -308,10 +328,6 @@ void Y1Direction(void *p_arg) | |||
| } | |||
| } | |||
| } | |||
| AllPulseCNT = BaseCNT + TIM2->CNT; | |||
| CountSave(); | |||
| OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍 | |||
| } | |||
| } | |||
| @@ -333,7 +349,7 @@ void PulseStartTsk(void *p_arg) | |||
| PLSROptionLoad(); //读取脉冲基础设置 | |||
| if(Register_L[0x3000] == 0x01 && EN == 1) | |||
| { | |||
| { | |||
| SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency); | |||
| PulseStart(); | |||
| EN = 0; | |||
| @@ -394,6 +410,7 @@ void DirOutput(void *p_arg) | |||
| while(1) | |||
| { | |||
| /* 根据当前的方向和输出的方向的端口进行输出的配置 */ | |||
| if (Options.DirPost == 0) | |||
| { | |||
| if (Options.Dir == 1) | |||
| @@ -438,13 +455,59 @@ void DirOutput(void *p_arg) | |||
| HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_RESET); | |||
| } | |||
| } | |||
| /* 预留时间给其他任务 */ | |||
| OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍 | |||
| } | |||
| } | |||
| /** | |||
| * @brief 任务4,脉冲计数 | |||
| * @return 无 | |||
| */ | |||
| void PulseGetCount(void *p_arg) | |||
| { | |||
| p_arg = p_arg; | |||
| OS_ERR err; | |||
| while(1) | |||
| { | |||
| /* 根据当前脉冲的方向设置输出的方向 */ | |||
| if(PulseOutput[NowPulse].PulseCount < 0) | |||
| { | |||
| Options.Dir = 1; | |||
| } | |||
| else | |||
| { | |||
| Options.Dir = 0; | |||
| } | |||
| // if(Options.Dir == 0) | |||
| // { | |||
| // AllPulseCNT = BaseCNT + TIM2->CNT; | |||
| // } | |||
| // else if(Options.Dir == 1) | |||
| // { | |||
| // AllPulseCNT = BaseCNT - TIM2->CNT; | |||
| // } | |||
| if(TIM2->CNT != 0) | |||
| { | |||
| if (Options.Dir == 1) | |||
| { | |||
| CNT_Only[NowPulse] = 0 - (TIM2->CNT); | |||
| } | |||
| else if (Options.Dir == 0) | |||
| { | |||
| CNT_Only[NowPulse] = TIM2->CNT; | |||
| } | |||
| } | |||
| AllPulseCNT = CNT_Only[0] + CNT_Only[1] + CNT_Only[2] + CNT_Only[3] + | |||
| CNT_Only[4] + CNT_Only[5] + CNT_Only[6] + CNT_Only[7] + | |||
| CNT_Only[8] + CNT_Only[9]; | |||
| CountSave(); | |||
| OSTimeDly(10, OS_OPT_TIME_DLY, &err); | |||
| } | |||
| } | |||
| /* USER CODE END 4 */ | |||
| @@ -61,7 +61,6 @@ | |||
| /* External variables --------------------------------------------------------*/ | |||
| extern TIM_HandleTypeDef htim2; | |||
| extern TIM_HandleTypeDef htim10; | |||
| extern DMA_HandleTypeDef hdma_usart1_rx; | |||
| extern DMA_HandleTypeDef hdma_usart1_tx; | |||
| extern UART_HandleTypeDef huart1; | |||
| @@ -207,20 +206,6 @@ void SysTick_Handler(void) | |||
| /* please refer to the startup file (startup_stm32f4xx.s). */ | |||
| /******************************************************************************/ | |||
| /** | |||
| * @brief This function handles TIM1 update interrupt and TIM10 global interrupt. | |||
| */ | |||
| void TIM1_UP_TIM10_IRQHandler(void) | |||
| { | |||
| /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */ | |||
| /* USER CODE END TIM1_UP_TIM10_IRQn 0 */ | |||
| HAL_TIM_IRQHandler(&htim10); | |||
| /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */ | |||
| /* USER CODE END TIM1_UP_TIM10_IRQn 1 */ | |||
| } | |||
| /** | |||
| * @brief This function handles TIM2 global interrupt. | |||
| */ | |||
| @@ -234,7 +219,7 @@ void TIM2_IRQHandler(void) | |||
| HAL_TIM_PWM_Stop_IT(&htim10,TIM_CHANNEL_1); /* 停止PWM输出 */ | |||
| PulseNum ++; /* 脉冲段数增加 */ | |||
| BaseCNT += TIM2->ARR; | |||
| if (Options.RunMod == 0) | |||
| { | |||
| @@ -250,7 +235,8 @@ void TIM2_IRQHandler(void) | |||
| { | |||
| NowPulse = PulseOutput[NowPulse].NextPulse - 1; /* 进入下一段脉冲 */ | |||
| } | |||
| BaseCNT += PulseOutput[PrePulse].PulseCount; | |||
| /* 准备加减速 */ | |||
| if(PulseOutput[PrePulse].Frequency <= PulseOutput[NowPulse].Frequency) | |||
| { | |||
| @@ -271,6 +257,7 @@ void TIM2_IRQHandler(void) | |||
| { | |||
| PulseCount = 0; | |||
| ArrFlag = 0; | |||
| BaseCNT += PulseOutput[NowPulse].PulseCount; | |||
| HAL_TIM_PWM_Stop_IT(&htim10,TIM_CHANNEL_1); /* 停止PWM输出 */ | |||
| } | |||
| } | |||
| @@ -280,10 +280,6 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) | |||
| /* USER CODE END TIM10_MspInit 0 */ | |||
| /* TIM10 clock enable */ | |||
| __HAL_RCC_TIM10_CLK_ENABLE(); | |||
| /* TIM10 interrupt Init */ | |||
| HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0); | |||
| HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); | |||
| /* USER CODE BEGIN TIM10_MspInit 1 */ | |||
| /* USER CODE END TIM10_MspInit 1 */ | |||
| @@ -441,9 +437,6 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) | |||
| /* USER CODE END TIM10_MspDeInit 0 */ | |||
| /* Peripheral clock disable */ | |||
| __HAL_RCC_TIM10_CLK_DISABLE(); | |||
| /* TIM10 interrupt Deinit */ | |||
| HAL_NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn); | |||
| /* USER CODE BEGIN TIM10_MspDeInit 1 */ | |||
| /* USER CODE END TIM10_MspDeInit 1 */ | |||
| @@ -63,7 +63,7 @@ void MX_USART1_UART_Init(void) | |||
| /* USER CODE END USART1_Init 1 */ | |||
| huart1.Instance = USART1; | |||
| huart1.Init.BaudRate = 19200; | |||
| huart1.Init.BaudRate = 9600; | |||
| huart1.Init.WordLength = UART_WORDLENGTH_9B; | |||
| huart1.Init.StopBits = UART_STOPBITS_1; | |||
| huart1.Init.Parity = UART_PARITY_ODD; | |||
| @@ -20,15 +20,15 @@ | |||
| <LeaveTargetRunning>_ 0</LeaveTargetRunning> | |||
| </StLinkDriver> | |||
| <DebugChecksum> | |||
| <Checksum>3456179106</Checksum> | |||
| <Checksum>2527891484</Checksum> | |||
| </DebugChecksum> | |||
| <Exceptions> | |||
| <StopOnUncaught>_ 0</StopOnUncaught> | |||
| <StopOnThrow>_ 0</StopOnThrow> | |||
| </Exceptions> | |||
| <Disassembly> | |||
| <MixedMode>1</MixedMode> | |||
| <InstrCount>0</InstrCount> | |||
| <MixedMode>1</MixedMode> | |||
| </Disassembly> | |||
| <CodeCoverage> | |||
| <Enabled>0</Enabled> | |||
| @@ -74,8 +74,9 @@ | |||
| <watch_formats> | |||
| <Fmt0>{W}1:AccITCount 3 0</Fmt0> | |||
| <Fmt1>{W}1:AllPulseCNT 3 0</Fmt1> | |||
| <Fmt2>{W}1:c 4 0</Fmt2> | |||
| <Fmt3>{W}1:datCount 3 0</Fmt3> | |||
| <Fmt2>{W}1:DatL 3 0</Fmt2> | |||
| <Fmt3>{W}1:c 4 0</Fmt3> | |||
| <Fmt4>{W}1:datCount 3 0</Fmt4> | |||
| </watch_formats> | |||
| <Trace2> | |||
| <Enabled>0</Enabled> | |||
| @@ -30,8 +30,8 @@ int32_t PulseCount = 0; | |||
| */ | |||
| void SetFrequency(uint8_t SentPost, uint32_t Frequency) | |||
| { | |||
| Frequency_Change_PSC_And_ARR(Frequency, &psc, &arr); | |||
| printf("Fre=%d,",Frequency); | |||
| CalculatePSCARR(Frequency, 72000000, 65535, &psc, &arr); | |||
| //printf("Fre=%d,",Frequency); | |||
| switch(SentPost) | |||
| { | |||
| case 0: TIM10->ARR = arr, TIM10->PSC = psc, TIM10->CCR1 = arr / 2; break; | |||
| @@ -80,7 +80,14 @@ void PulseBaseInit(uint8_t StartPulse, uint8_t PulseMod, int32_t MAX_Pulse) | |||
| */ | |||
| void PulseStart(void) | |||
| { | |||
| TIM2->ARR = PulseOutput[NowPulse].PulseCount; | |||
| if(PulseOutput[NowPulse].PulseCount >= 0) | |||
| { | |||
| TIM2->ARR = PulseOutput[NowPulse].PulseCount; | |||
| } | |||
| else | |||
| { | |||
| TIM2->ARR = - PulseOutput[NowPulse].PulseCount; | |||
| } | |||
| switch(Options.SentPost) | |||
| { | |||
| @@ -178,7 +185,15 @@ void SetNextPulse(void) | |||
| if(Options.RunMod == 0) /* 如果是相对模式 */ | |||
| { | |||
| TIM2->ARR = PulseOutput[NowPulse].PulseCount; | |||
| if(PulseOutput[NowPulse].PulseCount > 0) | |||
| { | |||
| TIM2->ARR = PulseOutput[NowPulse].PulseCount; | |||
| } | |||
| else | |||
| { | |||
| TIM2->ARR = - PulseOutput[NowPulse].PulseCount; | |||
| } | |||
| } | |||
| else /* 如果是绝对模式 */ | |||
| { | |||
| @@ -281,8 +296,8 @@ void CountSave(void) | |||
| memcpy(&temp_Count, &AllPulseCNT, 4); | |||
| DatH = temp_Count / 0xffff; | |||
| DatL = temp_Count % 0xffff; | |||
| DatH = (temp_Count >> 16); | |||
| DatL = (temp_Count & 0x0000ffff); | |||
| Register_H[0x2001] = (DatH >> 8); | |||
| Register_L[0x2001] = (DatH & 0x00ff); | |||
| Register_H[0x2000] = (DatL >> 8); | |||
| @@ -1,7 +1,7 @@ | |||
| #include "PSCARR.h" | |||
| uint16_t psc; | |||
| uint16_t arr; | |||
| uint16_t psc = 0; | |||
| uint16_t arr = 0; | |||
| const unsigned short ARRPSC[1098][2] = {\ | |||
| 0x465,0xFA00,0x240,0xF424,0x177,0xFA00,0x120,0xF424,0xE1,0xFA00,0xC0,0xF424,0x161,0x71D2,0x90,0xF424,0x7D,0xFA00,0x78,0xEA60,\ | |||
| @@ -138,3 +138,57 @@ void Frequency_Change_PSC_And_ARR(uint32_t Frequency, uint16_t* psc, uint16_t* a | |||
| } | |||
| } | |||
| /** | |||
| * @brief 计算PSC和ARR值以产生指定频率 | |||
| * @param[in] desired_freq 期望的频率(Hz) | |||
| * @param[in] timer_clk 定时器时钟频率(Hz), 通常为72MHz | |||
| * @param[in] max_arr ARR的最大值(通常是16位定时器的65535) | |||
| * @param[out] psc 预分频器值 | |||
| * @param[out] arr 自动重装载值 | |||
| * @return 0-成功, 1-频率太低, 2-频率太高 | |||
| */ | |||
| uint8_t CalculatePSCARR(uint32_t desired_freq, uint32_t timer_clk, uint16_t max_arr, | |||
| uint16_t *psc, uint16_t *arr) { | |||
| uint32_t psc_candidate, arr_candidate; | |||
| uint32_t clock_div; | |||
| if (desired_freq == 0) { | |||
| return 1; // 频率太低 | |||
| } | |||
| // 计算所需的总分频系数 | |||
| clock_div = timer_clk / desired_freq; | |||
| if (clock_div == 0) { | |||
| return 2; // 频率太高 | |||
| } | |||
| // 初始尝试: 将ARR设为最大值,计算PSC | |||
| psc_candidate = (clock_div - 1) / max_arr; | |||
| arr_candidate = clock_div / (psc_candidate + 1) - 1; | |||
| // 如果PSC太大,则减少PSC并增加ARR | |||
| if (psc_candidate > max_arr) { | |||
| psc_candidate = max_arr; | |||
| arr_candidate = clock_div / (psc_candidate + 1) - 1; | |||
| if (arr_candidate > max_arr) { | |||
| return 2; // 频率太高 | |||
| } | |||
| } | |||
| // 确保结果在有效范围内 | |||
| if (psc_candidate > max_arr || arr_candidate > max_arr) { | |||
| return 2; // 频率太高 | |||
| } | |||
| if (arr_candidate == 0) { | |||
| return 1; // 频率太低 | |||
| } | |||
| *psc = (uint16_t)psc_candidate; | |||
| *arr = (uint16_t)arr_candidate; | |||
| return 0; // 成功 | |||
| } | |||
| @@ -2,6 +2,7 @@ | |||
| #define __PSCARR_H__ | |||
| #include "stdint.h" | |||
| #include "math.h" | |||
| extern const unsigned short ARRPSC[1098][2]; | |||
| @@ -10,5 +11,7 @@ extern uint16_t psc; | |||
| extern uint16_t arr; | |||
| void Frequency_Change_PSC_And_ARR(uint32_t Frequency, uint16_t* psc, uint16_t* arr); /* 输出要配置的PSC和ARR */ | |||
| uint8_t CalculatePSCARR(uint32_t desired_freq, uint32_t timer_clk, uint16_t max_arr, | |||
| uint16_t *psc, uint16_t *arr); | |||
| #endif | |||
| @@ -83,7 +83,6 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |||
| NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 | |||
| NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |||
| NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false | |||
| NVIC.TIM1_UP_TIM10_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | |||
| NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | |||
| NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | |||
| NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |||
| @@ -166,7 +165,8 @@ RCC.AHBFreq_Value=72000000 | |||
| RCC.APB1CLKDivider=RCC_HCLK_DIV2 | |||
| RCC.APB1Freq_Value=36000000 | |||
| RCC.APB1TimFreq_Value=72000000 | |||
| RCC.APB2Freq_Value=72000000 | |||
| RCC.APB2CLKDivider=RCC_HCLK_DIV2 | |||
| RCC.APB2Freq_Value=36000000 | |||
| RCC.APB2TimFreq_Value=72000000 | |||
| RCC.CortexFreq_Value=72000000 | |||
| RCC.EthernetFreq_Value=72000000 | |||
| @@ -176,7 +176,7 @@ RCC.HCLKFreq_Value=72000000 | |||
| RCC.HSE_VALUE=12000000 | |||
| RCC.HSI_VALUE=16000000 | |||
| RCC.I2SClocksFreq_Value=192000000 | |||
| RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQCLKFreq_Value,PLLSourceVirtual,RCC_RTC_Clock_Source,RCC_RTC_Clock_SourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S | |||
| RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQCLKFreq_Value,PLLSourceVirtual,RCC_RTC_Clock_Source,RCC_RTC_Clock_SourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S | |||
| RCC.LSE_VALUE=32768 | |||
| RCC.LSI_VALUE=32000 | |||
| RCC.MCO2PinFreq_Value=72000000 | |||
| @@ -217,7 +217,7 @@ TIM13.Channel=TIM_CHANNEL_1 | |||
| TIM13.IPParameters=Channel | |||
| TIM14.Channel=TIM_CHANNEL_1 | |||
| TIM14.IPParameters=Channel | |||
| USART1.BaudRate=19200 | |||
| USART1.BaudRate=9600 | |||
| USART1.IPParameters=VirtualMode,BaudRate,Parity,WordLength | |||
| USART1.Parity=PARITY_ODD | |||
| USART1.VirtualMode=VM_ASYNC | |||