久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1897|回復: 20
打印 上一主題 下一主題
收起左側

求教單片機流水燈開慢到快關時快到慢關閉,不太懂占空比取固定值怎么寫?

[復制鏈接]
跳轉到指定樓層
樓主
ID:1002664 發表于 2022-1-23 16:48 來自手機 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
求教流水燈開慢到快,關快到慢程序思路,試著delay來判斷,不懂占空比5%~100%怎么取值固定,小白。流水程序看視頻學寫的,delay按著一些理解來寫的,軟件void delay報錯不對。。。。

單片機源程序如下:
#include  <reg51.h> // <reg51.h>程序電腦實驗  


sbit key1=P3^0;

unsigned char dat1[4]={0xf1,0xf2,0xf4,0xf8};
unsigned char dat2[4]={0xfc,0xf9,0xf3,0xf6};
unsigned char dat3[4]={0xfe,0xfd,0xfb,0xf7};

        
unsigned char MODE;
unsigned int  count;

void delay (unsigned int x);
void mode1(void);
void mode2(void);
void mode3(void);
void keyscan(void);

void main(void)
{
        while(1)
        {
                keyscan();
                switch(MODE)
                {
                        case 0: P0=0xff;break;
                        case 1: mode1();break;
                        case 2: mode2();break;
                        case 3: mode3();break;
                }
                delay(1);
  }
}

void delay(unsigned int x)
{
        unsigned int i,j;
        for(i=0;i<x;i++)
        {
              for(j=0;j<120;j++);//12T
         
        }
}


void mode1(void)
{
        static unsigned char i;
        static unsigned int j;
        P0=dat1;
     for(j=500;j>50;j--)  //慢到快,怎么固定到快?不知道對不對
       if(++j>=50)
        {
                j=50
                i=++i%4;
        }
   {
    MODE=0
   for(j=50;j<50;j++)  //快到慢?關閉?
     if(++j>=50)
    }
}
void mode2(void)
{
        static unsigned char i;
        static unsigned int j;
        P0=dat2;
         for(j=500;j>50;j--)  //慢到快,怎么固定到快?不知道對不對
       if(++j>=50)
        {
                j=50
                i=++i%4;
        }
   {
    MODE=0
   for(j=50;j<50;j++)  //快到慢?關閉?
     if(++j>=50)
    }
}

void mode3(void)
{
        static unsigned char i;
        static unsigned int j;
        P0=dat3;
         for(j=500;j>50;j--)  //慢到快,怎么固定到快?不知道對不對
       if(++j>=50)
        {
                j=50
                i=++i%4;
        }
   {
    MODE=0
   for(j=50;j<50;j++)  //快到慢?關閉?
     if(++j>=50)
    }
}

