打印
[技术问答]

ADC的PWM怎么解释

[复制链接]
1637|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xuanhuanzi|  楼主 | 2018-9-28 14:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ADC, PWM, TE, ck, ni
/******************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V0.10
* $Revision: 2 $
* $Date: 14/01/28 11:43a $
* [url=home.php?mod=space&uid=247401]@brief[/url]    ADC and PWM sample for M051 learning board
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "M051Series.h"
#include "lcd_driver.h"

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Enable ADC and PWM23 clock */
    CLK->APBCLK = CLK_APBCLK_PWM23_EN_Msk | CLK_APBCLK_ADC_EN_Msk;

    /* ADC clock source is 22.1184MHz, set divider to (3 + 1), ADC clock is 22.1184/4 MHz */
    CLK->CLKDIV |= (3 << CLK_CLKDIV_ADC_N_Pos);

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and CycylesPerUs automatically. */
    SystemCoreClockUpdate();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set P4.3 to PWM3 function */
    SYS->P4_MFP = SYS_MFP_P43_PWM3;
    /* Set P1.0 to AIN0 function */
    SYS->P1_MFP = SYS_MFP_P10_AIN0;

    /* Disable digital input path of analog pin AIN0 to prevent leakage */
    P1->OFFD |= 1 << GPIO_OFFD_OFFD_Pos;

    /* Lock protected registers */
    SYS_LockReg();
}


void PWM_Init(void)
{
    /* Set PWM 3 clock prescale to 60, and divider to 1*/
    PWMA->PPR = 60 << PWM_PPR_CP23_Pos;
    PWMA->CSR = PWM_CLK_DIV_1 << PWM_CSR_CSR3_Pos;

    /* Enable PWM3 and set to auto-reload mode.
       Configure PWM mode before setting CNR, CMR. Otherwise CNR will be reset */
    PWMA->PCR = PWM_PCR_CH3EN_Msk | PWM_PCR_CH3MOD_Msk;
    /* PWM 3 frequency = HCLK / (prescale * divider * (CNR + 1))
       PWM 3 duty ratio = (CMR + 1) / (CNR + 1) */
    PWMA->CNR3 = 1843 - 1;
    PWMA->CMR3 = 1833 - 1;

    /* Enable PWM3 Output */
    PWMA->POE = PWM_POE_PWM3_Msk;

}

void ADC_Init(void)
{
    /* Set to convert ADC channel 0 */
    ADC->ADCHER = 0x1;
    /* Enable the ADC converter */
    ADC->ADCR = ADC_ADCR_ADEN_Msk;

}

/* Main function  */
int main(void)
{
    uint32_t u32Data, u32Sum, u32Count;
    char adc_value[20];

    /* Init System, IP clock and multi-function I/O
       In the end of SYS_Init() will issue SYS_LockReg()
       to lock protected register. If user want to write
       protected register, please issue SYS_UnlockReg()
       to unlock protected register if necessary */
    SYS_Init();

    /* Initial LCD panel. SPI clock and interface is configured in this function. */
    LCD_Init();
    /* Clear LCD screen. Do this before turn back light on */
    LCD_ClearScreen();
    /* Enable LCD back light */
    LCD_EnableBackLight();
    /* Show messages on LCD */
    LCD_Print(0, "ADC_PWM");
    LCD_Print(1, "Sample code");
    LCD_Print(2, "ADC Value:");

    /* Init PWM channel 3 */
    PWM_Init();

    /* Init ADC to get the value of variable resistor */
    ADC_Init();

    u32Count = 0;
    u32Sum = 0;

    while(1)
    {
        /* Start convert */
        ADC_START_CONV(ADC);

        /* Waiting for convert complete */
        while(ADC_IS_BUSY(ADC));

        /* Read the result from ADC */
        u32Data = ADC->ADDR[0] & ADC_ADDR_RSLT_Msk;

        /* Determine the sum */
        u32Sum += u32Data;
        u32Count++;
        if(u32Count == 128)
        {
            /* Determine the average */
            u32Data = u32Sum / 128;
            /* Update the average ADC conversion result to LCD */
            sprintf(adc_value, "          %4d", u32Data);
            LCD_Print(3, adc_value);
            /* Adjust the duty cycle of PWM3 according to the average ADC value. */
            PWMA->CMR3 = (u32Data * PWMA->CNR3) / 4096;
            /* Reset count and sum */
            u32Count = 0;
            u32Sum = 0;
        }
    }
}

/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/




沙发
xuanhuanzi|  楼主 | 2018-9-28 14:17 | 只看该作者
看到了这个例子,不知道啥意思,请大神解释一下这个是什么应用。

使用特权

评论回复
板凳
gaoyang9992006| | 2018-9-28 14:27 | 只看该作者
看while里的注释啊。是先测128次的ADC,然后求平均值,将平均值作为参数传递给PWM作为占空比参数。
用ADC的结果调整PWM。
这样就可以ADC那边用一个电位器调节来控制PWM输出。

使用特权

评论回复
地板
wahahaheihei| | 2018-9-28 19:42 | 只看该作者
楼主大师总结的很好,如果是ADC检测,那么必然要动起来才好测出来,用电位器是很好的一个方式。

使用特权

评论回复
5
wanduzi| | 2018-9-28 20:48 | 只看该作者
看不懂的英文,请用谷歌翻译。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

176

主题

2236

帖子

3

粉丝