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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5579|回復(fù): 12
收起左側(cè)

關(guān)于單片機(jī)IO口模擬實(shí)現(xiàn)呼吸燈的疑問

[復(fù)制鏈接]
ID:258164 發(fā)表于 2018-12-18 11:34 | 顯示全部樓層 |閱讀模式
如何利用一個定時器和IO口實(shí)現(xiàn)LED有呼吸的功能呢?因?yàn)槲业膯纹瑱C(jī)資源有限,沒有硬件的PWM,所以想使用定時器來實(shí)現(xiàn)調(diào)節(jié)占空比,原理我是知道的,但是邏輯感覺還是沒有理清楚。

我看網(wǎng)上很多都是用的延時或者多個定時器,如果我只有一個定時器該怎么實(shí)現(xiàn)呢?我的定時周期多少合適?
回復(fù)

使用道具 舉報

ID:111517 發(fā)表于 2018-12-18 13:56 | 顯示全部樓層
如果用一個定時器的話你,你可以用這個定時器來做一個節(jié)拍啊,假設(shè)節(jié)拍是100us,你定時器就設(shè)置為100us,然后再定義一個計(jì)數(shù)器變量放在定時器中斷里面,然后每計(jì)數(shù)到100就重置,這樣的話周期就是10ms,你可以在主函數(shù)里利用這個變量來更改占空比
回復(fù)

使用道具 舉報

ID:94031 發(fā)表于 2018-12-18 14:21 | 顯示全部樓層
參考程序:
#include<reg51.h>
void Delay1(int del)
{
        int i,j;
        for(i=0; i<del; i++)
        for(j=0; j<1827; j++)   
        ;
}
void Delay(unsigned int t)
{
while(--t);
}
//函數(shù)聲明
unsigned int z,y;
void main (void)//主函數(shù)
{
        unsigned int CYCLE=400,PWM_LOW=0;//定義周期并賦值
        while (1)         //主循環(huán)
        {

/*--------整排LED燈呼吸---------*/
               
                Delay1(100);                                                                 //加延時,可以看到熄滅的過程(下面程序同理)
                for(PWM_LOW=1;PWM_LOW<CYCLE;PWM_LOW++)           //PWM_LOW表示低
                        {
                                P1=0x00;                                       
                                Delay(PWM_LOW);
                                P1=0xff;
                                Delay(CYCLE-PWM_LOW);
                        }
                P1=0xff;                                                                                
                for(PWM_LOW=CYCLE-1;PWM_LOW>0;PWM_LOW--)         //與逐漸變亮相反的過程
                        {
                                   P1=0x00;                                                        //點(diǎn)亮LED
                                   Delay(PWM_LOW);
                                   P1=0xff;                                                        //熄滅LED
                                  Delay(CYCLE-PWM_LOW);                                //主循環(huán)中添加其他需要一直工作的程序,延時長度,600次循環(huán)中從599減至1
                        }

}
}
回復(fù)

使用道具 舉報

ID:258164 發(fā)表于 2018-12-18 14:55 | 顯示全部樓層
滄浪 發(fā)表于 2018-12-18 13:56
如果用一個定時器的話你,你可以用這個定時器來做一個節(jié)拍啊,假設(shè)節(jié)拍是100us,你定時器就設(shè)置為100us,然 ...

呼吸燈一般要求是3s的周期,也就是說要在3s的時間里實(shí)現(xiàn)漸亮到漸滅再到漸亮的過程。我現(xiàn)在的定時器周期是10ms,那么我怎么利用變量來改變占空比呢,怎么和LED的高低電平配合起來
回復(fù)

使用道具 舉報

ID:258164 發(fā)表于 2018-12-18 14:55 | 顯示全部樓層
xuyaqi 發(fā)表于 2018-12-18 14:21
參考程序:
#include
void Delay1(int del)

你這個是延時的辦法,對于我的程序來說效率太低了,如果要使用定時器該怎么做呢?
回復(fù)

使用道具 舉報

ID:94031 發(fā)表于 2018-12-18 16:50 | 顯示全部樓層
HelloPan111 發(fā)表于 2018-12-18 14:55
你這個是延時的辦法,對于我的程序來說效率太低了,如果要使用定時器該怎么做呢?

