历史上的今天
返回首页

历史上的今天

今天是:2024年10月21日(星期一)

正在发生

2019年10月21日 | ATmega2560单片机12路PWM输出的程序 每路PWM可独立控制

2019-10-21 来源:51hei

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<    }

}


void Timer5_Init(void)

{

    unsigned int temp;


    timer5_ticks = 0;

    timer5_ticksmin = 0;


    TCCR5A = 0x00;

    TCCR5B = 0x00;

    TCCR5C = 0x00;

    TCNT5H = 0x00;

    TCNT5L = 0x00;

    temp = F_CPU/16/20;

    OCR5A=temp;

    //temp = temp/2;

    //OCR5B=temp;

    //OCR5C=temp;

    //TCCR5A=(0<

推荐阅读

史海拾趣

GAPTEC Electronic GmbH & Co. KG公司的发展小趣事

背景:在闪存市场取得成功后,Galaxy Microelectronics开始探索多元化发展道路。

发展:公司决定进入DRAM市场,并投入大量资源进行技术研发。经过几年的努力,Galaxy Microelectronics成功推出了多款高性能DRAM产品,进一步丰富了其产品线。此外,公司还开始涉足SSD固态硬盘领域,推出了多款具有竞争力的产品,进一步巩固了其在存储市场的地位。

Engineered Components Co公司的发展小趣事

为了确保产品质量和客户满意度,ECC建立了完善的质量管理体系。他们从原材料采购到生产、检测、包装等各个环节都制定了严格的质量标准。ECC还引入了先进的质量检测设备和方法,确保每一件产品都符合高标准的质量要求。此外,ECC还定期对员工进行质量培训,提高员工的质量意识和操作技能。这些措施使得ECC的产品在市场上赢得了良好的口碑和信誉。

CBM_America_Corporation公司的发展小趣事

在全球电子行业遭遇供应链危机时,CBM_America_Corporation面临着巨大的挑战。公司的原材料采购受到影响,生产成本大幅上升。为了应对这一危机,CBM积极调整采购策略,寻找新的供应商和合作伙伴。同时,公司还加大了研发投入,开发出了更加环保、节能的产品,以适应市场需求的变化。通过一系列措施的实施,CBM成功度过了危机,并保持了稳定的发展态势。

DEWALT公司的发展小趣事

在第二次世界大战期间,DEWALT公司面临了巨大的挑战。由于战争的影响,许多原材料和零部件供应中断,生产受到严重影响。然而,DEWALT公司凭借自身的技术实力和创新能力,成功克服了这些困难。公司还积极为军队提供所需的电动工具产品,为战争胜利做出了贡献。这些经历使DEWALT公司更加坚定了技术创新和品质控制的信念。

高博(GBG)公司的发展小趣事

谷峰电子有限公司的故事始于1995年,当时公司在香港成立,标志着其半导体元器件研发与销售的起点。初期,面对激烈的市场竞争和技术挑战,谷峰团队凭借对半导体技术的深刻理解和对市场需求的敏锐洞察,逐步确立了以功率MOSFET为核心产品的战略方向。2000年,谷峰在深圳设立分公司,进一步扩大了其研发和销售网络,为公司的快速发展奠定了坚实基础。

Herrmann Kg公司的发展小趣事

Herrmann Kg深知不同客户对超声波焊接个性化需求,因此推出了模块化系统解决方案。这些模块化组件可以很容易地集成到现有的生产流程中,确保成功的焊接过程和出色的结果。无论是电子制造、汽车工业还是其他行业,Herrmann Kg都能根据客户的具体需求提供定制化的焊接解决方案。这种灵活性和定制化服务使得Herrmann Kg在市场上具有独特的竞争优势。

问答坊 | AI 解惑

在win CE下如何对Bluetooth编写应用程序啊?

本人正在做毕业设计,无奈上网找不到合适的资料,在这里请教下大家了,我想知道在windows ce下如何实现对蓝牙串口通信的编程,不要是单单串口通信那种代码,要如何打开蓝牙,连接对方的蓝牙实现RFCOMM连接.谢谢!…

查看全部问答>

光传输、光通信

需要向NCP/NCPF单板中烧程序,那个程序就是所谓的Agent程序吗? 单板中的Flash是指什么?…

查看全部问答>

请问:我在windows xp 下windows ce 4.2.net现在再怎么办呀,我能用它什么呀,

我在windows xp 下windows ce 4.2.net现在再怎么办呀,我能用它什么呀, 我能不能用它写一些开发序呀…

查看全部问答>

WinCE下的注册表读写,在线等,急~~~~

我在VC下的注册表读写问题为什么在EVC下运行成功,却无法对注册表修改?…

查看全部问答>

关于使用FAT文件系统实现SD卡读写的问题求助!

       在论坛上看到有不少高手使用不同芯片都实现了在FAT文件系统下读写SD卡,在下最近也在折腾这个,但是最近一直止步不前。以下是在下的具体问题,还请坛子上的各位高手不吝赐教,拜谢!    &nbs ...…

查看全部问答>

quartusII软件完全破解方法

quartusII软件完全破解方法…

查看全部问答>

用过8279的大哥们,给我指导一下!

我现在板子的情况是LCD(19264)和8279分别作为外部没备与89C52相连。LCD用来显示电流、电压、功率,以及故障显示和报警;8279用来扩展4X4的键盘来控制LCD显示,但是8279的第一个控制字我一直读不懂,大家帮解释一下好吗?以下是这个控制字的说明: (我 ...…

查看全部问答>

关于C6203B XBUS总线-XWE信号加电复位后异常情况分析

在我们的DSP系统中,出现了一种非常奇怪的现象:系统加电复位(冷复位)后,XBUS总线的-XWE/-XWAIT信号一直为低(正常时应为高!),当DSP写XBUS总线时(异步I/O方式,使用-XCE0)没有正常的负脉冲,而在DSP读XBUS总线时(同步FIFO方式,使用-XCE2 ...…

查看全部问答>

F28027模拟I2C

看着论坛中有很多人想要I2C的驱动,本来想着电设完成之后再发,算了。发一个工程使用的I2C.c与头文件吧,大家可以借鉴一下。…

查看全部问答>