ATmega2560单片机12路PWM输出的程序 每路PWM可独立控制

2019-10-21来源: 51hei关键字:ATmega2560  单片机  PWM输出  独立控制

PWM模块设计说明:

使用ATmega2560单片机开发一个12路PWM输出的程序,要求每路PWM可以独立控制。通过串口指令控制某路PWM输出某个频率值(具体通道受指令第一字节控制),每路PWM的频率范围能在20-2000HZ范围内变化(具体频率值受指令第二字节控制),同时,还能够随时停止某路的输出。

指令要求:

A1  XX   第一路PWM连续输出占空比为50%不变的方波。

(XX为00时,停止输出,为01~FF时,输出20~2000HZ频率值,其中重点关照1000HZ以下,以5HZ为步进;1000-2000HZ以15HZ步进即可,以上要求的步进值并非十分严格,如果不易实现,可以稍微修改。)  

以下均相同要求:

A2  XX   第二路。。。。

A3  XX   第三路。。。。

...............

AC  XX   第十二路。。。。

初始上电时,各路均不输出。


avr单片机源程序:

#include "kernel.h"


unsigned int PWM_Buf[6];//6路PWM频率


unsigned long timer0_ticks;

unsigned long timer0_tickssec;

unsigned long timer1_ticks;

unsigned long timer1_ticksmin;

unsigned long timer2_ticks;

unsigned long timer2_tickssec;

unsigned long timer3_ticks;

unsigned long timer3_ticksmin;

unsigned long timer4_ticks;

unsigned long timer4_ticksmin;

unsigned long timer5_ticks;

unsigned long timer5_ticksmin;


void Timer0_Init(void)

{

    timer0_ticks = 0;

    timer0_tickssec = 0;


    TCCR0A = 0x00;

    TCCR0B = 0x00;

    TCNT0 = 0x00;

    OCR0A = F_CPU/(1024-1)/20;//频率F_PWM

    OCR0B = OCR0A/2;//占空比50%

    //TCCR0A = 0xA3;  //COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00

    TCCR0B = 0xCD;  //FOC0A FOC0B – – WGM02 CS02 CS01 CS00

    /*

    TCCR0A = 0x00;

    TCCR0B = 0x00;//stop

    TCNT0  = 0xE7;//25us

    OCR0A  = 0x18;

    OCR0B  = 0x18;

    TCCR0A = 0x03;

    TCCR0B = 0x02;//start,clkT0S/8

    TIMSK0|= 0x01;//enable 0verflow interrupt*/

}


void TC0_Set_PWM(unsigned int curF)

{//20~80为clkT0S/1024,80~300为clkT0S/256,300~2000为clkT0S/64

    if(curF==0)

    {

        OCR0A = 0;

        OCR0B = 0;

        TCCR0A = 0;

    }

    else if((curF>=20)&&(curF<80))

    {

        OCR0A = F_CPU/(1024-1)/curF;

        OCR0B = OCR0A/2;

        TCCR0A = 0xA3;

        TCCR0B = 0xCD;

    }

    else if((curF>=80)&&(curF<300))

    {

        OCR0A = F_CPU/(256-1)/curF;

        OCR0B = OCR0A/2;

        TCCR0A = 0xA3;

        TCCR0B = 0xCC;

    }

    else if((curF>=300)&&(curF<=2000))

    {

        OCR0A = F_CPU/(64-1)/curF;

        OCR0B = OCR0A/2;

        TCCR0A = 0xA3;

        TCCR0B = 0xCB;

    }

}


void Timer1_Init(void)

