chengzepeng 发表于 2012-8-13 04:12:33

看我的普通51最快软件模拟PWM, 应该是最简单的了吧

本帖最后由 chengzepeng 于 2012-8-13 05:14 编辑

/*
        程序说明: 51最快?PWM,12M时可输出625-712Hz,
        按键可以加减PWM占空比,OUT为PWM输出,
        检测一个按键时更快,不检测按键时最快。
        制作者;bbsniua
        2012/8/13
*/
#include<AT89X51.H>        // AT89X51专属库

#define uint8_t unsigned char
#define uint16_t unsigned int

#define K_U P1_0        // 按键KU接口
#define K_D P1_1        // 按键KD接口
#define OUT P2_0        // PWM输出口

uint8_t PWM,P_S;
uint16_t d_ms;

void mcu_init()                // mcu初始化子函数
{
        TMOD = 0x01;        // T0为16位定时器
        TH0= 0xFC;        // TH0预装值,12M晶体时1mS中断一次
        TL0= 0x18;         // TL0预装值
        ET0= 1;                   // 开T0中断
        TR0= 1;                // 启动T0
        EA   = 1;                // 开总中断
        P_S= 0;                // PWM计数
        PWM= 50;
        K_U= 1;
        K_D= 1;
        OUT= 0;
}

void int_t0(void) interrupt TF0_VECTOR                // T0中断函数
{
        TH0= 0xFC;        // TH0预装值,12M晶体时1mS中断一次
        TL0= 0x18;         // TL0预装值
        if(d_ms)
        {
                --d_ms;
        }
}

void delay_ms(uint16_t xms)
{
        d_ms = xms;
        TR0 = 1;
        while(d_ms);
        TR0 = 0;               
}

void main()                                                  // 主函数
{
        mcu_init();                                        // mcu寄存器初始化
        while(1)
        {
                ++P_S;
                if(P_S==101)
                {
                        P_S = 1;
                }
                if(P_S>PWM)
                {
                        OUT = 0;
                }
                else
                {
                        OUT = 1;
                }
                if(!K_U)                                // 加PWM,最大限制为99%
                {
                        delay_ms(50);
                        if(!K_U)
                        {
                                if(PWM<99)
                                {
                                        ++PWM;
                                }
                                while(!K_U);       
                        }
                }
                else if(!K_D)                           // 减PWM,最小限制为1%
                {
                        delay_ms(50);
                        if(!K_D)
                        {
                                if(PWM>1)
                                {
                                        --PWM;                                       
                                }
                                while(!K_D);       
                        }
                }                               
        }
}/*
        程序说明: 51最快的PWM,12M时可输出832Hz,
        OUT为PWM输出,占空比50%
        制作者;bbsniua
        2012/8/13
*/
#include<AT89X51.H>        // AT89X51专属库

#define uint8_t unsigned char

#define OUT P2_0        // PWM输出口

uint8_t PWM,P_S;

void main()               
{
        PWM = 50;                  // 此处设置PWM
        while(1)
        {
                ++P_S;
                if(P_S==101)
                {
                        P_S = 1;
                }
                if(P_S>PWM)
                {
                        OUT = 0;
                }
                else
                {
                        OUT = 1;
                }                               
        }
}还有降低分辨率来提高输出频率,
以及限制占空比范围在中间采用高低电平分开填充定时器也可以得到更高的输出频率。

jetli 发表于 2012-8-13 08:15:02

{:sweat:} 用有pwm输出的 stc和mpc、等mcu不是更好?

duxingkei 发表于 2012-8-13 08:39:37

模拟PWM也应该在定时中断中翻转IO口,在主程序里面操作,根本没有实用性

chengzepeng 发表于 2012-8-13 13:31:59

duxingkei 发表于 2012-8-13 08:39 static/image/common/back.gif
模拟PWM也应该在定时中断中翻转IO口,在主程序里面操作,根本没有实用性

研究性的实验程序,
仅用来做新手了解PWM用,
实用性还不如用中断弄。

gaoyichuan000 发表于 2012-8-13 19:32:10

这个频率低点吧 1T的会不会高一点?
来自:amoBBS 阿莫电子论坛 Android客户端

chengzepeng 发表于 2012-8-14 16:02:49

gaoyichuan000 发表于 2012-8-13 19:32 static/image/common/back.gif
这个频率低点吧 1T的会不会高一点?
来自:amoBBS 阿莫电子论坛 Android客户端

写在中断里面比较实用,
模拟的主要看处理速度!
页: [1]
查看完整版本: 看我的普通51最快软件模拟PWM, 应该是最简单的了吧