• CMT2380F32模块开发17-ADC例程


    外部的模拟信号需要转变成数字信号才能由MCU进一步处理。内部集成了一个12位高精度、高转换速率的逐次逼近型模数转换器(SAR ADC)模块。

    1M SPS 转换速度;
    12 路转换通道:9 个引脚通道、内置温度传感器、内置 1.2v 基准电压、1/3 电源电压;
    4 种参考源:电源电压、ExRef 引脚、内置 1.5v 参考电压、内置 2.5v 参考电压;
    ADC 的电压输入范围:0~Vref;
    3 种转换模式:单次转换、连续转换、累加转换;
    软件可配置 ADC 的转换速率;
    内置信号放大器,可转换高阻信号;
    支持片内外设自动触发ADC转换,有效降低芯片功耗并提高转换的实时性。

    ADC 框图

    ADC 转换速度与 ADC 参考电压及 VCC 电压相关,最高转换速度如下表所示: 

    开发板的配置为最后一个,也就是理论上转换速度可以达到1M。 

    例程就是adc的几种转换模式,单次,连续,累加,外部触发,然后在有查询和中断两种,一个8个例程,这里就比较典型的连续和外部触发讲解一下,其他的步骤在文档里有详细的说明,可以对照代码查看。

    adc_scan_polling_sw连续触发,查询模式

    1. Gpio_SetAnalog(3, 2, TRUE); // AIN2
    2. Gpio_SetAnalog(3, 3, TRUE); // AIN3
    3. Gpio_SetAnalog(3, 4, TRUE); // AIN4
    4. Adc_Enable();
    5. M0P_BGR->CR_f.BGR_EN = 0x1u; // BGR必须使能
    6. M0P_BGR->CR_f.TS_EN = 0x1u;
    7. delay100us(1);
    8. stcAdcCfg.enAdcOpMode = AdcScanMode; //扫描采样模式
    9. stcAdcCfg.enAdcClkSel = AdcClkSysTDiv8;
    10. stcAdcCfg.enAdcSampTimeSel = AdcSampTime4Clk;
    11. stcAdcCfg.enAdcRefVolSel = RefVolSelAVDD;
    12. stcAdcCfg.bAdcInBufEn = FALSE;
    13. stcAdcCfg.enAdcTrig0Sel = AdcTrigDisable;
    14. stcAdcCfg.enAdcTrig1Sel = AdcTrigDisable;
    15. Adc_Init(&stcAdcCfg);
    16. stcAdcScanCfg.u8AdcScanModeCh = ADC_SCAN_CH2_EN | ADC_SCAN_CH3_EN | ADC_SCAN_CH4_EN;
    17. stcAdcScanCfg.u8AdcSampCnt = 0x6;
    18. Adc_ConfigScanMode(&stcAdcCfg, &stcAdcScanCfg);
    19. while (1) {
    20. Adc_Start();
    21. while (FALSE != Adc_PollBusyState())
    22. ;
    23. for (u8Channel = 0; u8Channel < 8; u8Channel++) {
    24. Adc_GetScanResult(u8Channel, &u16ScanResult[u8Channel]);
    25. if ((1 << u8Channel) & stcAdcScanCfg.u8AdcScanModeCh) {
    26. printf("CH: %d is enabled, AdcVal: 0x%X\n", u8Channel, u16ScanResult[u8Channel]);
    27. } else {
    28. printf("CH: %d is disabled, AdcVal: 0x%X\n", u8Channel, u16ScanResult[u8Channel]);
    29. }
    30. }
    31. delay1ms(1000);
    32. Adc_Init(&stcAdcCfg);
    33. Adc_ConfigScanMode(&stcAdcCfg, &stcAdcScanCfg);
    34. }

    配置P32,P33,P34为adc,并配置u8AdcScanModeCh设置扫描通道。然后Adc_Start()开始转换。

    查询转换结束Adc_PollBusyState(),读取转换结果Adc_GetScanResult(u8Channel, &u16ScanResult[u8Channel]);

    adc_uart_polling_sw串口触发

    1. stcAdcCfg.enAdcOpMode = AdcNormalMode; //单次采样模式
    2. stcAdcCfg.enAdcClkSel = AdcClkSysTDiv1;
    3. stcAdcCfg.enAdcSampTimeSel = AdcSampTime4Clk;
    4. stcAdcCfg.enAdcRefVolSel = RefVolSelExtern1;
    5. stcAdcCfg.bAdcInBufEn = FALSE;
    6. stcAdcCfg.u32AdcRegHighThd = 0x0fffu;
    7. stcAdcCfg.u32AdcRegLowThd = 0u;
    8. stcAdcCfg.enAdcTrig0Sel = AdcTrigUart1;
    9. Adc_Init(&stcAdcCfg);
    10. M0P_ADC->CR1_f.REGCMP = 1;
    11. stcAdcNormCfg.enAdcNormModeCh = AdcExInputCH4;
    12. stcAdcNormCfg.bAdcResultAccEn = FALSE;
    13. Adc_ConfigNormMode(&stcAdcCfg, &stcAdcNormCfg);
    14. stcUartIrqCb.pfnRxIrqCb = RxIntCallback;
    15. stcUartIrqCb.pfnTxIrqCb = TxIntCallback;
    16. stcUartIrqCb.pfnRxErrIrqCb = ErrIntCallback;
    17. stcConfig.pstcIrqCb = &stcUartIrqCb;
    18. stcConfig.bTouchNvic = TRUE;
    19. stcConfig.enRunMode = UartMode1; //测试项,更改此处来转换4种模式测试
    20. stcMulti.enMulti_mode = UartNormal; //测试项,更改此处来转换多主机模式,mode2/3才有多主机模式
    21. enTb8 = Data;
    22. Uart_SetMMDOrCk(UARTCH1, enTb8);
    23. stcConfig.pstcMultiMode = &stcMulti;
    24. stcBaud.bDbaud = 0u; //双倍波特率功能
    25. stcBaud.u32Baud = 9600u; //更新波特率位置
    26. stcBaud.u8Mode = UartMode1; //计算波特率需要模式参数
    27. pclk = Clk_GetPClkFreq();
    28. timer = Uart_SetBaudRate(UARTCH1, pclk, &stcBaud);
    29. stcBtConfig.enMD = BtMode2;
    30. stcBtConfig.enCT = BtTimer;
    31. Bt_Init(TIM1, &stcBtConfig); //调用basetimer1设置函数产生波特率
    32. Bt_ARRSet(TIM1, timer);
    33. Bt_Cnt16Set(TIM1, timer);
    34. Bt_Run(TIM1);
    35. Uart_Init(UARTCH1, &stcConfig);
    36. Uart_EnableIrq(UARTCH1, UartRxIrq);
    37. Uart_ClrStatus(UARTCH1, UartRxFull);
    38. Uart_EnableFunc(UARTCH1, UartRx);
    39. while (1) {
    40. while (FALSE == M0P_ADC->IFR_f.REG_INTF)
    41. ;
    42. M0P_ADC->ICLR_f.REG_INTC = 0u;
    43. Adc_GetResult(&u16AdcResult);
    44. Adc_ClrAccResult();
    45. Gpio_SetIO(2, 3, 1);
    46. delay1ms(200);
    47. Gpio_SetIO(2, 3, 0);
    48. u32RxData[0] = '0';
    49. u32RxData[1] = 'x';
    50. if ((u16AdcResult >> 12) > 9) {
    51. u32RxData[2] = (u16AdcResult >> 12) - 10 + 'A';
    52. } else {
    53. u32RxData[2] = (u16AdcResult >> 12) + '0';
    54. }
    55. if (((u16AdcResult >> 8) & 0xF) > 9) {
    56. u32RxData[3] = ((u16AdcResult >> 8) & 0xF) - 10 + 'A';
    57. } else {
    58. u32RxData[3] = ((u16AdcResult >> 8) & 0xF) + '0';
    59. }
    60. if (((u16AdcResult >> 4) & 0xF) > 9) {
    61. u32RxData[4] = ((u16AdcResult >> 4) & 0xF) - 10 + 'A';
    62. } else {
    63. u32RxData[4] = ((u16AdcResult >> 4) & 0xF) + '0';
    64. }
    65. if (((u16AdcResult)&0xF) > 9) {
    66. u32RxData[5] = ((u16AdcResult)&0xF) - 10 + 'A';
    67. } else {
    68. u32RxData[5] = ((u16AdcResult)&0xF) + '0';
    69. }
    70. u32RxData[6] = '\n';
    71. for (u8TxCnt = 0; u8TxCnt < 7; u8TxCnt++) {
    72. Uart_SendData(UARTCH1, u32RxData[u8TxCnt]);
    73. }
    74. }

    外部触发意思就是当你设置的外部触发中断时,自动开始进行转换,比如例程中设置的    stcAdcCfg.enAdcTrig0Sel = AdcTrigUart1;串口1触发,就是串口1产生中断就会开始adc转换,所以需要同时配置uart1中断。Uart_EnableIrq(UARTCH1, UartRxIrq);,当产生接收中断时开始转换。

  • 相关阅读:
    五三想休息,今天还学习,图解二叉树的层序遍历BFS(广度优先)模板,附面试题题解
    十、【图框工具组】
    GPT learning
    【Unity3D】选中物体描边特效
    分库分表真的适合你的系统吗?聊聊分库分表和NewSQL如何选择
    在Red Hat 8环境下安装Gradle
    复盘:智能座舱系列文六- 它的3种交互方式之显式交互(语音以及显示)
    oauth2单点登录集成
    130.Impala基准测试
    【算法】递归思维
  • 原文地址:https://blog.csdn.net/andylauren/article/details/126378202