在裸奔程序中,循环获取7个通道的AD值并将转换为电阻后逐个打印,串口助手中显示正常,代码如下;
- i=0;
- while (1)
- {
- Change_Channel(i);
- ADS1248_Start(ADC_MODE_SINGLECOV);
- ADS1248_WaitBusy();
- Data=ADS1248_Read();
- R = (Data/8388607.0/8)*2*820+180;
- printf("%5.2f, ",R);
-
- i++;
- if(i==7)
- {
- i=0;
- printf("\n");
- };
-
- }
现将其移植到RTX系统中,启用单任务时运行正常:
- __task void adcTask (void) {
- ADS1248_Init(ADC_GAIN_8|ADC_SPS_20);
- int8_t chanel = 0;
- float R;
- for (;;) {
- int32_t Data;
-
- Data = ADS1248_Channel_Data(chanel);
- R = (Data/8388607.0/8)*2*820+180;
- printf("%5.2f, ", R);
- chanel++;
- if(chanel==7)
- {
- printf("\n");
- chanel=0;
- };
- os_dly_wait(10);
- }
- }
接着将AD转换与打印数据分离实现,启用一个新的任务用于打印AD数据,因此在AD任务中将7个通道的AD值逐个存入float类型数组R中,并在打印任务中打印AD值。结果AD值无法正常显示,数据显示如下图所示,,
请问有人遇到过类似的情况吗?是什么原因造成的?
(补充:测试时发现将SPI的时钟配置修改为70KHz后,AD值将正常显示,,原始SPI时钟频率为140KHz,根据AD数据手册时序要求得到SPI时钟频率的上限为2MHz,所以应该不是SPI的问题,应该只是有所牵连,具体问题出自于哪还望大神们解惑!!)
- __task void printfTask (void) {
-
- for (;;) {
-
- int i;
- for(i=0; i<7; i++)
- {
- printf("%5.2f, ", (chanelDataArray[i]/8388607.0/8)*2*820+180);
- }
- printf("\n");
- os_dly_wait(100);
- }
- }
本帖最后由 Tobey 于 2016-8-20 20:58 编辑
采用直接在ADC任务中将AD值转换为电阻值,然后存储至数组中,接着在打印任务里取出的方式,串口调试助手中显示的AD值显示正常~~也就是说不能在打印任务中进行转换,,,why???
前天刚遇到操作系统中的浮点数运算出错的问题,我是在tqOS上运行出错的,后来改了源码就行了,但是我的错误结果和你的不太一样,我觉得跟我的问题不一样,估计是因为程序设计上的问题,不是操作系统的问题,你可以把完整的程序拿出来看看。
好的,麻烦帮我看看--(我是采用HAL库进行开发的)
RTX配置:
这是main.c文件
- /**
- ******************************************************************************
- * File Name : main.c
- * Description : Main program body
- ******************************************************************************
- *
- * COPYRIGHT(c) 2016 STMicroelectronics
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "stm32f1xx_hal.h"
- #include "spi.h"
- #include "tim.h"
- #include "usart.h"
- #include "gpio.h"
-
- /* USER CODE BEGIN Includes */
- #include <RTL.h>
- #include "ADS1248.h"
- /* USER CODE END Includes */
-
- /* Private variables ---------------------------------------------------------*/
-
- /* USER CODE BEGIN PV */
- /* Private variables ---------------------------------------------------------*/
- OS_TID t_adc; /* assigned task id of task: adcTask */
- OS_TID t_printf; /* assigned task id of task: printfTask */
- OS_TID t_test; /* assigned task id of task: testTask */
- volatile int32_t chanelDataArray[7]; /* AD数据 */
- /* USER CODE END PV */
-
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- void Error_Handler(void);
-
- /* USER CODE BEGIN PFP */
- /* Private function prototypes -----------------------------------------------*/
-
- /* USER CODE END PFP */
-
- /* USER CODE BEGIN 0 */
-
- /**
- * @brief 测试任务.
- * @param None.
- * @note 设置LED1每秒闪烁一次.
- * @retval None
- */
- __task void testTask (void) {
- for (;;) {
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
- os_dly_wait(1000);
- }
- }
-
- /**
- * @brief 打印任务,用于打印串口数据.
- * @param None.
- * @note 当前打印数据仅AD通道数组中的AD数据
- * @retval None
- */
- __task void printfTask (void) {
-
- for (;;) {
-
- int i;
- float R;
- for(i=0; i<7; i++)
- {
- // // R = Ad/Full/Gain*2*Rref+R2
-
- /*当配置APB1的频率为36MHz时,使用下列两行将会造成输出结果不正确*/
- R = chanelDataArray[i]/8388607.0/8*2*810+180;
- printf("%5.2d , %4.2f ;", chanelDataArray[i], R);
-
- /*采用下列方法都显示正常*/
- // printf("%5.2d , %4.2f ;", chanelDataArray[i], chanelDataArray[i]/8388607.0/8.0*2.0*810.0 + 180);
-
- }
- printf("\n");
- os_dly_wait(100);
- }
- }
-
- /**
- * @brief ADC任务.
- * @param None.
- * @note 循环获取7个AD通道的AD值
- * @retval None
- */
- __task void adcTask (void) {
- os_dly_wait(20);
- ADS1248_Init(ADC_GAIN_8|ADC_SPS_20); //初始化 AD1248
- int8_t chanel = 0;
- for (;;) {
- int32_t Data;
-
- Data = ADS1248_Channel_Data(chanel);
- chanelDataArray[chanel] = Data;
- chanel++;
- if(chanel==7)
- {
- chanel=0;
- };
- os_dly_wait(10);
- }
- }
-
- /**
- * @brief 初始化任务.
- * @param None.
- * @note 用于创建任务,当任务都创建完成时,其使命达成自行销毁.
- * @retval None
- */
- __task void initTask (void) {
- t_adc = os_tsk_create(adcTask,1);
- t_printf = os_tsk_create(printfTask,1);
- t_test = os_tsk_create(testTask,1);
- os_tsk_delete_self();
- }
- /* USER CODE END 0 */
-
- int main(void)
- {
-
- /* USER CODE BEGIN 1 */
-
- /* USER CODE END 1 */
-
- /* MCU Configuration----------------------------------------------------------*/
-
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
-
- /* Configure the system clock */
- SystemClock_Config();
-
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_SPI2_Init();
- MX_TIM1_Init();
- MX_TIM2_Init();
- MX_TIM3_Init();
- MX_TIM4_Init();
- MX_USART1_UART_Init();
-
- /* USER CODE BEGIN 2 */
-
- HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_2);
-
- HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_2);
-
- HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_2);
- HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_3);
-
- // 初始化RTX内核并启动初始化任务,此后应用程序将在任务中继续执行
- // os_sys_init(initTask);
- os_sys_init_prio(initTask,3);
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
-
- }
- /* USER CODE END 3 */
-
- }
-
- /** System Clock Configuration
- */
- void SystemClock_Config(void)
- {
-
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
-
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
-
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
-
- HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
-
- HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
-
- /* SysTick_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
- }
-
- /* USER CODE BEGIN 4 */
- int fputc(int ch,FILE *f)
- {
- uint8_t temp[1]={ch};
- HAL_UART_Transmit(&huart1,temp,1,2);
- return ch;
- }
- /* USER CODE END 4 */
-
- /**
- * @brief This function is executed in case of error occurrence.
- * @param None
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler */
- /* User can add his own implementation to report the HAL error return state */
- while(1)
- {
- }
- /* USER CODE END Error_Handler */
- }
-
- #ifdef USE_FULL_ASSERT
-
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t* file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
-
- }
-
- #endif
-
- /**
- * @}
- */
-
- /**
- * @}
- */
-
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
以下是时钟配置:(SPI2采用256分频系数,APB2频率为36MHz时为140KHz,APB2为18MHz时为70KHz)
本帖最后由 Tobey 于 2016-9-1 15:07 编辑
首先假设你的ADS1248芯片的硬件驱动程序都是对的(我就没详细看了),直接看你的主程序,有几个想说的,但不一定是问题所在。
1、printftask中你说“当配置APB2的频率为36MHz时,使用下列两行将会造成输出结果不正确”, 看程序的话你应该用的是SPI2作为通信总线,这样的话APB2是不影响SPI2的速率的,可能是APB2影响了串口1的时钟导致波特率出问题,但是如果你的程序的串口初始化函数里面自适应了APB2的时钟的话那就不是这个问题,而且你后面也说了下一句程序是没问题的。
2、ADS1248_ReToTemp函数没看见定义在哪。
3、你说把APB2的频率改了之后出现问题,我感觉应该是系统问题,我看你在main函数里面初始化了定时器1234,234作为PWM发生器,定时器1做什么了,系统定时器应该是systick不是tim1啊,不明觉厉
4、你的系统开启了时间片轮转,先把时间片轮转的关了,然后把任务的优先级设置为:test任务优先级最低,adc采样任务优先级其次,打印任务优先级最高试试吧。
毕竟不是我在调试,问题的现象我不清楚,不好确定原因所在。
打错了,应该是APB1的频率,测试时没使用ADS1248_ReToTemp函数,所以没贴上,测试时R赋值的就是ADS1248_ReToTemp的参数部分,,tim1我使用来控制电机的,,,
把APB1的频率升高后,ADS1248的初始化部分也会出问题,需要减少一个寄存器的写入操作,,不过初始化时往MUX1中写入0x00倒是也没问题,但是,APB1的频率降低后这些问题就都不见了,,,
输出错误主要就是不稳定,一阵一阵的波动,,
改为抢占式也是一样的结果,根据你说的TIM1的问题,刚刚测试了发现,如果将与TIM1相关的电机任务关闭的话,串口助手中显示的数据是正常的,
只要启动电机任务,串口助手中的数据就炸了~~显示的基本都是通道断开时的数据,偶尔显示正确转换值、、、
这是为什么呢?
前面发的是出现问题时备份的项目程序代码,当前项目的main.c文件是这样的:(最近在测试PID控制,adc任务略乱~~)
- /**
- ******************************************************************************
- * File Name : main.c
- * Description : Main program body
- ******************************************************************************
- *
- * COPYRIGHT(c) 2016 STMicroelectronics
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "stm32f1xx_hal.h"
- #include "spi.h"
- #include "tim.h"
- #include "usart.h"
- #include "gpio.h"
- /* USER CODE BEGIN Includes */
- #include <RTL.h>
- #include "ADS1248.h"
- #include "step_motor_driver.h"
- #include "pid_driver.h"
- /* USER CODE END Includes */
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN PV */
- /* Private variables ---------------------------------------------------------*/
- OS_TID t_adc; /* assigned task id of task: adcTask */
- OS_TID t_printf; /* assigned task id of task: printfTask */
- OS_TID t_motor; /* assigned task id of task: motorTask */
- OS_TID t_test; /* assigned task id of task: testTask */
- volatile uint32_t chanelDataArray[7]; /* AD数据 */
- volatile float chanelTempArray[7]; /* 各通道温度数组 */
- const float chanelDrift[7] = { 0.6, 0.25, -0.3, -0.35, 0, 0, -0.3 };
- static PID PID_Chanel[7];
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- void Error_Handler(void);
- /* USER CODE BEGIN PFP */
- /* Private function prototypes -----------------------------------------------*/
- /* USER CODE END PFP */
- /* USER CODE BEGIN 0 */
- /**
- * @brief 步进电机控制测试任务.
- * @param None.
- * @note 两个静态变量分别用于控制电机步进控制与电机配置控制.
- * @arg openTIM: 0表示中断未开启,1表示中断已开启
- * @arg microStep: 0、1、2、3分别代表细分级数:FULL、HALF、QUARTER、EIGHTH
- * 每次切换细分级数时同时修改电机转动方向。
- * FULL -> 200节拍(一圈) (顺时针旋转)
- * HALF -> 400节拍(一圈) (逆时针旋转)
- * FOUTH -> 800节拍(一圈) (顺时针旋转)
- * EIGTH -> 1600节拍(一圈) (逆时针旋转)
- * @retval None
- */
- __task void motorTask (void) {
- BSP_STEP_MOTOR_Init(); // 初始化电机
- uint8_t openTIM = 1; // 默认初始化时Step为0,此时计时器中断应该为关闭状态,这里为了进行测试设置为1
- uint8_t microStep = 0; // 细分步数标志
- for (;;) {
- if(openTIM == 0 && STEP_MOTOR_Msg.Step > 0) // 当Step>0且计时器处于关闭状态时开启计时器
- {
- HAL_TIM_Base_Start_IT(&htim1);
- openTIM=1;
- }
- if(openTIM == 1 && STEP_MOTOR_Msg.Step == 0) // 当计时器处于开启状态且Step已为0时设置计时器标志位为1
- {
- openTIM = 0;
- os_dly_wait(100);
- switch(microStep)
- {
- case 0: // FULL FORWARD
- STEP_MOTOR_Msg.Dir = FORWARD;
- STEP_MOTOR_Msg.MicroStep = FULL;
- STEP_MOTOR_Msg.Step = 200;
- microStep++;
- break;
- case 1: // HALF REVERSAL
- STEP_MOTOR_Msg.Dir = REVERSAL;
- STEP_MOTOR_Msg.MicroStep = HALF;
- STEP_MOTOR_Msg.Step = 400;
- microStep++;
- break;
- case 2: // QUARTER FORWARD
- STEP_MOTOR_Msg.Dir = FORWARD;
- STEP_MOTOR_Msg.MicroStep = QUARTER;
- STEP_MOTOR_Msg.Step = 800;
- microStep++;
- break;
- case 3: // EIGHTH REVERSAL
- STEP_MOTOR_Msg.Dir = REVERSAL;
- STEP_MOTOR_Msg.MicroStep = EIGHTH;
- STEP_MOTOR_Msg.Step = 1600;
- microStep = 0;
- break;
- default:
- break;
- }
- }
- os_tsk_pass();//上述判断条件语句执行完成后交出CPU控制权
- }
- }
- /**
- * @brief 测试任务.
- * @param None.
- * @note 设置LED1每秒闪烁一次.
- * @retval None
- */
- __task void testTask (void) {
- for (;;) {
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
- os_dly_wait(1000);
- }
- }
- /**
- * @brief 打印任务,用于打印串口数据.
- * @param None.
- * @note 当前仅打印AD值及与其对应的温度值
- * @retval None
- */
- __task void printfTask (void) {
-
- for (;;) {
-
- int i;
- float Temp;
- for(i=0; i<7; i++)
- {
- // R = Ad/Full/Gain*2*Rref+R2
- // R = chanelDataArray[i]/0x7fffff/8*2*810+180;
- Temp = ADS1248_AdToTemp(chanelDataArray[i]);//直接根据AD值查表得到温度值
- printf("%5.2d , %4.2f ;", chanelDataArray[i], Temp);
-
- }
- printf("\n");
- os_dly_wait(100);
- }
- }
- /**
- * @brief ADC及PID测试任务.
- * @param None.
- * @note 循环获取7个AD通道的AD值,并将AD值存储至数组中
- * 根据转换得到的温度值进性PID控制
- * chanel:通道编号
- * PIDSet[7]:标识各通道PID控制时间间隔
- * chanelDataArray[7]:存储各通道AD值
- * chanelTempArray[7]:存储各通道AD值对应的温度值
- * @retval None
- */
- __task void adcTask (void) {
- int i;
- for(i=0; i<7; i++)//PID初始化
- {
- PID_Init(&PID_Chanel[i]);
- //PID配置,设置各通道Kp,Ki,Kd值,SetPoint值应该在设置温度时进性配置,此处用于测试对其进行配置
- PID_SetPoint(&PID_Chanel[i], 40); //设置 PID 调节的目标值
- PID_SetKp(&PID_Chanel[i], 2); //设置 PID 的 Kp 值
- PID_SetKi(&PID_Chanel[i], 0); //设置 PID 的 Ki 值
- PID_SetKd(&PID_Chanel[i], 0); //设置 PID 的 Kd 值
- }
-
- os_dly_wait(17);
- ADS1248_Init(ADC_GAIN_16|ADC_SPS_20); //初始化 AD1248
- int8_t chanel = 0;
- int16_t PIDSet[7] = { 0, 0, 0, 0, 0, 0, 0 };
- for (;;) {
- int32_t Data;
- Data = ADS1248_Channel_Data(chanel);
- chanelTempArray[chanel] = ADS1248_AdToTemp(Data);
-
- if(PIDSet[chanel] == 30) // 间隔指定时间进入一次PID控制
- {
- /*如果当前温度与设定值相差50度,则进入PID控制范围*/
- if( (PID_Chanel[chanel].SetPoint - chanelTempArray[chanel] < 50 && PID_Chanel[chanel].SetPoint - chanelTempArray[chanel] > 0)
- || (PID_Chanel[chanel].SetPoint - chanelTempArray[chanel] > -50 && PID_Chanel[chanel].SetPoint - chanelTempArray[chanel] < 0))
- {
- uint8_t pulse = PID_IncCalc(&PID_Chanel[chanel],chanelTempArray[chanel]);//采用PID增量模式
- printf("puse%d: %d, temp: %f\n",chanel, pulse, chanelTempArray[chanel]);
- PID_IncPWMCtr(chanel, pulse);//增量式PID的PWM控制
- }
- PIDSet[chanel] = 0;
-
- }
-
- chanelDataArray[chanel] = Data;
- PIDSet[chanel]++;
- chanel++;
- if(chanel==7)
- {
- chanel=0;
- };
- os_dly_wait(10);
-
- }
- }
- /**
- * @brief 初始化任务.
- * @param None.
- * @note 用于创建任务,当任务都创建完成时,其使命达成自行销毁.
- * @retval None
- */
- __task void initTask (void) {
- t_adc = os_tsk_create(adcTask,1);
- t_printf = os_tsk_create(printfTask,1);
- t_motor = os_tsk_create(motorTask,1);
- t_test = os_tsk_create(testTask,1);
- os_tsk_delete_self();
- }
- /* USER CODE END 0 */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /* MCU Configuration----------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* Configure the system clock */
- SystemClock_Config();
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_SPI2_Init();
- MX_TIM1_Init();
- MX_TIM2_Init();
- MX_TIM3_Init();
- MX_TIM4_Init();
- MX_USART1_UART_Init();
- /* USER CODE BEGIN 2 */
- HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_2);
- HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_2);
-
- HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_2);
- HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_3);
- // 初始化RTX内核并启动初始化任务,此后应用程序将在任务中继续执行
- // os_sys_init(initTask);
- os_sys_init_prio(initTask,3);
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
- }
- /** System Clock Configuration
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
- HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
- HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
- /* SysTick_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
- }
- /* USER CODE BEGIN 4 */
- int fputc(int ch,FILE *f)
- {
- uint8_t temp[1]={ch};
- HAL_UART_Transmit(&huart1,temp,1,2);
- return ch;
- }
- /* USER CODE END 4 */
- /**
- * @brief This function is executed in case of error occurrence.
- * @param None
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler */
- /* User can add his own implementation to report the HAL error return state */
- while(1)
- {
- }
- /* USER CODE END Error_Handler */
- }
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t* file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif
- /**
- * @}
- */
- /**
- * @}
- */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
TIM1中断处理函数:
- /**
- * @brief This function handles TIM1 update interrupt.
- */
- void TIM1_UP_IRQHandler(void)
- {
- /* USER CODE BEGIN TIM1_UP_IRQn 0 */
- /* USER CODE END TIM1_UP_IRQn 0 */
- HAL_TIM_IRQHandler(&htim1);
- /* USER CODE BEGIN TIM1_UP_IRQn 1 */
- //0-1开关,用于向电机发送脉冲,修改两次引脚电平后,减小节拍数(节拍数用于控制电机转动角度)
- static int CNT = (int)0;
- if(CNT == 1)
- {
- CNT = 0;
- HAL_GPIO_WritePin(STEP_MOTOR_STEP_GPIO_PORT, STEP_MOTOR_STEP_GPIO_PIN, GPIO_PIN_SET);
- STEP_MOTOR_Msg.Step--;
- }
- else
- {
- HAL_GPIO_WritePin(STEP_MOTOR_STEP_GPIO_PORT, STEP_MOTOR_STEP_GPIO_PIN, GPIO_PIN_RESET);
- BSP_STEP_MOTOR_Dir_Set(STEP_MOTOR_Msg.Dir); //设置电机转动方向
- BSP_STEP_MOTOR_MicroStep_Set(STEP_MOTOR_Msg.MicroStep);//设置电机细分数量级
- CNT++;
- }
- if(STEP_MOTOR_Msg.Step<=0)HAL_TIM_Base_Stop_IT(&htim1);//当节拍数为0时关闭定时器
-
- /* USER CODE END TIM1_UP_IRQn 1 */
- }
看不出是什么原因造成的电机线程对打印的影响,其实我还是建议你不要用RTX,网上说RTX的bug比较多,毕竟不开源,有问题难以被反馈和解决,还是用UCOS或者自己写一个操作系统吧。。。。我自己写了一个tqOS也有bug但是我能自己修改不过。。。。
这个已经排除了,,手册上的上限是2MHz左右,140KHz完全没超啊~~
嗯,这是上面要求需要使用RTX的~~RTX在keil v4版本是是开源的,有提供源码的,,,不过我小白一个,不懂怎么找出问题的地方~~
啊,是么,我孤陋寡闻了
,之前用过几次RTX,最大的优点就是不用移植,不用管很多移植上的细节。好吧,你们这个还需要好好弄,信号同步和资源竞争问题你最好液压考虑一下。我之前是遇到过很多次串口资源抢占问题。
你可能是在v5下用的CMSIS_RTOS吧,v5下把RTX经过封装后就没有源码了~~多谢提醒!到时候实在不行就换吧
将任务printfTask略修改一下
int x = chanelDataArray[i]; // 增加这一句,C语言可能需要将定义移至函数的前面
R = x/8388607.0/8*2*810+180;
printf("%5.2d , %4.2f ;", x, R);
// 只要chanelDataArray[i]是整型,基本可以解决打印混乱的问题
// 请不要怀疑RTX