設(shè)定好定時器中斷時間,數(shù)中斷次數(shù)求得延時時間。
回復(fù)

使用道具 舉報

ID:155507 發(fā)表于 2018-12-18 18:50 | 顯示全部樓層
參考程序:

  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* 如果要在程序中使用此代碼,請?jiān)诔绦蛑凶⒚魇褂昧薙TC的資料及程序        */
  5. /*---------------------------------------------------------------------*/


  6. /*************  功能說明    **************

  7. 使用Timer0模擬16通道PWM驅(qū)動程序。

  8. 輸出為 P1.0 ~ P1.7, P2.0 ~ P2.7, 對應(yīng) PWM0 ~ PWM15.

  9. 定時器中斷頻率一般不要超過100KHZ, 留足夠的時間給別的程序運(yùn)行.

  10. 本例子使用11.0592MHZ時鐘, 25K的中斷頻率, 250級PWM, 周期為10ms.

  11. 中斷里處理的時間不超過6us, 占CPU時間大約為15%.

  12. ******************************************/

  13. #include    <reg52.h>

  14. #define MAIN_Fosc       11059200UL  //定義主時鐘
  15. #define Timer0_Rate     25000       //中斷頻率


  16. typedef     unsigned char   u8;
  17. typedef     unsigned int    u16;
  18. typedef     unsigned long   u32;

  19. sfr AUXR = 0x8E;

  20. sfr P1M1 = 0x91;    //PxM1.n,PxM0.n     =00--->Standard,    01--->push-pull
  21. sfr P1M0 = 0x92;    //                  =10--->pure input,  11--->open drain
  22. sfr P0M1 = 0x93;
  23. sfr P0M0 = 0x94;
  24. sfr P2M1 = 0x95;
  25. sfr P2M0 = 0x96;
  26. sfr P3M1 = 0xB1;
  27. sfr P3M0 = 0xB2;
  28. sfr P4M1 = 0xB3;
  29. sfr P4M0 = 0xB4;
  30. sfr P5M1 = 0xC9;
  31. sfr P5M0 = 0xCA;
  32. sfr P6M1 = 0xCB;
  33. sfr P6M0 = 0xCC;
  34. sfr P7M1 = 0xE1;
  35. sfr P7M0 = 0xE2;

  36. #define Timer0_Reload   (65536UL -(MAIN_Fosc / Timer0_Rate))        //Timer 0 重裝值

  37. //************** PWM8 變量和常量以及IO口定義 ***************
  38. //********************  8通道8 bit 軟PWM    ********************

  39. #define     PWM_DUTY_MAX    250 // 0~255    PWM周期, 最大255
  40. #define     PWM_ON          1   // 定義占空比的電平, 1 或 0

  41. #define     PWM_OFF         (!PWM_ON)
  42. #define     PWM_ALL_ON      (0xff * PWM_ON)

  43. u8 bdata PWM_temp1,PWM_temp2;       //影射一個RAM,可位尋址,輸出時同步刷新
  44. sbit    P_PWM0  =   PWM_temp1^0;    //  定義影射RAM每位對應(yīng)的IO
  45. sbit    P_PWM1  =   PWM_temp1^1;
  46. sbit    P_PWM2  =   PWM_temp1^2;
  47. sbit    P_PWM3  =   PWM_temp1^3;
  48. sbit    P_PWM4  =   PWM_temp1^4;
  49. sbit    P_PWM5  =   PWM_temp1^5;
  50. sbit    P_PWM6  =   PWM_temp1^6;
  51. sbit    P_PWM7  =   PWM_temp1^7;
  52. sbit    P_PWM8  =   PWM_temp2^0;
  53. sbit    P_PWM9  =   PWM_temp2^1;
  54. sbit    P_PWM10 =   PWM_temp2^2;
  55. sbit    P_PWM11 =   PWM_temp2^3;
  56. sbit    P_PWM12 =   PWM_temp2^4;
  57. sbit    P_PWM13 =   PWM_temp2^5;
  58. sbit    P_PWM14 =   PWM_temp2^6;
  59. sbit    P_PWM15 =   PWM_temp2^7;

  60. u8  pwm_duty;       //周期計(jì)數(shù)值
  61. u8  pwm[16];        //pwm0~pwm15 為0至15路PWM的寬度值

  62. bit     B_1ms;
  63. u8      cnt_1ms;
  64. u8      cnt_20ms;

  65. /**********************************************/
  66. void main(void)
  67. {
  68.     u8  i;
  69.    
  70.     P0M0 = 0x00;
  71.     P0M1 = 0x00;
  72.     P1M0 = 0x00;
  73.     P1M1 = 0x00;
  74.     P2M0 = 0x00;
  75.     P2M1 = 0x00;
  76.     P3M0 = 0x00;
  77.     P3M1 = 0x00;
  78.     P4M0 = 0x00;
  79.     P4M1 = 0x00;
  80.     P5M0 = 0x00;
  81.     P5M1 = 0x00;
  82.     P6M0 = 0x00;
  83.     P6M1 = 0x00;
  84.     P7M0 = 0x00;
  85.     P7M1 = 0x00;

  86.     AUXR |=  (1<<7);    // Timer0 set as 1T mode
  87.     TMOD &= ~(1<<2);    // Timer0 set as Timer
  88.     TMOD &= ~0x03;      // Timer0 set as 16 bits Auto Reload
  89.     TH0 = Timer0_Reload / 256;  //Timer0 Load
  90.     TL0 = Timer0_Reload % 256;
  91.     ET0 = 1;        //Timer0 Interrupt Enable
  92.     PT0 = 1;        //高優(yōu)先級
  93.     TR0 = 1;        //Timer0 Run
  94.     EA = 1;         //打開總中斷

  95.     cnt_1ms = Timer0_Rate / 1000;   //1ms計(jì)數(shù)
  96.     cnt_20ms = 20;
  97.    
  98.     for(i=0; i<16; i++)     pwm[i] = i * 15 + 15;   //給PWM一個初值
  99.    
  100.     while(1)
  101.     {
  102.         if(B_1ms)   //1ms到
  103.         {
  104.             B_1ms = 0;
  105.             if(--cnt_20ms == 0) //PWM 20ms改變一階
  106.             {
  107.                 cnt_20ms = 20;
  108.                 for(i=0; i<16; i++) pwm[i]++;
  109.             }
  110.         }
  111.     }
  112. }


  113. /********************** Timer0 1ms中斷函數(shù) ************************/
  114. void timer0 (void) interrupt 1
  115. {
  116.     P1 = PWM_temp1;         //影射RAM輸出到實(shí)際的PWM端口
  117.     P2 = PWM_temp2;
  118.         
  119.     if(++pwm_duty == PWM_DUTY_MAX)      //PWM周期結(jié)束,重新開始新的周期
  120.     {
  121.         pwm_duty = 0;
  122.         PWM_temp1 = PWM_ALL_ON;
  123.         PWM_temp2 = PWM_ALL_ON;
  124.     }
  125.     ACC = pwm_duty;
  126.     if(ACC == pwm[0])       P_PWM0  = PWM_OFF;  //判斷PWM占空比是否結(jié)束
  127.     if(ACC == pwm[1])       P_PWM1  = PWM_OFF;
  128.     if(ACC == pwm[2])       P_PWM2  = PWM_OFF;
  129.     if(ACC == pwm[3])       P_PWM3  = PWM_OFF;
  130.     if(ACC == pwm[4])       P_PWM4  = PWM_OFF;
  131.     if(ACC == pwm[5])       P_PWM5  = PWM_OFF;
  132.     if(ACC == pwm[6])       P_PWM6  = PWM_OFF;
  133.     if(ACC == pwm[7])       P_PWM7  = PWM_OFF;
  134.     if(ACC == pwm[8])       P_PWM8  = PWM_OFF;
  135.     if(ACC == pwm[9])       P_PWM9  = PWM_OFF;
  136.     if(ACC == pwm[10])      P_PWM10 = PWM_OFF;
  137.     if(ACC == pwm[11])      P_PWM11 = PWM_OFF;
  138.     if(ACC == pwm[12])      P_PWM12 = PWM_OFF;
  139.     if(ACC == pwm[13])      P_PWM13 = PWM_OFF;
  140.     if(ACC == pwm[14])      P_PWM14 = PWM_OFF;
  141.     if(ACC == pwm[15])      P_PWM15 = PWM_OFF;

  142.     if(--cnt_1ms == 0)
  143.     {
  144.         cnt_1ms = Timer0_Rate / 1000;
  145.         B_1ms = 1;      // 1ms標(biāo)志
  146.     }
  147. }
