打印
[DemoCode下载]

PWM下的ADC采样

[复制链接]
892|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhuomuniao110|  楼主 | 2019-5-26 22:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/******************************************************************************
* [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. ***/




使用特权

评论回复
沙发
zhuomuniao110|  楼主 | 2019-5-26 22:44 | 只看该作者
这个就是两者结合的参考例子,非常棒,新唐这个例子提供,比PIC单片机强多了。

使用特权

评论回复
板凳
zhuomuniao110|  楼主 | 2019-5-26 22:45 | 只看该作者
很符合中国人需求,哈哈。

使用特权

评论回复
地板
21mengnan| | 2019-5-27 19:19 | 只看该作者
这个有什么现实意义

使用特权

评论回复
5
equivalent| | 2019-5-29 20:38 | 只看该作者
没太明白这是准备干什么

使用特权

评论回复
6
稳稳の幸福| | 2019-5-29 22:31 | 只看该作者
看懂了,是根据ADC设置PWM占空比。

使用特权

评论回复
7
稳稳の幸福| | 2019-5-29 22:32 | 只看该作者
PWMA->CMR3 = (u32Data * PWMA->CNR3) / 4096;
看这个是ADC的结果作为一个参数给占空比了

使用特权

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

本版积分规则

206

主题

3358

帖子

10

粉丝