en-us--EC_MS51_ADC_PWM_V1.00.zip
(1.12 MB)
大家猜猜这是怎么用的?
是不是弄一个分压电位器,旋钮,转动起来就调节了PWM,是不是很爽。
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* [url=home.php?mod=space&uid=895143]@version[/url] V1.00
* [url=home.php?mod=space&uid=247401]@brief[/url] This example code uses MS51 PWM to output 10 KHz waveform with 0~100% duty according to 0~3V ADC conversion.
*
* SPDX-License-Identifier: Apache-2.0
* [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2022 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "MS51_8K.h"
/*---------------------------------------------------------------------------------------------------------*/
/* Define */
/*---------------------------------------------------------------------------------------------------------*/
/* main-loop switch-case state */
#define IDLE_STATE 0
#define ADC_UPDATE_STATE 1
/**
* PWM frequency = FPWM / {(PWM0PH, PWM0PL) + 1}
* 10kHz = 24MHz / {(PWM0PH, PWM0PL) + 1}
* (PWM0PH, PWM0PL) = 2399(0x95F)
*/
#define PWM_FREQ 0x95F
#define ROUNDING(x) (2x-(int)(x))
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
bit g_bADC_Flag = 0;
unsigned int xdata u32_ADCdataAIN;
double i64_ADCdataConvert;
/*---------------------------------------------------------------------------------------------------------*/
/* Functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief ADC interrupt service routine
*
* @param[in] None
*
* [url=home.php?mod=space&uid=266161]@return[/url] None
*
* [url=home.php?mod=space&uid=1543424]@Details[/url] Get ADC conversion result.
*/
void ADC_ISR(void) interrupt 11
{
_push_(SFRS);
clr_ADCCON0_ADCF;//Clear ADC interrupt flag
u32_ADCdataAIN = ADCRH << 4;
u32_ADCdataAIN |= ADCRL;
g_bADC_Flag = 1;
_pop_(SFRS);
}
/**
* @brief Initialize the PWM module with specified configurations. It could be clock source, PWM channel and frequency.
* The default duty cycle is 50%.
*
* @param[in] None
*
* @return None
*
* @details None
*/
void PWM0_Init(void)
{
/* Define PWM0 clock source and divider. */
PWM0_ClockSource(PWM_FSYS, 1);
/* Setting PWM0 channel 2 */
ENABLE_PWM0_CH2_P10_OUTPUT;
P10_PUSHPULL_MODE;
PWM0_ConfigOutputChannel(2, Independent, EdgeAligned, PWM_FREQ, 50);
PWM0_RUN();
}
/**
* @brief Update PWM duty cycle.
*
* @param[in] u16PWM0Duty Set PWM default duty cycle. The range is 0%~100%
*
* @return None
*
* @details The formula is:
* PWM duty cycle = PWM duty register / (PWM period register + 1)
* -> PWM duty register = PWM duty cycle * (PWM period register + 1)
*/
void PWM0_Reload(unsigned int u16PWM0Duty)
{
/* Reload PWM duty */
unsigned int u16PWM0DutyCycleTemp = 0;
u16PWM0DutyCycleTemp = ((PWM_FREQ + 1) / 100) * u16PWM0Duty;
PWM2H = u16PWM0DutyCycleTemp >> 8;
PWM2L = u16PWM0DutyCycleTemp;
set_PWMCON0_LOAD;
}
/**
* @brief Initialize the ADC module with specified configurations and start ADC convert.
*
* @param[in] None
*
* @return None
*
* @details None
*/
void ADC_Convert(void)
{
/*Enable channel 5 */
ENABLE_ADC_CH5;
ADCCON1 |= 0x30; /* clock divider */
ADCCON2 |= 0x0E; /* AQT time */
AUXR1 |= SET_BIT4; /* ADC clock low speed */
clr_ADCCON0_ADCF;
set_ADCCON0_ADCS;
/* Enable ADC interrupt */
set_IE_EADC;
}
void main(void)
{
unsigned char state = IDLE_STATE;
/* FSYS = 24MHz */
MODIFY_HIRC(HIRC_24);
PWM0_Init();
ENABLE_GLOBAL_INTERRUPT;
while (1)
{
switch (state)
{
case IDLE_STATE:
default:
/* Enable channel 5 */
ADC_Convert();
state = ADC_UPDATE_STATE;
break;
case ADC_UPDATE_STATE:
if (g_bADC_Flag == 1)
{
g_bADC_Flag = 0;
i64_ADCdataConvert = u32_ADCdataAIN;
i64_ADCdataConvert = i64_ADCdataConvert * 100 / 4095;
/* Integer value */
i64_ADCdataConvert = (2 * i64_ADCdataConvert - (int)(i64_ADCdataConvert));
PWM0_Reload((unsigned int)i64_ADCdataConvert);
DISABLE_ADC;
state = IDLE_STATE;
}
break;
}
}
}
|