打印

写程序做到转脚位问题,请指教

[复制链接]
2225|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
meetof4|  楼主 | 2013-2-4 00:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个程序,写到可以控制LED的光量
用了定时器 0 ,1 来做到 pwn控制
現在只能做到一個脚位 輸出 pwm
但我想控制多个LED 在不同pin位

现在想到解决方法是转 脚位如 按了A制 pwm输出位是P1^0     按了B制 pwm输出位是P1^1
不知这个方法可行吗?


#include <reg52.h>
sbit LED=P1^0;                   <----如果可行, 又可以如何改写
sbit k1=P2^3;
sbit k2=P2^0;
unsigned char PWM =0x7f;
char code reserve[3] _at_ 0x3b;
        bit light =0;

void delay(unsigned int ms)
{
unsigned char i;
while(ms--)
{
for(i=0;i<114;i++);
}
}

void main()

{
LED= 0xff ;
TMOD=0x21;
TH0=0xB1;
TL0=0xE0;

TH1=PWM;
TL1=0;

EA=1;
ET0=1;
ET1=1;



TR0=1 ;
light=0;
   while(1)
   {
           if(k1==0)        {
        do{
            if(PWM!=0xff&&light==0){
                        PWM++ ;delay(45);

                }
        else light=1 ;
                 if(PWM!=0x02&&light==1){
                         PWM-- ;delay(45);
                        }
                        else light=0;
          }while(k1==0);
        light=0;
       


          }
         
                 }

}


          void timer0() interrupt 1
          {
          TR1=0;
          TH0=0xfe;
          TL0=0xfe;
          TH1=PWM;
          TR1=1;
          LED=0x00;
          }

         void timer1() interrupt 3
         {
         TR1=0;
         LED=0xff;
         }

相关帖子

沙发
shell.albert| | 2013-2-4 08:40 | 只看该作者
将PWM输出接到缓冲器上,然后再使用多路选择器,通过片选分别输出。只能如此了。

使用特权

评论回复
板凳
meetof4|  楼主 | 2013-2-4 12:35 | 只看该作者
本帖最后由 meetof4 于 2013-2-4 15:31 编辑

请问我用的是STC12C5A60S2 应该用什么缓冲器和多路选择器?
怎样做到片选这个功能有没有一些相关的资料或教学
谢谢!

使用特权

评论回复
地板
meetof4|  楼主 | 2013-2-5 07:33 | 只看该作者
顶一顶,请求答覆!

使用特权

评论回复
5
g1234567| | 2013-2-5 09:59 | 只看该作者
按你要求:P
sbit LED1=P1^0;
sbit LED2=P1^1;

sbit LEDn=  ;
if(A)  {LED1=  ;}
else IF(B){ LED2=;}
......
else{LEDn=  ;}

使用特权

评论回复
6
meetof4|  楼主 | 2013-2-5 15:17 | 只看该作者
g1234567 发表于 2013-2-5 09:59
按你要求
sbit LED1=P1^0;
sbit LED2=P1^1;

十分感謝

但遇到一些問題, 因為控制光量要用定時器, 輸出位也要在定時器中設定
void main()
{LED= 0xff ;...}

如果用sbit LED1=P1^0; sbit LED2=P1^1;再在定時器中設定
void main()
{LED1= 0xff ;LED2= 0xff ;...}
只可以做到同時改變光量, 不能獨立運作

所以我想問怎樣將(紅字) pwm輸出位有什麼方法修改到不用固定因為如果一開始就設定了輸出位是P1^0下面的程序就難以工作
例如 :我想加一個按鈕叫k3和k4 ,再在程序寫如果k3按了pwm輸出位是P1^x如果k4按了 pwm又會是其他輸出位

sbit LED=P1^0;                  
.......
void main()

