1087|0

7183

帖子

11

TA的资源

版主

楼主
 

【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_CLK分频选择
  • 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; //DMA选择
  • 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; //ADC1
  • HAL_ADC_Init(&ADC_Handle);
  • /* The total adc regular channels number */
  • ADC_Handle.ChannelNum = 2;
  • /* Add adc channels */
  • 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_DIFFERENTIAL_ENDED ; //单端/差分模式
  • //offset config
  • ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE; //modeString[0].number; //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;
  • //PMU CLK Enable
  • RCC->APB1ENR |= 1<<27;
  • //VBG1P2
  • *(__IO uint32_t*)(0x400070C0) = 0x05;
  • HAL_SimpleDelay(2000);
  • ADC_Handle_Vrefp.Init.ClockPrescaler = ADC_CLOCK_DIV16; //ADC_CLK分频选择
  • 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; //DMA选择
  • 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);
  • /* The total adc regular channels number */
  • ADC_Handle_Vrefp.ChannelNum = 1;
  • /* Add adc channels */
  • 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));
  • //VBG1P2
  • *(__IO uint32_t*)(0x400070C0) &= ~0x05;
  • TrimValue_3v = *(volatile uint32_t*)(0x00080240); //Read the 1.2v trim value in 3.0v vrefp.
  • 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的周期采集打印。

  • #include "main.h"
  • #include "app.h"
  • #include "tos_k.h"
  • 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时钟。

点赞 关注(1)
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
ADI 有奖直播报名中~
直播时间:3月27日(周四) 上午10:00-11:30
直播主题:易于驱动SAR型ADC的原理、优点及应用介绍
好礼等你拿~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 12

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表