新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于avr單片機I/O口輸出SPWM程序

        基于avr單片機I/O口輸出SPWM程序

        作者: 時間:2016-11-30 來源:網絡 收藏
        基于ATmega16單片機輸出SPWM程序,PWM頻率為25KHZ,輸出正弦波為50HZ,輸出電壓波形光滑,失真度小,只需要硬件和軟件相結合。電路簡單,只修改程序就可以調整功能,成本低,可靠性主高。

        #include <avr/io.h>
        #includeinterrupt.h>
        #define BIT(x) (1<//周期為20ms,產生50HZ的交流電,spwm頻率為20k
        const unsigned char list[]={1,4,7,10,13,16,19,22,25,28,31,34,37,39,42,45,48,51,54,57,60,62,
        65,68,71,74,76,79,82,84,87,90,92,95,97,100,103,105,108,110,112,115,117,119,
        122,124,126,128,131,133,135,137,139,141,143,145,147,149,151,152,154,156,157,
        159,161,162,164,165,167,168,169,171,172,173,174,176,177,178,179,180,181,182,
        182,183,184,185,185,186,186,187,187,188,188,189,189,189,189,189,189,189,189,
        189,189,189,189,189,189,188,188,187,187,186,186,185,185,184,183,182,182,181,
        180,179,178,177,176,174,173,172,171,169,168,167,165,164,162,161,159,157,156,
        154,152,151,149,147,145,143,141,139,137,135,133,131,128,126,124,122,119,117,
        115,112,110,108,105,103,100,97,95,92,90,87,84,82,79,76,74,71,68,65,62,60,57,
        54,51,48,45,42,39,37,34,31,28,25,22,19,16,13,10,7,4,1};
        //周期為20ms,產生50HZ的交流電,spwm頻率為20k
        int count,zf=0;
        void port_init(void)
        {
        PORTB = 0x00;
        DDRB = 0xFF;//b口輸出
        PORTC = 0x00;
        DDRC = 0xFF;//c口輸出
        PORTD = 0x00;
        DDRD = 0xFF;//d口輸出
        }
        //TIMER1 initialize - prescale:1
        // WGM13:0=10) PWM phz correct, TOP= ICR1
        // desired value: 10KHz
        // actual value: 10.000KHz (0.0%)
        void timer1_init(void)
        {
        TCCR1B = 0x00; //stop
        TCNT1H = 0xFF; /tup
        TCNT1L = 0x38;
        OCR1AH = 0x00;
        OCR1AL = 0xC8;
        OCR1BH = 0x00;
        OCR1BL = 0xC8;
        ICR1H = 0x00;
        ICR1L = 200;// 載波周期為50us
        TCCR1A = 0xA2; //10100010 top時更新OCR1A OCR1B,向上計數比較匹配清零,反之置位
        TCCR1B = 0x11; //start Timer 00010001 clk無分頻,相位修正PWM
        TIMSK |= 0x20; //timer interrupt sources使能捕捉中斷
        }

        //#pragma interrupt_handler timer1_capt_isr:7
        ISR(TIMER1_CAPT_vect)

        本文引用地址:http://www.104case.com/article/201611/323643.htm

        { OCR1A=500; OCR1B=500;

        if(zf)

        {

        if(count<200)
        {
        if(count==1) //此時2#管子才關斷
        {
        //PORTB &= ~BIT(3); //3#管子已經關斷
        PORTB |= BIT(4); //開通4#管子
        }
        OCR1A=list[count++]; //開通1#管子
        }
        else if((count>=200)&&(count<400))
        {
        if(count==200)
        {
        PORTB &= ~BIT(4); //關斷4#管子
        }
        if(count==201) //此時1#管子才關斷
        {
        PORTB |= BIT(3); //開通3#管子
        }
        OCR1B=list[count++-200]; //開通2#管子
        } else {
        count=0; //2#管子已經關斷
        PORTB &= ~BIT(3); //關斷3#管子
        //PORTB |= BIT(4); //開通4#管子
        OCR1A=list[count++]; //開通1#管子
        } } else; }

        //call this routine to initialize all peripherals
        void init_devices(void)
        {
        //stop errant interrupts until set up
        cli(); //disable all interrupts
        port_init();
        timer1_init();

        sei(); //re-enable interrupts
        //all peripherals are now initialized
        }
        // 主函數
        int main(void)
        {
        init_devices();
        //insert your functional code here...

        zf = 1; OCR1A=500; OCR1B=500; PORTB = 0; while(1);

        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 高唐县| 双鸭山市| 康保县| 桐庐县| 昌乐县| 舟曲县| 监利县| 博罗县| 宜良县| 湖州市| 顺昌县| 江山市| 榆树市| 肃北| 商南县| 黎平县| 吉首市| 依安县| 中卫市| 平武县| 云霄县| 仁布县| 建始县| 河津市| 南漳县| 曲周县| 成武县| 定西市| 茌平县| 正安县| 克拉玛依市| 革吉县| 方山县| 阜南县| 沁阳市| 福清市| 肥东县| 泰宁县| 徐汇区| 衡水市| 文水县|