復(fù)制代碼



  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC15F4K60S4 系列 定時器軟件模擬PWM舉例-------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
  7. /* --- Web: www.STCMCU.com --------------------------------------------*/
  8. /* --- Web: www.GXWMCU.com --------------------------------------------*/
  9. /* 如果要在程序中使用此代碼,請?jiān)诔绦蛑凶⒚魇褂昧薙TC的資料及程序        */
  10. /* 如果要在文章中應(yīng)用此代碼,請?jiān)谖恼轮凶⒚魇褂昧薙TC的資料及程序        */
  11. /*---------------------------------------------------------------------*/

  12. //本示例在Keil開發(fā)環(huán)境下請選擇Intel的8058芯片型號進(jìn)行編譯
  13. //若無特別說明,工作頻率一般為11.0592MHz


  14. #include "reg51.h"

  15. //#define PWM6BIT   64              //6-bit PWM 周期數(shù)
  16. #define PWM8BIT     256             //8-bit PWM 周期數(shù)
  17. //#define PWM10BIT  1024            //10-bit PWM 周期數(shù)
  18. //#define PWM16BIT  65536           //16-bit PWM 周期數(shù)

  19. #define HIGHDUTY 64                 //高電平周期數(shù)(占空比64/256=25%)
  20. #define LOWDUTY  (PWM8BIT-HIGHDUTY) //低電平周期數(shù)

  21. sfr P0M1 = 0x93;
  22. sfr P0M0 = 0x94;
  23. sfr P1M1 = 0x91;
  24. sfr P1M0 = 0x92;
  25. sfr P2M1 = 0x95;
  26. sfr P2M0 = 0x96;
  27. sfr P3M1 = 0xb1;
  28. sfr P3M0 = 0xb2;
  29. sfr P4M1 = 0xb3;
  30. sfr P4M0 = 0xb4;
  31. sfr P5M1 = 0xC9;
  32. sfr P5M0 = 0xCA;
  33. sfr P6M1 = 0xCB;
  34. sfr P6M0 = 0xCC;
  35. sfr P7M1 = 0xE1;
  36. sfr P7M0 = 0xE2;

  37. sfr AUXR      = 0x8e;               //輔助寄存器
  38. sfr INT_CLKO  = 0x8f;               //時鐘輸出控制寄存器
  39. sbit T0CLKO   = P3^5;               //定時器0的時鐘輸出口

  40. bit flag;

  41. //定時器0中斷服務(wù)程序
  42. void tm0() interrupt 1
  43. {
  44.     flag = !flag;                   //反轉(zhuǎn)PWM的輸出標(biāo)志
  45.     if (flag)
  46.     {
  47.         TL0 = (65536-HIGHDUTY);     //準(zhǔn)備高電平的重載值
  48.         TH0 = (65536-HIGHDUTY) >> 8;
  49.     }
  50.     else
  51.     {
  52.         TL0 = (65536-LOWDUTY);      //準(zhǔn)備低電平的重載值
  53.         TH0 = (65536-LOWDUTY) >> 8;
  54.     }
  55. }

  56. void main()
  57. {
  58.     P0M0 = 0x00;
  59.     P0M1 = 0x00;
  60.     P1M0 = 0x00;
  61.     P1M1 = 0x00;
  62.     P2M0 = 0x00;
  63.     P2M1 = 0x00;
  64.     P3M0 = 0x00;
  65.     P3M1 = 0x00;
  66.     P4M0 = 0x00;
  67.     P4M1 = 0x00;
  68.     P5M0 = 0x00;
  69.     P5M1 = 0x00;
  70.     P6M0 = 0x00;
  71.     P6M1 = 0x00;
  72.     P7M0 = 0x00;
  73.     P7M1 = 0x00;

  74.     AUXR = 0x80;                    //定時器0為1T模式
  75.     INT_CLKO = 0x01;                //使能定時器0的時鐘輸出功能
  76.     TMOD &= 0xf0;                   //設(shè)置定時器0為模式0(16位自動重裝載)
  77.     TL0 = (65536-LOWDUTY);          //初始化定時器初值和重裝值
  78.     TH0 = (65536-LOWDUTY) >> 8;
  79.     T0CLKO = 1;                     //初始化時鐘輸出腳(軟PWM口)
  80.     flag = 0;                       //初始化標(biāo)志位
  81.     TR0 = 1;                        //定時器0開始計(jì)時
  82.     ET0 = 1;                        //使能定時器0中斷
  83.     EA = 1;
  84.     while (1);
  85. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:258164 發(fā)表于 2018-12-18 20:32 | 顯示全部樓層
xuyaqi 發(fā)表于 2018-12-18 16:50
設(shè)定好定時器中斷時間,數(shù)中斷次數(shù)求得延時時間。

這樣還是不行啊,我的目標(biāo)是最好在中斷里實(shí)現(xiàn)呼吸燈的效果,如果是在主循環(huán)里的話,對我的程序效率來說太差了。
回復(fù)

使用道具 舉報

ID:258164 發(fā)表于 2018-12-18 20:34 | 顯示全部樓層

謝謝拉,不過你給的這個程序看著有點(diǎn)亂啊,我看了還是沒有太理解思路是什么
回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2018-12-19 22:46 | 顯示全部樓層
樓上的程序太恐怖了
給你一個算法,自己去寫代碼
模擬PWM的頻率設(shè)定為1KHZ,如果你要PWM的分辨率達(dá)到1%,那你就得把寄存器中斷設(shè)定為10uS一次了,10uS進(jìn)入一次中斷,然后,再在寄存器的中斷中設(shè)定占空比,但我覺得這不太現(xiàn)實(shí),10uS都沒有能執(zhí)行幾條指令,還不如用兩個定時器,C不會,幫不上你
但PWM的頻率設(shè)定為1KHZ是對的,我測試過很多的LED手電,呼吸燈的頻率都是1024uS的
但程序不會很大的,肯定是沒有上面的那么多代碼的,我就是用匯編也不會有那么代碼的,更何況是C呢

回復(fù)

使用道具 舉報

ID:258164 發(fā)表于 2018-12-20 17:55 | 顯示全部樓層
Y_G_G 發(fā)表于 2018-12-19 22:46
樓上的程序太恐怖了
給你一個算法,自己去寫代碼
模擬PWM的頻率設(shè)定為1KHZ,如果你要PWM的分辨率達(dá)到1%,那 ...

我其實(shí) 不需要呼吸燈的效果有多好,只要肉眼看到的效果是呼吸的就行。
另外如果用兩個定時器的話,程序邏輯該是怎么樣的呢
回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2018-12-20 23:08 | 顯示全部樓層
完全的算法不好說,大概就是進(jìn)入一個定時器就累加一次變量,再把這個變量當(dāng)成另一個定時器的中斷時間,然后關(guān)閉當(dāng)前定時器,再打開另一個定時器,中斷返回
總的來說就是進(jìn)入中斷就關(guān)閉當(dāng)前定時器,由另一個定時器來打開
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕一区二区三区四区五区 | 日本大片在线播放 | 久久久精品视频免费 | 中文字幕不卡在线88 | 久久精品国产清自在天天线 | 亚洲97| 91久久久久久久久 | 亚洲一区二区av | 日韩一区二区三区视频在线观看 | 91麻豆蜜桃一区二区三区 | 久久精品男人的天堂 | 日本不卡免费新一二三区 | 欧美婷婷 | 欧美中文在线 | 国产成人精品福利 | 成人免费观看男女羞羞视频 | 亚洲一区 中文字幕 | 国产精品久久久久久久久久久久午夜片 | 亚洲欧美aⅴ | 久久一区二区三区四区五区 | 国产高清免费 | 欧美精品video | 精品欧美一区二区精品久久久 | 国产精品精品久久久久久 | 久久综合一区 | 一区二区高清 | aaa在线观看| 污片在线免费观看 | 亚洲一级黄色 | 亚洲三级在线观看 | 三区四区在线观看 | 日韩精品在线观看视频 | 欧美中文字幕一区二区三区亚洲 | 国产高清在线精品 | 欧美精品在线视频 | 亚洲人成人一区二区在线观看 | 精品av| 国产亚洲黄色片 | 麻豆久久久9性大片 | 欧美日韩精品一区二区三区视频 | 欧美激情精品久久久久 |