{
LED= 0xff ;
TMOD=0x21;
TH0=0xB1;
TL0=0xE0;

TH1=PWM;
TL1=0;

EA=1;
ET0=1;
ET1=1;

TR0=1 ;
light=0;
.....

          void timer0() interrupt 1
          {
          TR1=0;
          TH0=0xfe;
          TL0=0xfe;
          TH1=PWM;
          TR1=1;
          LED=0x00;
          }

         void timer1() interrupt 3
         {
         TR1=0;
         LED=0xff;
         }





使用特权

评论回复
7
joyme| | 2013-2-5 15:34 | 只看该作者
1、一个定时器可以控制很多管脚输出不同频率的PWM
2、转换管脚输出,语句简单,定义一个带参数的宏(复杂点就写个函数),根据按键情况改变调用的参数就好

使用特权

评论回复
8
meetof4|  楼主 | 2013-2-5 16:23 | 只看该作者
本帖最后由 meetof4 于 2013-2-5 20:27 编辑
joyme 发表于 2013-2-5 15:34
1、一个定时器可以控制很多管脚输出不同频率的PWM
2、转换管脚输出,语句简单,定义一个带参数的宏(复杂点 ...

前辈 所说的正是我想做到的
这两个方法我也想过  但因为还是新人一名  苦无对策  难以完成
可否给予一些例子 作参考,谢谢





使用特权

评论回复
9
jwwhy| | 2013-2-5 21:47 | 只看该作者
可以k3/K4按键按下时区分做个标志位,然后在输出pWM中加判断就可以了 。

使用特权

评论回复
10
fp123123| | 2013-2-5 23:25 | 只看该作者
不用定时器也可以控制很多个不同亮度的LED,这个程序应该可以用
#include <reg52.h>

// LED数据结构
struct LedData
{
  sbit Bit; // LED的Pin
  unsigned char pwm; // LED的PWM数值
};

// 8个LED的数组,缺省PWM=0
struct LedData LED[8] = {
  {P1^0, 0},
  {P1^1, 0},
  {P1^2, 0},
  {P1^3, 0},
  {P1^4, 0},
  {P1^5, 0},
  {P1^6, 0},
  {P1^7, 0}};

sbit k1=P2^3; // PWM++
sbit k2=P2^0; // PWM--
sbit k3=P2^1; // 转换当前按键控制的灯

void main()
{
  unsigned char light; // 当前按键控制的灯
  unsigned short key_count; // 按键消抖动
  char k1_down, k2_down, k3_down;
  unsigned char PWM = 0;
  char c;

  k1_down = 0;
  k2_down = 0;
  k3_down = 0;

  for(;;)
  {
    if(k3==0)
    {
      k3_down = 1;
      key_count = 0;
    }
    else if(k3_down==1)
    {
      // k3按下后再释放,超过一定时间才认为是有效按键,达到消抖动效果
      key_count++;
      if(key_count==3000) // 3000是延时,需要根据实际情况修改这个数值
      {
        // 有效按键,换灯
        k3_down = 0;
        light = (light+1)%8;
      }
    }

    if(k1==0)
    {
      k1_down = 1;
      key_count = 0;
    }
    else if(k1_down==1)
    {
      // k1按下后再释放,超过一定时间才认为是有效按键,达到消抖动效果
      key_count++;
      if(key_count==3000) // 3000是延时,需要根据实际情况修改这个数值
      {
        // 有效按键,PWM++
        k1_down = 0;
        if(LED[light].pwm<245) LED[light].pwm += 10;
      }
    }

    if(k2==0)
    {
      k2_down = 1;
      key_count = 0;
    }
    else if(k2_down==1)
    {
      // k2按下后再释放,超过一定时间才认为是有效按键,达到消抖动效果
      key_count++;
      if(key_count==3000) // 3000是延时,需要根据实际情况修改这个数值
      {
        // 有效按键,PWM--
        k2_down = 0;
        if(LED[light].pwm>10) LED[light].pwm -= 10;
      }
    }

    PWM++;

    if(PWM==255)
    {
      // 全部打开
      for(c=0;c<8;c++) LED[c].Bit = 0;
      PWM = 0;
    }

    // 根据不同LED的PWM值关闭对应的LED
    for(c=0;c<8;c++)
    {
      if(LED[c].pwm==PWM) LED[c].Bit = 1;
    }
  }
}


使用特权

评论回复
11
jrcsh| | 2013-2-6 00:44 | 只看该作者
  。。。。。。。。  变换个思路~~~这个问题简单得很

  1个 定时器输出 固定的周期值计数,  比如为 100份(ppp)

  每IO 独立给 一个占空比值
aaa=50
bbb=70
if(aaa>ppp)
{
p1=0;
}

if(bbb>ppp)
{
p2=0;
}


细节自己补完

使用特权

评论回复
12
meetof4|  楼主 | 2013-2-6 09:51 | 只看该作者
本帖最后由 meetof4 于 2013-2-6 10:24 编辑
fp123123 发表于 2013-2-5 23:25
不用定时器也可以控制很多个不同亮度的LED,这个程序应该可以用
#include

谢谢
红字的部分是我的理解和修改 但还是有error


#include <reg52.h>

// LED数据结构
struct LedData
{
  sbit Bit; // LED的Pin                                      <----这个还想不到是什么                        
  sbit Bit=P1;  (?)         
  unsigned char pwm; // LED的PWM数值       <----
unsigned char pwm =0x7f;;
};


// 8个LED的数组,缺省PWM=0
struct LedData LED[8] = {                            <---这个也是想不到是什么
  {P1^0, 0},
  {P1^1, 0},
  {P1^2, 0},
  {P1^3, 0},
  {P1^4, 0},
  {P1^5, 0},
  {P1^6, 0},
  {P1^7, 0}};

sbit k1=P2^3; // PWM++
sbit k2=P2^0; // PWM--
sbit k3=P2^1; // 转换当前按键控制的灯

void main()
{
  unsigned char light; // 当前按键控制的灯
  unsigned short key_count; // 按键消抖动
  char k1_down, k2_down, k3_down;
  unsigned char PWM = 0;
  char c;

  k1_down = 0;
  k2_down = 0;
  k3_down = 0;

  for(;;)
  {
    if(k3==0)
    {
      k3_down = 1;
      key_count = 0;
    }
    else if(k3_down==1)
    {
      // k3按下后再释放,超过一定时间才认为是有效按键,达到消抖动效果
      key_count++;
      if(key_count==3000) // 3000是延时,需要根据实际情况修改这个数值
      {
        // 有效按键,换灯
        k3_down = 0;
        light = (light+1)%8;
      }
    }

    if(k1==0)
    {
      k1_down = 1;
      key_count = 0;
    }
    else if(k1_down==1)
    {
      // k1按下后再释放,超过一定时间才认为是有效按键,达到消抖动效果
      key_count++;
      if(key_count==3000) // 3000是延时,需要根据实际情况修改这个数值
      {
        // 有效按键,PWM++
        k1_down = 0;
        if(LED[light].pwm<245) LED[light].pwm += 10;
      }
    }

    if(k2==0)
    {
      k2_down = 1;
      key_count = 0;
    }
    else if(k2_down==1)
    {
      // k2按下后再释放,超过一定时间才认为是有效按键,达到消抖动效果
      key_count++;
      if(key_count==3000) // 3000是延时,需要根据实际情况修改这个数值
      {
        // 有效按键,PWM--
        k2_down = 0;
        if(LED[light].pwm>10) LED[light].pwm -= 10;
      }
    }

    PWM++;

    if(PWM==255)
    {
      // 全部打开
      for(c=0;c<8;c++) LED[c].Bit = 0;
      PWM = 0;
    }

    // 根据不同LED的PWM值关闭对应的LED
    for(c=0;c<8;c++)
    {
      if(LED[c].pwm==PWM) LED[c].Bit = 1;
    }
  }
}

使用特权

评论回复
13
meetof4|  楼主 | 2013-2-6 09:52 | 只看该作者
jrcsh 发表于 2013-2-6 00:44
。。。。。。。。  变换个思路~~~这个问题简单得很

  1个 定时器输出 固定的周期值计数,  比如为 100份 ...

谢谢 前辈
这个思路 要一些时间来理解和消化

使用特权

评论回复
14
fp123123| | 2013-2-6 23:13 | 只看该作者
我给你的程序就是这个思路,你去复习一下C语言再看吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

7

帖子

0

粉丝