×
单片机 > 单片机程序设计 > 详情

ATMEGA16单片机Timer1的OC1A脚输出占空比可调的PWM信号

发布时间:2020-08-26 发布时间:
|

采用快速PWM方式,通过按键设置OCR1A的值,从而改变占空比;

当数值超出界限时,以了LED和LCD的方式报警;

输出经过滤波可以得到直流信号,改变占空比,输出不一样。

仿真原理图如下
 

单片机源程序如下:


#define MAIN_C

#include "includes.h"

/***************************/

/*PWM*/

/*晶振为4MHz*/

/*利用Timer1的OC1A脚输出占空比可调的信号*/

/*通过按键控制OCR1A的值*/

/***************************/


#define PwmOut     PD5     //A通道的PWM输出

#define OCR        OCR1A

#define KeyUp      PA0     //增大PWM值的按键

#define KeyDown    PA1     //减小PWM值的按键

#define Above      PA2     //设置位值过高指示

#define Below      PA3     //设置位值过低指示

#define STEP       64      //定义按键时的步进值

int OcrReg = 1024;         //OCR1A初始值

int Icr1Reg = 0x7ff;       //PWM的计数顶部值  Icr1Reg = 2047

//unsigned char *show = "0000"; 

unsigned char temp;


void init(void)   //初始化函数

{

    //比较匹配时清零,计数到最大时置位OC1A

    TCCR1A |= (1<

    //11位分辨率,快速PWM模式,使用系统时钟作为计数时钟

    TCCR1B |= (1<

    ICR1   = Icr1Reg;  

    OCR    = 0 ;

    DDRD  |= (1<

    DDRA  |= (1<

    DDRA  &= ~((1<

    PORTA |= (1<

    PORTA |= (1<

    //TIMSK |= (1<

    //SREG  |= (1<<7);   //开全局中断

}


void  ShowValue(int value)

{

    unsigned char *temp = "0000";

    temp[0] = value/1000 + 0x30;

    value = value%1000;

    temp[1] = value/100 +0x30;

    value = value%100;

    temp[2] = value/10 + 0x30;

    value = value%10;

    temp[3] = value + 0x30;  

    ClearLine(2);

    LCD_DisplayString(2,1,"OCR1A = ");

    LCD_DisplayString(2,9,temp);  

}


void main(void)

    unsigned char i; 

    init();

    Init_LCD();

    OCR = OcrReg;

    LCD_DisplayString(1,1,"PWM test");

    LCD_DisplayString(2,1,"OCR1A = ");

    ShowValue(OcrReg);

    while(1)

    {                

        if(!(PINA&(1<

        {

            delay_nms(10);    //按键消抖

            if(!(PINA&(1<

            {

                while(!(PINA&(1<

                if(OcrReg >= (Icr1Reg+1))

                {

                    for(i=0;i<5;i++)

                    {

                        PORTA ^= (1<

                        delay_nms(200);

                    }

                    ClearLine(2);

                    LCD_DisplayString(2,1,"Value MAX!");

                }

                else

                {

                    PORTA |= (1<

                    OcrReg += STEP;                    

                    OCR = OcrReg;

                    ShowValue(OcrReg);

                }

            }

        }

        if(!(PINA&(1<

        {

            delay_nms(10);    //按键消抖

            if(!(PINA&(1<

            {

                while(!(PINA&(1<

                if(OcrReg <= 0)

                {

                    for(i=0;i<5;i++)

                    {

                        PORTA ^= (1<

                        delay_nms(200);

                    }

                     ClearLine(2);

                    LCD_DisplayString(2,1,"Value MIN!");

                }

                else

                {

                    PORTA |= (1<

                    OcrReg -= STEP;

                    OCR = OcrReg;

                    ShowValue(OcrReg);

                }

            }

        }       

    }

}



//比较中断子程序,可以用来产生正弦波

/*#pragma vector = TIMER1_COMPA_vect

    __interrupt void CompA_isr( void ) 

{

    

    OcrReg =  st[j];

    OCR = OcrReg;  

    j++;  

    if(j>88)

    {

        j = 0;

    }

}*/



关键字:ATMEGA16  单片机  Timer1  占空比  PWM信号 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR单片机中RC电容触摸的感应原理解析