【ACM32G103RCT6开发板测评】tobudOS实现多任务ADC采集
[复制链接]
【目的】使用tobudOS实现多任务采集ADC
【实验器材】ACM32G103RCT6开发板
【开发软件】MDK5.38、TobudOS
【实现步步骤】
1、复制我的tobudOS工程,重命名为ADCtest
2、在APP中根据官方的例程初始化ADC1通道0、通道1。
- /******************************************************************************
- * [url=home.php?mod=space&uid=159083]@brief[/url] : ADC Polling Mode Initialization.
- * @param : none
- * @return: none
- ******************************************************************************/
- void ADC_Init_Polling_Nchannels(void)
- {
- ADC_ChannelConfTypeDef ADC_ChannelConf;
-
- ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_DIV16;
- ADC_Handle.Init.Resolution = ADC_RESOLUTION_12B;
- ADC_Handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- ADC_Handle.Init.ConConvMode = DISABLE;
-
- ADC_Handle.Init.DiscontinuousConvMode = DISABLE;
- ADC_Handle.Init.NbrOfDiscConversion =1;
- ADC_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
- ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;
- ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;
-
- ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;
- ADC_Handle.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;
- ADC_Handle.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;
- ADC_Handle.Init.Oversampling.TriggeredMode =0;
- ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;
- ADC_Handle.Init.ChannelEn = ADC_CHANNEL_0_EN | ADC_CHANNEL_1_EN ;
-
- ADC_Handle.Instance = ADC1;
-
- HAL_ADC_Init(&ADC_Handle);
-
-
-
- ADC_Handle.ChannelNum = 2;
-
-
- ADC_ChannelConf.Channel = ADC_CHANNEL_0;
- ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;
- ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
- ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
-
- ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
- ADC_ChannelConf.Offset = 0;
- ADC_ChannelConf.OffsetSign = 0;
- ADC_ChannelConf.OffsetSaturation = 0;
- HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
-
-
- ADC_ChannelConf.Channel = ADC_CHANNEL_1;
- ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ2;
- ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
- ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
- ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
- ADC_ChannelConf.Offset = 0;
- HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
-
-
- }
为了转换电压值我们还需要获取参考电压值:
- /******************************************************************************
- * @brief : ADC Get The VrefP Value.
- * @param : none
- * @return: VrefP Value
- ******************************************************************************/
- uint32_t ADC_GetVrefP(void)
- {
- ADC_HandleTypeDef ADC_Handle_Vrefp;
- ADC_ChannelConfTypeDef ADC_ChannelConf;
- uint32_t TrimValue_3v, AdcValue_VrefP[1], VrefP,temp;
-
-
- RCC->APB1ENR |= 1<<27;
-
- *(__IO uint32_t*)(0x400070C0) = 0x05;
-
- HAL_SimpleDelay(2000);
-
- ADC_Handle_Vrefp.Init.ClockPrescaler = ADC_CLOCK_DIV16;
- ADC_Handle_Vrefp.Init.Resolution = ADC_RESOLUTION_12B;
- ADC_Handle_Vrefp.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- ADC_Handle_Vrefp.Init.ConConvMode = DISABLE;
-
- ADC_Handle_Vrefp.Init.DiscontinuousConvMode = DISABLE;
- ADC_Handle_Vrefp.Init.NbrOfDiscConversion = 1;
- ADC_Handle_Vrefp.Init.ExternalTrigConv = ADC_SOFTWARE_START;
- ADC_Handle_Vrefp.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- ADC_Handle_Vrefp.Init.DMAMode = ADC_DMAMODE_DISABLE;
- ADC_Handle_Vrefp.Init.OverMode = ADC_OVERMODE_DISABLE;
-
- ADC_Handle_Vrefp.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;
- ADC_Handle_Vrefp.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;
- ADC_Handle_Vrefp.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;
- ADC_Handle_Vrefp.Init.Oversampling.TriggeredMode =0;
- ADC_Handle_Vrefp.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;
- ADC_Handle_Vrefp.Init.ChannelEn = ADC_CHANNEL_VBGR_EN;
-
- ADC_Handle_Vrefp.Instance = ADC1;
-
- HAL_ADC_Init(&ADC_Handle_Vrefp);
-
-
- ADC_Handle_Vrefp.ChannelNum = 1;
-
-
- ADC_ChannelConf.Channel = ADC_CHANNEL_VBGR;
- ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;
- ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
- ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
- ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
- ADC_ChannelConf.Offset = 0;
- HAL_ADC_ConfigChannel(&ADC_Handle_Vrefp,&ADC_ChannelConf);
-
- HAL_ADC_Polling(&ADC_Handle_Vrefp, AdcValue_VrefP, ADC_Handle_Vrefp.ChannelNum, 0);
-
- printfS("The adc convert result : 0x%08x[ %d ], VBGR = %dmV\r\n", AdcValue_VrefP[0], AdcValue_VrefP[0] & 0xFFF, ((AdcValue_VrefP[0] & 0xFFF) * 3300 / 4095));
-
-
- *(__IO uint32_t*)(0x400070C0) &= ~0x05;
-
- TrimValue_3v = *(volatile uint32_t*)(0x00080240);
-
- printfS("The adc 1.2v trim value is : 0x%08x \r\n", TrimValue_3v);
-
- if(((~TrimValue_3v&0xFFFF0000)>>16) == (TrimValue_3v&0x0000FFFF))
- {
- temp = TrimValue_3v & 0xFFF;
-
- VrefP = (uint32_t)(temp * 3000 / (AdcValue_VrefP[0] & 0xFFF));
-
- return VrefP;
- }
- return 0;
- }
我们创建循环触发获取两个通道的ADC程 序
- /******************************************************************************
- * @brief : ADC Polling Mode test.
- * @param : none
- * @return: none
- ******************************************************************************/
- void ADC_Test_Polling_Nchannels(void)
- {
- uint32_t i, VrefP, Voltage;
-
- uint32_t lu32_COM_OK = 0;
-
- printfS("The ADC test ADC_Test_Polling_Nchannels start.");
-
- VrefP = ADC_GetVrefP();
- printfS("The VrefP value is : %d \r\n", VrefP);
-
- ADC_Init_Polling_Nchannels();
-
- while(1)
- {
- for (i = 0; i < BUFFER_LENGTH; i++)
- {
- gadcBuffer[i] = 0;
- }
-
- HAL_ADC_Polling(&ADC_Handle, gadcBuffer, ADC_Handle.ChannelNum, 0);
-
-
- for (i = 0; i < ADC_Handle.ChannelNum; i++)
- {
- printfS("The adc convert result : Channel %d = %d\r\n", gadcBuffer[i]>>16 & 0xFF,gadcBuffer[i]&0xFFF);
- Voltage = (gadcBuffer[i]&0xFFF)*VrefP/4095;
- printfS("The Voltage is: %d mV \r\n", Voltage);
-
- }
- tos_task_delay(1000);
- }
- }
-
创建两个任务,一个用于hello 打印,另一个用于ADC的周期采集打印。
-
-
-
-
- k_task_t task, led_task;
-
- k_stack_t task_stack[1024], task_stack_led[1024];
-
- void test_task(void *Parameter)
- {
- while(1)
- {
- printf("hello tobuandOS\r\n");
- tos_task_delay(1000);
- }
- }
-
- void led_task_entry(void *Parameter)
- {
-
- ADC_Regular_Channel_Test(ADC_Regular_POLLING);
-
-
- }
- /******************************************************************************
- *@brief : main program
- *@param : none
- *@return: none
- ******************************************************************************/
- int main(void)
- {
- uint32_t count=0;
- k_err_t err;
-
- HAL_Init();
- SystemClock_Config();
-
- BSP_UART_Init();
- BSP_LED_Init();
-
- tos_knl_init();
- err = tos_task_create(&task, "task1",test_task,NULL, 2, task_stack,1024,20);
- err = tos_task_create(&led_task, "task_led",led_task_entry,NULL, 2, task_stack_led,1024,20);
- tos_knl_start();
-
- }
实现现象,我们把开发板上的A0与VDD相接,A1与GND相接,串口打印效果如下:
- ====== ACM32G103 MCU is runing ======
- SysCoreClk: 120270000Hz, HCLK:120270000Hz
- PCLK1:60135000Hz, PCLK2:60135000Hz
-
- Firmware compiled on Jan 9 2024 11:14:52
- hello tobuandOS
- The ADC test ADC_Test_Polling_Nchannels start.The adc convert result : 0x001105c2[ 1474 ], VBGR = 1187mV
- The adc 1.2v trim value is : 0xf9b5064a
- The VrefP value is : 3276
- The adc convert result : Channel 0 = 4095
- The Voltage is: 3276 mV
- The adc convert result : Channel 1 = 0
- The Voltage is: 0 mV
- hello tobuandOS
- The adc convert result : Channel 0 = 4095
- The Voltage is: 3276 mV
- The adc convert result : Channel 1 = 0
- The Voltage is: 0 mV
- hello tobuandOS
【讨论】不知道是总线频率的问题还是怎么样,我使用主频为180MHz时初始化ADC是失败的,但是用官方的例程跑为120MHz是可以的。还需要分析一下ADC时钟。
|