void keyscan(void)
{
        if(key1==0)
        {
                if(count<501)count++;

                if(count==500)
                {
                        sign=~sign;
                        if(sign)
                        {
                                slow=MODE;
                                MODE=0;
                        }
                        else MODE=slow;
                }
        }   
        else
        {
                if(count>20 && count<500
                {
                        ++MODE;
                        if(MODE>3)
                                MODE=1;
                }
                count=0;
        }   
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:624769 發表于 2022-1-23 22:55 | 只看該作者
初學單片機,學了流水燈,delay 稍微了解一下即可。
接下來,你應該折騰定時器,研究中斷。用這些組合來控制流水燈。
然后,再回過頭來,搞花樣delay.

不然,你單片機學習的道路,會越走越偏,還會固化思想,在單線程道路上越走越遠。
回復

使用道具 舉報

板凳
ID:474583 發表于 2022-1-23 23:26 | 只看該作者
有的MCU有PWM硬件, 可以配置周期和占空比的。如果沒有PWM, 只能用GPIO+TIM 配合實現了
回復

使用道具 舉報

地板
ID:990881 發表于 2022-1-24 08:41 | 只看該作者
代碼是不是貼錯了,咋感覺看不懂,
for(j=500;j>50;j--)  //慢到快,怎么固定到快?不知道對不對
       if(++j>=50)
        {
                j=50
                i=++i%4;
        }
這個不是就循環一次嗎?
  for(j=50;j<50;j++)  //快到慢?關閉?
     if(++j>=50)
這個也是循環一次,兩個沒區別呀
回復

使用道具 舉報

5#
ID:1002664 發表于 2022-1-24 08:58 來自手機 | 只看該作者
188610329 發表于 2022-1-23 22:55
初學單片機,學了流水燈,delay 稍微了解一下即可。
接下來,你應該折騰定時器,研究中斷。用這些組合來控 ...

哦哦好的,謝謝
回復

使用道具 舉報

6#
ID:1002664 發表于 2022-1-24 10:05 | 只看該作者
188610329 發表于 2022-1-23 22:55
初學單片機,學了流水燈,delay 稍微了解一下即可。
接下來,你應該折騰定時器,研究中斷。用這些組合來控 ...

就是看了學習視頻不知道怎么融入進去能給一段融合后的參考下嘛
回復

使用道具 舉報

7#
ID:161164 發表于 2022-1-24 14:25 | 只看該作者
本帖最后由 lkc8210 于 2022-1-24 21:28 編輯

一步一步來
先弄一個定速流水燈

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295
  5. u16 TMR_XX_ACC;
  6. u8 index = 0;
  7. void main()
  8. {
  9.     while (1)
  10.     {        
  11.                         if(++TMR_XX_ACC >= 10000)
  12.                         {TMR_XX_ACC=0;
  13.                                 P1 = ~(0x01 << index);
  14.                                 index = ++index %8;
  15.                         }
  16.     }
  17. }
復制代碼


加一個變數變成加速流水燈

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295
  5. u16 TMR_XX_ACC;
  6. u16 TMR_XX_PRE = 10000;
  7. u8 index = 0;
  8. void main()
  9. {
  10.     while (1)
  11.     {        
  12.                         if(++TMR_XX_ACC >= TMR_XX_PRE)
  13.                         {TMR_XX_ACC=0;
  14.                                 P1 = ~(0x01 << index);
  15.                                 index = ++index %8;
  16.                                 if(index==0)
  17.                                         if(TMR_XX_PRE>1000)//固定到快
  18.                                                 TMR_XX_PRE -=500;
  19.                         }
  20.     }
  21. }
復制代碼


再來一組LED 1%固定亮度PWM

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295

  5. void delayus(u8 x)
  6. {
  7.         while(x--);
  8. }
  9. void main()
  10. {
  11.     while (1)
  12.     {        
  13.                         P1 = 0;
  14.                         delayus(1);               
  15.                         P1 = 0xFF;
  16.                         delayus(99);                        
  17.     }
  18. }
復制代碼


加一個變數變漸亮PWM

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295

  5. u16 TMR_XX_ACC;
  6. u8 PWM = 1;
  7. void delayus(u8 x)
  8. {
  9.         while(x--);
  10. }
  11. void main()
  12. {
  13.     while (1)
  14.     {        
  15.                         P1 = 0;
  16.                         delayus(PWM);               
  17.                         P1 = 0xFF;
  18.                         delayus(100-PWM);
  19.                         if(++TMR_XX_ACC >= 500)
  20.                         {TMR_XX_ACC=0;
  21.                                 if(PWM <99) PWM++;
  22.                         }
  23.     }
  24. }
復制代碼


最后把他們合起來

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295

  5. u16 TMR_XX_ACC;
  6. u16 TMR_XX_PRE = 500;
  7. u8 PWM = 1;
  8. u8 index = 0;
  9. void delayus(u8 x)
  10. {
  11.         while(x--);
  12. }
  13. void main()
  14. {
  15.     while (1)
  16.     {        
  17.                         P1 = ~(0x01 << index);
  18.                         delayus(PWM);               
  19.                         P1 = 0xFF;
  20.                         delayus(100-PWM);
  21.                         if(++TMR_XX_ACC >= TMR_XX_PRE)
  22.                         {TMR_XX_ACC=0;
  23.                                 if(PWM <99) PWM++;
  24.                                 index = ++index %8;
  25.                                 if(index==0)
  26.                                         if(TMR_XX_PRE>50)//固定到快
  27.                                                 TMR_XX_PRE -=50;
  28.                         }
  29.     }
  30. }
復制代碼
回復

使用道具 舉報

8#
ID:1002664 發表于 2022-1-25 23:00 | 只看該作者
lkc8210 發表于 2022-1-24 14:25
一步一步來
先弄一個定速流水燈

謝謝 大佬,TMR_XX_ACC是定時器嘛?PWM為什么不用寫TH0 ;TL0這些中斷,啟動也能行?
回復

使用道具 舉報

9#
ID:161164 發表于 2022-1-26 09:43 | 只看該作者
菜鳥一個622 發表于 2022-1-25 23:00
謝謝 大佬,TMR_XX_ACC是定時器嘛?PWM為什么不用寫TH0 ;TL0這些中斷,啟動也能行?

TMR_XX_ACC是變數,記錄系統走了多少個循環
PWM是用定時器中斷來寫更好,但初入門用delay比較好理解
當你了解了定時器的原理,就可以試試用定時器來寫
回復

使用道具 舉報

10#
ID:1002664 發表于 2022-1-26 14:52 | 只看該作者
lkc8210 發表于 2022-1-26 09:43
TMR_XX_ACC是變數,記錄系統走了多少個循環
PWM是用定時器中斷來寫更好,但初入門用delay比較好理解
當 ...

您的代碼好短,能簡單實現功能,我看b站學好幾天代碼一大堆需要的實現不了還出錯,如果可以這個開關快慢暗亮是不是可以在 void key里面實現,main里面我直接切換模式?key里面就是消抖按鍵時長貌似不能,在main里面切換模式,mode里面開關又出問題了,要么開不了,要么關不了。。啊腦子不夠了,您有空可以直接寫我想的這個程序我看看嘛,開時慢到快暗到亮,可以切換模式,關亮到暗快到慢結束嘛。碼代碼都懵了,碼完keil也沒報錯就是功能不對大佬私聊消息看看吧
回復

使用道具 舉報

11#
ID:161164 發表于 2022-1-26 16:34 | 只看該作者
繼續加功能

之前弄了由暗到亮由慢到快
現在再加個變數和邏輯來實現由亮到暗由快到慢再關機


  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295
  5. sbit key1=P3^0;
  6. u16 TMR_XX_ACC;
  7. u16 TMR_XX_PRE = 500;
  8. u8 PWM = 1;
  9. u8 index = 0;
  10. bit Power_On = 1;
  11. void delayus(u8 x)
  12. {
  13.         while(x--);
  14. }
  15. void main()
  16. {
  17.         while (1)
  18.         {
  19.                 if(PWM > 0)
  20.                 {
  21.                         P1 = ~(0x01 << index);
  22.                         delayus(PWM);
  23.                 }
  24.                 P1 = 0xFF;
  25.                 delayus(100 - PWM);
  26.                 if(++TMR_XX_ACC >= TMR_XX_PRE)
  27.                 {
  28.                         TMR_XX_ACC = 0;
  29.                         if(Power_On)
  30.                         {
  31.                                 if(PWM < 99)
  32.                                 {
  33.                                         PWM++;
  34.                                 }
  35.                                 else
  36.                                         Power_On = 0;
  37.                         }
  38.                         else
  39.                         {
  40.                                 if(PWM > 0)
  41.                                 {
  42.                                         PWM--;
  43.                                 }
  44.                         }
  45.                         index = ++index % 8;
  46.                         if(index == 0)
  47.                                 if(Power_On)
  48.                                 {
  49.                                         if(TMR_XX_PRE > 50) //固定到快
  50.                                         {
  51.                                                 TMR_XX_PRE -= 50;
  52.                                         }
  53.                                 }
  54.                                 else
  55.                                 {
  56.                                         if(TMR_XX_PRE < 500) //固定到快
  57.                                         {
  58.                                                 TMR_XX_PRE += 50;
  59.                                         }
  60.                                 }
  61.                 }
  62.         }
  63. }
復制代碼


加一段按鍵代碼去控制開機還是關機

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295
  5. sbit key1=P3^0;
  6. u16 TMR_XX_ACC;
  7. u16 TMR_XX_PRE = 500;
  8. u8 PWM = 1;
  9. u8 index = 0;
  10. bit Power_On = 1;
  11. void key_Proc()
  12. {
  13.         static u16 Delay_XD=0;                        //消抖計數
  14.         if(!key1)
  15.         {
  16.                 if(Delay_XD<0xFFFF)Delay_XD++;
  17.                 if(Delay_XD==25)                        //消抖
  18.                 {
  19.                         if(!key1)Power_On ^= 1;
  20.                 }
  21.         }
  22.         else                                                        //按鍵抬起
  23.                 Delay_XD=0;                                        //Delay_XD清0
  24. }
  25. void delayus(u8 x)
  26. {
  27.         while(x--);
  28. }
  29. void main()
  30. {
  31.         while (1)
  32.         {
  33.                 if(PWM > 0)
  34.                 {
  35.                         P1 = ~(0x01 << index);
  36.                         delayus(PWM);
  37.                 }
  38.                 P1 = 0xFF;
  39.                 delayus(100 - PWM);
  40.                 key_Proc();
  41.                 if(++TMR_XX_ACC >= TMR_XX_PRE)
  42.                 {
  43.                         TMR_XX_ACC = 0;
  44.                         if(Power_On)
  45.                         {
  46.                                 if(PWM < 99) PWM++;
  47.                         }
  48.                         else
  49.                         {
  50.                                 if(PWM > 0) PWM--;
  51.                         }
  52.                         index = ++index % 8;
  53.                         if(index == 0)
  54.                                 if(Power_On)
  55.                                 {
  56.                                         if(TMR_XX_PRE > 50) //固定到快
  57.                                         {
  58.                                                 TMR_XX_PRE -= 50;
  59.                                         }
  60.                                 }
  61.                                 else
  62.                                 {
  63.                                         if(TMR_XX_PRE < 500) //固定到快
  64.                                         {
  65.                                                 TMR_XX_PRE += 50;
  66.                                         }
  67.                                 }
  68.                 }
  69.         }
  70. }
復制代碼
回復

使用道具 舉報

12#
ID:1002664 發表于 2022-1-27 08:46 | 只看該作者
lkc8210 發表于 2022-1-26 16:34
繼續加功能

之前弄了由暗到亮由慢到快

謝謝大佬 今天又有得琢磨,但是肯定要簡單些了
回復

使用道具 舉報

13#
ID:908826 發表于 2022-1-27 09:05 | 只看該作者
要不先去看看呼吸燈的寫法?進階的玩一下,再回頭玩這個,會很簡單的,就是編程邏輯和思路的問題
回復

使用道具 舉報

14#
ID:1002664 發表于 2022-1-27 13:10 來自手機 | 只看該作者
13205495918 發表于 2022-1-27 09:05
要不先去看看呼吸燈的寫法?進階的玩一下,再回頭玩這個,會很簡單的,就是編程邏輯和思路的問題

呼吸燈會寫,但是代碼沒這個短,怎么固定值,頭有點亂
回復

使用道具 舉報

15#
ID:1002664 發表于 2022-1-27 14:29 | 只看該作者
lkc8210 發表于 2022-1-26 16:34
繼續加功能

之前弄了由暗到亮由慢到快

研究懂了,那么切換led亮的顆數能,現在是0x01<<index我保留,增加0x03<<index的亮法,啟動不了。。。

void key_Proc()
{
                        count=0;
        if(!key1)
        
        if(key1==0)
        {
                if(count<501)count++;

                if(count==500)//長按
                {
                        ++MODE;
                        if(MODE>3)
                                MODE=1;
                }
                                                               
        }   
        else
        {
                if(count>20 && count<500)//短按
                { Power_On=~Power_On;
                        if(Power_On)
                        {
                                slow=MODE;//保存鍵值
                                MODE=0;//關閉流水
                        }
                        else MODE=slow;//還原鍵值
                     
                }
                count=0;
        }                                 
}
void main()
{
    while (1)
     {

           key_Proc();
                                        switch(MODE)
                                        {
                                                case 0: P0=0xFF;break;
                                                case 1: mode1();break;
                                                case 2: mode1();break;
                                        }
         
        }
}

void mode1(void)
{
                   if(PWM > 0)
          {
           P0 = ~(0x01 << index);
          delayus(PWM);
          }
           P0 = 0xFF;
           delayus(100 - PWM);
        if(++TMR_XX_ACC >= TMR_XX_PRE)
             {
              TMR_XX_ACC = 0;
              if(Power_On)
             {
               if(PWM < 99)PWM++;
                                                         
             }
                   else
             {
                  if(PWM > 0) PWM--;
             }
             index = ++index % 8;
          if(index == 0)
          if(Power_On)
      {
         if(TMR_XX_PRE > 50) //固定到快
            {
             TMR_XX_PRE -= 50;
                                                }
       }
                  else
             {
            if(TMR_XX_PRE < 500) //固定到快
             {
              TMR_XX_PRE += 50;
                       }
                    }
                }
                                                        }
回復

使用道具 舉報

16#
ID:1002664 發表于 2022-1-27 14:37 | 只看該作者
lkc8210 發表于 2022-1-26 16:34
繼續加功能

之前弄了由暗到亮由慢到快

我也試著在主程序main里面switch(),case0:直接啟動流水,case1:流水模式2 。不行
回復

使用道具 舉報

17#
ID:161164 發表于 2022-1-27 22:06 | 只看該作者
最后再加上長短按功能和多個流水模式就達成了樓主的要求

  1. #include <reg52.h>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. typedef         unsigned long        u32;  //0 to 4294967295
  5. sbit key1 = P3 ^ 0;
  6. u16 TMR_XX_ACC;
  7. u16 TMR_XX_PRE = 500;
  8. u8 PWM = 1;
  9. u8 index = 0;
  10. u8 MODE = 1;
  11. bit Power_On = 1;
  12. unsigned char dat1[4] = {0xf1, 0xf2, 0xf4, 0xf8};
  13. unsigned char dat2[4] = {0xfc, 0xf9, 0xf3, 0xf6};
  14. unsigned char dat3[4] = {0xfe, 0xfd, 0xfb, 0xf7};

  15. void key_Proc()
  16. {
  17.     static u16 Delay_XD = 0;                      //消抖計數
  18.     static u16 Min_T = 25;
  19.     static u16 Max_T = 2500;

  20.     if(!key1)
  21.     {
  22.         if(Delay_XD < 0xFFFF)Delay_XD++;
  23.         //else Delay_XD = 0;                //連按功能
  24.         if(Delay_XD == Max_T)                        //長按
  25.         {
  26.             MODE = ++MODE % 3;
  27.         }
  28.     }
  29.     else                                                         //按鍵抬起
  30.     {
  31.         if(Delay_XD > Min_T && Delay_XD < Max_T)                        //短按
  32.         {
  33.             Power_On ^= 1;
  34.         }
  35.         Delay_XD = 0;                                      //Delay_XD清0
  36.     }
  37. }
  38. void delayus(u8 x)
  39. {
  40.     while(x--);
  41. }
  42. void main()
  43. {
  44.     while (1)
  45.     {   
  46.         if(PWM > 0) {
  47.             switch (MODE)
  48.             {
  49.             case 0:
  50.                 P1 = dat1[index];
  51.                 break;
  52.             case 1:
  53.                 P1 = dat2[index];
  54.                 break;
  55.             case 2:
  56.                 P1 = dat3[index];
  57.                 break;
  58.             }
  59.             delayus(PWM);
  60.         }
  61.         P1 = 0xFF;
  62.         delayus(100 - PWM);
  63.         key_Proc();
  64.         if(++TMR_XX_ACC >= TMR_XX_PRE)
  65.         {   TMR_XX_ACC = 0;
  66.             if(Power_On)
  67.             {
  68.                 if(PWM < 99) PWM++;
  69.             } else {
  70.                 if(PWM > 0) PWM--;
  71.             }
  72.             index = ++index % 4;
  73.             if(index == 0)
  74.                 if(Power_On)
  75.                 {
  76.                     if(TMR_XX_PRE > 50) //固定到快
  77.                     {
  78.                         TMR_XX_PRE -= 50;
  79.                     }
  80.                 } else {
  81.                     if(TMR_XX_PRE < 500) //固定到快
  82.                     {
  83.                         TMR_XX_PRE += 50;
  84.                     }
  85.                 }
  86.         }
  87.     }
  88. }
復制代碼
回復

使用道具 舉報

18#
ID:161164 發表于 2022-1-27 22:07 | 只看該作者
菜鳥一個622 發表于 2022-1-27 14:37
我也試著在主程序main里面switch(),case0:直接啟動流水,case1:流水模式2 。不行

放錯地方了
回復

使用道具 舉報

19#
ID:1002664 發表于 2022-1-28 09:30 | 只看該作者

該放那里,大佬
回復

使用道具 舉報

20#
ID:1002664 發表于 2022-1-28 10:46 | 只看該作者
lkc8210 發表于 2022-1-27 22:06
最后再加上長短按功能和多個流水模式就達成了樓主的要求

謝謝大佬,有的學,來琢磨了
回復

使用道具 舉報

21#
ID:161164 發表于 2022-1-28 13:50 | 只看該作者

參考我的回覆
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人性视频免费网站 | 麻豆天堂 | 两性午夜视频 | 久久区二区 | 亚洲视频在线播放 | 久久久久久亚洲精品不卡 | 91视频观看 | 欧美一级二级在线观看 | 国产韩国精品一区二区三区 | 国产精品一区二区av | 久久精片 | 日韩福利 | 国产一区精品 | 一级片网址 | 成人欧美一区二区 | 日韩中文字幕第一页 | 国产成人99久久亚洲综合精品 | 91精品国产乱码久久久久久久久 | 91在线精品一区二区 | 亚洲精品日韩一区二区电影 | 91精品国产手机 | 久久国产精品亚洲 | 国产中的精品av涩差av | 一区二区三区免费 | 国产三级一区二区 | 欧美日韩一区二区三区不卡视频 | 日本黄色大片免费 | 亚洲一区二区中文字幕 | 毛片电影| 伊人91在线 | 中文字幕第二区 | 日本久草视频 | 作爱视频免费看 | 99精品久久99久久久久 | 一区二区三区四区不卡视频 | 毛片免费观看视频 | 欧美日韩精品一区 | 粉嫩粉嫩芽的虎白女18在线视频 | 久草视频观看 | 精品国产乱码久久久久久丨区2区 | 亚洲一视频 |