{

    unsigned int temp;


    timer1_ticks = 0;

    timer1_ticksmin = 0;


    TCCR1A = 0x00;

    TCCR1B = 0x00;

    TCCR1C = 0x00;

    TCNT1H = 0x00;

    TCNT1L = 0x00;

    temp = F_CPU/16/20;

    OCR1A=temp;

    //temp = temp/2;

    //OCR1B=temp;

    //OCR1C=temp;

    //TCCR1A=(0<

    TCCR1B=(1<

    /*

    TCCR1A = 0x00;//COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10

    TCCR1B = 0x00;//stop,ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10

    TCCR1C = 0x00;//FOC1A FOC1B FOC1C – – – – –

    TCNT1H = 0xE3;

    TCNT1L = 0xE0;

    OCR1AH = 0x1C;

    OCR1AL = 0x1F;

    OCR1BH = 0x1C;

    OCR1BL = 0x1F;

    OCR1CH = 0x1C;

    OCR1CL = 0x1F;

    ICR1H  = 0x00;

    ICR1L  = 0x00;

    TCCR1B = 0x05;

//    TIMSK |= 0x04;//enable 0verflow interrupt*/

}


void TC1_Set_PWM(unsigned int curF)

{

    unsigned int temp;


    if(curF==0)

    {

        //OCR1A = 0;

        //OCR1B = 0;

        TCCR1A=0;

    }

    else if((curF>=20)&&(curF<=2000))

    {

        temp = F_CPU/16/curF;

        OCR1A=temp;

        TCCR1A=(0<

    }

}


void Timer2_Init(void)

{

    timer2_ticks = 0;

    timer2_tickssec = 0;


    TCCR2A = 0x00;

    TCCR2B = 0x00;

    TCNT2 = 0x00;

    OCR2A = F_CPU/(1024-1)/20;//频率F_PWM

    OCR2B = OCR2A/2;//占空比50%

    //TCCR2A = 0xA3;  //COM2A1 COM2A0 COM2B1 COM2B0 – – WGM21 WGM20

    TCCR2B = 0xCF;  //FOC2A FOC2B – – WGM22 CS22 CS21 CS20


//    TCCR2 = 0x00;//stop,FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20

//    TCNT2 = 0xB8;//set count 10ms

//    OCR2  = 0x47;

//    TCCR2 = 0x05;//start,clkT0S/1024

//    TIMSK|= 0x40;//enable 0verflow interrupt

}


void TC2_Set_PWM(unsigned int curF)

{//20~80为clkT0S/1024,80~300为clkT0S/256,300~2000为clkT0S/64

    if(curF==0)

    {

        OCR2A = 0;

        OCR2B = 0;

        TCCR2A = 0;

    }

    else if((curF>=20)&&(curF<80))

    {

        OCR2A = F_CPU/(1024-1)/curF;

        OCR2B = OCR2A/2;

        TCCR2A = 0xA3;

        TCCR2B = 0xCF;

    }

    else if((curF>=80)&&(curF<300))

    {

        OCR2A = F_CPU/(256-1)/curF;

        OCR2B = OCR2A/2;

        TCCR2A = 0xA3;

        TCCR2B = 0xCE;

    }

    else if((curF>=300)&&(curF<=2000))

    {

        OCR2A = F_CPU/(64-1)/curF;

        OCR2B = OCR2A/2;

        TCCR2A = 0xA3;

        TCCR2B = 0xCC;

    }

}


void Timer3_Init(void)

{

    unsigned int temp;


    timer3_ticks = 0;

    timer3_ticksmin = 0;


    TCCR3A = 0x00;

    TCCR3B = 0x00;

    TCCR3C = 0x00;

    TCNT3H = 0x00;

    TCNT3L = 0x00;

    temp = F_CPU/16/20;

    OCR3A=temp;

    //temp = temp/2;

    //OCR3B=temp;

    //OCR3C=temp;

    //TCCR3A=(0<

    TCCR3B=(1<

    /*

    TCCR3A = 0x00;//COM3A1 COM3A0 COM3B1 COM3B0 COM3C1 COM3C0 WGM31 WGM30

    TCCR3B = 0x00;//stop,ICNC3 ICES3 – WGM33 WGM32 CS32 CS31 CS30

    TCCR3C = 0x00;//FOC3A FOC3B FOC3C – – – – –

    TCNT3H = 0xE3;

    TCNT3L = 0xE0;//set count 1s

    OCR3AH = 0x1C;

    OCR3AL = 0x1F;

    OCR3BH = 0x1C;

    OCR3BL = 0x1F;

    OCR3CH = 0x1C;

    OCR3CL = 0x1F;

    ICR3H  = 0x00;

    ICR3L  = 0x00;

    TCCR3B = 0x05;//start,clkT0S/1024

//    ETIMSK|= 0x04;//enable 0verflow interrupt*/

}


void TC3_Set_PWM(unsigned int curF)

{

    unsigned int temp;


    if(curF==0)

    {

        //OCR3A = 0;

        //OCR3B = 0;

        TCCR3A=0;

    }

    else if((curF>=20)&&(curF<=2000))

    {

        temp = F_CPU/16/curF;

        OCR3A=temp;

        TCCR3A=(0<

    }

}


void Timer4_Init(void)

{

    unsigned int temp;


    timer4_ticks = 0;

    timer4_ticksmin = 0;


    TCCR4A = 0x00;

    TCCR4B = 0x00;

    TCCR4C = 0x00;

    TCNT4H = 0x00;

    TCNT4L = 0x00;

    temp = F_CPU/16/20;

    OCR4A=temp;

    //temp = temp/2;

    //OCR4B=temp;

    //OCR4C=temp;

    //TCCR4A=(0<

    TCCR4B=(1<

}


void TC4_Set_PWM(unsigned int curF)

{

    unsigned int temp;


    if(curF==0)

    {

        //OCR4A = 0;

        //OCR4B = 0;

        TCCR4A=0;

    }

    else if((curF>=20)&&(curF<=2000))

    {

        temp = F_CPU/16/curF;

        OCR4A=temp;

TCCR4A=(0<

[1] [2]
关键字:ATmega2560  单片机  PWM输出  独立控制 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic477786.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:bascom avr单片机仿真oled显示
下一篇:Atmega16单片机实验:DS18B20和ad采集显示程序

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

Atmega32A驱动LCD1602显示屏
对于初学者来说,最烦躁的可能就是调试程序,往往小小一个问题,要找个一个小时,甚至几个小时才能解决,这个程序是刚调试完的,整整九个多小时啊,现在看着挺简单的,没调试好前根本不敢肯能调得好.高手别笑,初学者参考编程环境Atmel Studio 7.0 和Proteus 8仿真,说明:仿真和真实电路是有点区别的,仿真Proteus 8只能用内部晶振,最大8MHz,我的DIY板是16M,所以实际电路总是比仿真的跑快好多单片机源程序:/** LCD1602_AVR.h** Created: 2017/3/19 23:07:51*  Author: lyl*LCD1602的基本操作时序      &nbs
发表于 2019-11-11
Atmega32A驱动LCD1602显示屏
ATMEGA16L实现时间和温度的循环显示程序分享
//ICC-AVR application builder : 2/13 20:52:33/******************************************************************************** 版权:     ** 单片机:   ATMAGE16L* 晶振:     外部8MHz* 编译器:   ICC 7.22** 文件名:   main.c* 作者:     木子工作室* 版本:     1.0* 完成日期: * 功能描述: 在12M晶振下,
发表于 2019-11-09
基于ATmega128单片机的红外控制电机系统源码
单片机源程序如下:#include "Main.h"SIGNAL(SIG_OVERFLOW0) //中断每1秒发一个数{                TCNT0 = 200;         TIMSK &= ~_BV(TOIE0);  //TIMSK中TOIE0置0        if(++g_bCount>1)        {     
发表于 2019-11-09
AVR stdio写的ATMEGA16控制步进电机正反转和速度
AVR stdio写的ATMEGA16控制步进电机正反转和速度,供大家免费参阅和批评适合初学者,总共七个按键  三个按键控制三个速度正转,三个按键控制三个速度反转,一个按键控制停止。本程序控制步进电机是和步进电机驱动器相连接的,所以脉冲只有一路,如果想直接连步进电机只需要稍加改动即可。 主程序预览:#define F_CPU 800000UL#include <avr/io.h>#include <util/delay.h>#define INT8U unsigned int#define INT16U unsigned intconst INT8U FFW[]={0x01
发表于 2019-11-09
AVR stdio写的ATMEGA16控制步进电机正反转和速度
atmega16与24l01按键主程序
#include<avr/io.h>#include<avr/delay.h>#include"NRF24L01.h"//#define Open_TX#define Open_RXtypedef unsigned char  uint8;                   /* defined for unsigned 8-bits integer variable     无符号8位整型变量 &n
发表于 2019-11-08
ATmega8+PT100热敏电阻+AD824S proteus仿真与源程序
pt100热敏电阻+AD824S放大并由ATmega8单片机主控的测温系统仿真原理图如下ATmega8单片机源程序如下:/*****************************************************This program was produced by theCodeWizardAVR V2.03.4 StandardAutomatic Program Generator?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.Project : Version : Date    
发表于 2019-11-08
ATmega8+PT100热敏电阻+AD824S proteus仿真与源程序
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved