amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 1431|回复: 7

新手原创 STC15F104W输出3路占空比可调PWM波形

[复制链接]
发表于 2015-1-2 19:53:40 | 显示全部楼层 |阅读模式
本帖最后由 zxq_9781 于 2015-1-2 21:06 编辑

stc15f104w.png
/*程序说明*/
//P3.3-P3.5输出3路频率500hz占空比1%-99%可调方波//
//P3.0-P3.2有3个按键单独控制3路占空比输出长按加5%
//短按加1%占空比
#include <STC15F2K60S2.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit red=P3^1;   //红色LED输出口
sbit green=P3^4; //绿色LED输出口
sbit blue=P3^5;     //蓝色LED输出口
sbit k1=P3^0;     //红色LEDpwm控制
sbit k2=P3^3;     //绿色LEDpwm控制
sbit k3=P3^2;     //蓝色LEDpwm控制
uchar r_temp=1,g_temp=1,b_temp=1;  //三色占空比数值缓存
uchar flag;                          //定时器T2定时次数标志
//延时函数,大约延时10ms.

void Delay10ms()        //@11.0592MHz
{
    unsigned char i, j;

    i = 108;
    j = 145;
    do
    {
        while (--j);
    } while (--i);
}

//按键扫描程序
void key()
{
  uchar num1=0,num2=0,num3=0;
  if(k1==0)               //按键K1处理程序
   {
     Delay10ms();
     if(k1==0)
       {
        if(r_temp<99)
             {   
              r_temp++;
              while(!k1)        
                 {
                  num1++;      //长按标志位加到10约100ms
                  Delay10ms();
                  if(num1==10&&r_temp<95)
                     {
                     r_temp+=5;
                     num1=0;
                     }
                  if(r_temp>=95) r_temp=1;
                 }
            }
        else r_temp=1;        
        }
    }
   
  if(k2==0)               //按键K2处理程序
   {
     Delay10ms();
     if(k2==0)
       {
         if(g_temp<99)
           {
             g_temp++;
             while(!k2)
                 {
                   num2++;          //长按标志位加到10约100ms
                   Delay10ms();
                   if(num2==10&&g_temp<95)
                        {
                          g_temp+=5;
                          num2=0;
                        }
                   if (g_temp>=95) g_temp=1;
                  }
            }
          else g_temp =1;
       }
    }
  if(k3==0)                       //按键K3处理程序
    {
    Delay10ms();
     if(k3==0)
     {
       if(b_temp<99)
           {
            b_temp++;
            while(!k3)
                {
                 num3++;         //长按标志位加到10约100ms
                 Delay10ms();
                 if(num3==10&&b_temp<95)
                    {
                     b_temp+=5;
                     num3=0;
                    }
                 if(b_temp>=95) b_temp=1;
                }
           }
     else b_temp =1;
      }
    }
}
/*
void exint0() interrupt 0   
        {
     PCON&= 0xFD;
         Delay10ms();
    }
void exint1() interrupt 2   
        {
     PCON&= 0xFD;
         Delay10ms();
    }
void exint4() interrupt 16   
        {
     PCON&= 0xFD;   
     Delay10ms();
    }
*/
//定时器T0 16位自动模式定时1ms 控制灯灭时间

void InitTimer0() interrupt 1  // 1毫秒@11.0592MHz
{   
    IE2 = 0x00;   //关闭定时器2中断
    AUXR=0XE4;    //关闭定时器2计数
    TL0 = 0xCD;
    TH0 = 0xD4;
    red=1;
    green=1;
    blue=1;
    flag=1;
    AUXR=0xF4;        //开启定时器2计数
    IE2=0x04;       //开启定时器2中断允许
}

//定时器T2 16位自动模式定时10us    控制等亮时间
void InitTimer2() interrupt 12    //     10微秒@11.0592MHz
{   
    flag++;
    T2L = 0x91;        //设置定时初值
    T2H = 0xFF;        //设置定时初值
    if(r_temp==flag) red=0;
    if(g_temp==flag) green=0;
    if(b_temp==flag) blue=0;
}
void init()
{
    AUXR =0XE4;//设置定时器0和2为1T模式
    TMOD= 0x00;
    TL0 = 0xCD;
    TH0 = 0xD4;
    T2L = 0x91;        //设置定时初值
    T2H = 0xFF;        //设置定时初值
    EA = 1;
    ET0 = 1;
    TR0 = 1;
//        IT1 = 1;                   //中断1下降沿触发
//        IT0 = 1;                   //中断0下降沿触发
//        EX1 = 1;                  //开外部中断1
//        EX0 = 1;                  //开外部中断0
//        INT_CLKO |= 0x40; //开外部中断4
}   
void main()
{  
init();
while(1)
   {
   key();
/*   if(r_temp==1);
      if(g_temp==1);
       if(b_temp==1);
        PCON |= 0x02;
*/
   }
}
 楼主| 发表于 2015-1-2 21:06:06 | 显示全部楼层
xiaoyigechaos 发表于 2015-1-2 21:01
你确定1脚和2脚画对了?

多谢提醒,眼真尖
 楼主| 发表于 2015-1-2 21:08:32 | 显示全部楼层
xiaoyigechaos 发表于 2015-1-2 21:01
你确定1脚和2脚画对了?

程序已经试过了,本来不想发图的,怕有人问,临时画了一下;程序里面已经说明资源配置了
发表于 2015-1-2 22:52:44 来自手机 | 显示全部楼层
首先肯定一下,自己能做出来。
控制pwm的功能应该写成函数,控制3个你可以写3遍,30个,300个呢?
楼住再考虑一下怎么用一个定时器实现你的需求。
发表于 2015-1-2 23:01:31 | 显示全部楼层
定时器中断里不需要再装值,16位自动重装嘛。。。

我一般只用一个定时器实现:
sbit   P31 = P3^1;
sbit   P34 = P3^4;
sbit   P35 = P3^5;
bit    B_PWM1,B_PWM2,B_PWM3;
u8     duty;
u8     pwm1,pwm2,pwm3;
u8     pwm1_tmp,pwm2_tmp,pwm3_tmp;

//定时器T2 16位自动模式定时10us    控制等亮时间
void InitTimer2() interrupt 12    //     10微秒@11.0592MHz
{
    P31 = B_PWM1;
    P34 = B_PWM2;
    P35 = B_PWM3;   
    if(++duty == 100)   //周期值为100
    {
        duty = 0;
        pwm1_tmp = pwm1;
        pwm2_tmp = pwm2;
        pwm3_tmp = pwm3;
        if(pwm1 != 0)        B_PWM1 = 1;
        if(pwm2 != 0)        B_PWM2 = 1;
        if(pwm3 != 0)        B_PWM3 = 1;
    }
    else
    {
       if(pwm1_tmp == duty)  B_PWM1 = 0;
       if(pwm2_tmp == duty)  B_PWM2 = 0;
       if(pwm3_tmp == duty)  B_PWM3 = 0;
    }
}
 楼主| 发表于 2015-1-3 20:26:42 | 显示全部楼层
ThinkARM 发表于 2015-1-2 22:52
首先肯定一下,自己能做出来。
控制pwm的功能应该写成函数,控制3个你可以写3遍,30个,300个呢?
楼住再考 ...

多谢指教,新手有待研究
 楼主| 发表于 2015-1-3 20:40:33 | 显示全部楼层
小李非刀 发表于 2015-1-2 23:01
定时器中断里不需要再装值,16位自动重装嘛。。。

我一般只用一个定时器实现:

多谢指教,要慢慢消化一下
发表于 2015-1-27 15:36:34 | 显示全部楼层
学习了。
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2019-6-18 07:53

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表