/*
pwm 输出是P2.2
说明:此程序完成了方案2 的第二部分 每隔10s 改变电压1v 3v 5v
因为我实测过用AD反馈的话,采来了的电压非线性问题很严重,不好调整,不如通过实测输出1v 3v 5v 时的pwm值固定下来,来的准确。
当然要是想做ad反馈的话,程序中也有ad程序 改改就可以用。
*/
//******************************************************************************
#include "msp430g2553.h"
#define PWM_DUTY_MAX 256 //设定占空比最大值 最小值
#define PWM_DUTY_MIN 0
#define PWM_1V 53 //这里根据自己电路参数调整
#define PWM_3V 130
#define PWM_5V 202
#define PWM_PER 256 //PWM初始化时 设置 pwm 周期 12MHZ/PWM_PER
#define PWM_DUTY PWM_1V //PWM初始化 设置 初始 占空比
void SysCtlClockInit(void);
void AD_Init(void);
void TIMERA_Init(void);
void PWMDA1_Config(void);
void PWM_Duty_Set(unsigned char duty);
unsigned int dutya=0;
unsigned int AD_Value[16];
unsigned int AD_sum=0;
unsigned int AD_averge_value=0;
unsigned char AD_Times;
float AD_average_voltage=0;
unsigned int _10ms_times;
int Pwm_duty=PWM_DUTY;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
SysCtlClockInit();
//AD_Init(); //AD 不做反馈就不用了
TIMERA_Init();
PWMDA1_Config();
P1DIR|=BIT0;
_EINT();
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
for (;;)
{
if(_10ms_times==1000) //10ms *1000 =10s
{
PWM_Duty_Set(PWM_3V);
}
else if(_10ms_times==2000)
{
PWM_Duty_Set(PWM_5V);
}
else if(_10ms_times==3000)
{
PWM_Duty_Set(PWM_1V);
_10ms_times=0;
}
}
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
AD_Value[AD_Times]=ADC10MEM; //用来记录ad采样值 调试时观察
AD_sum=AD_sum+ADC10MEM;
AD_Times++;
if(AD_Times==16)
{
AD_Times=0;
AD_averge_value=AD_sum>>4; //相当于AD_sum/16
AD_average_voltage=AD_averge_value/1024.0*3.6;
AD_sum=0;
}
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += 15000; // 12mhz /8 分频
_10ms_times++; //作为10ms 中断计数器用
P1OUT^=BIT0;
}
void PWMDA1_Config(void)
{
// TimerA Config
TA1CTL = TASSEL_2 + MC_1 + ID_0; // smclk 设置为12mhz
TA1CCR0 = PWM_PER; //pwm周期
TA1CCR1 = PWM_DUTY; //pwm占空比
TA1CCTL1 = OUTMOD_7;
P2SEL |= BIT2; //pwm 输出IO
P2DIR |= BIT2;
}
void PWM_Duty_Set(unsigned char duty)
{
dutya=duty;
TA1CCR1 =duty; //pwm占空比
}
void SysCtlClockInit(void)
{
DCOCTL=0;
BCSCTL1=CALBC1_12MHZ;
DCOCTL =CALDCO_12MHZ;
BCSCTL1|=DIVA_0; //ACLK =32768HZ
BCSCTL2|=DIVS_0; //SMCLK=MCLK=12mhz
}
void AD_Init()
{
ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled
ADC10CTL1 = INCH_4+ADC10DIV_7; // input A3
ADC10AE0 |= BIT4; // PA.4 ADC option select
}
void TIMERA_Init(void)
{
CCTL0=CCIE;
CCR0=15000;
TA0CTL=TASSEL_2 + MC_2 + ID_3; //SMCLK 1Mhz Continous up
}