找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

帖子
查看: 14143|回復(fù): 30
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)測(cè)量PWM脈沖寬度LCD1602顯示當(dāng)前PWM占空比頻率

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:455286 發(fā)表于 2018-12-26 12:22 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
此程序通過(guò)兩個(gè)定時(shí)器一個(gè)外部中斷,測(cè)量PWM高電平時(shí)間以及周期,計(jì)算并在1602顯示出占空比 周期 高電平時(shí)間,只需讓脈沖在P3^2口輸入即能測(cè)得數(shù)據(jù)。。

單片機(jī)源程序如下:
  1. #include <reg52.h>
  2. #include <LCD1602.h>

  3. typedef unsigned char uint8;
  4. typedef unsigned int  uint16;//數(shù)據(jù)類(lèi)型重定義

  5. uint8 count = 0; //計(jì)進(jìn)入外部中斷次數(shù)
  6. bit flag = 1;  //捕獲結(jié)束標(biāo)志位
  7. long Pwm_All; //PWM的周期
  8. long Pwm_High; //PWM的高電平時(shí)間                   占空比=Pwm_High/Pwm_All
  9. void delay(long i)
  10. {
  11.         while(i--);
  12. }

  13. void Interrupt_Init()
  14. {
  15.         /*定時(shí)器1為工作模式1 16位計(jì)數(shù)器 由TR1直接啟動(dòng)
  16.                 定時(shí)器0為工作模式1 16位計(jì)數(shù)器 由GATE和TR0共同啟動(dòng)*/
  17.         TMOD = 0x19;
  18.         
  19.         TH1 = 0;
  20.         TL1 = 0;
  21.         TH0 = 0;
  22.         TL0 = 0;
  23.         
  24.         IT0 = 1;//下降沿觸發(fā)
  25.         IT1 = 1;
  26.         //TR0 = 1; //GATE高電平啟動(dòng)
  27.         
  28.         EX0 = 1;
  29.         EA = 1;        
  30. }

  31. void main()
  32. {
  33.         uint16 Pwm_percentage; //PWM占空比
  34.         Interrupt_Init();
  35.         LCD1602_Initialize( );
  36.         LCD1602_PrintString(1,1,"ALL:");
  37.         LCD1602_PrintString(1,10,"us");
  38.         LCD1602_PrintString(2,1,"HIGH:");
  39.         LCD1602_PrintString(2,11,"us");
  40.         while(1)
  41.         {
  42.                
  43.                 if(flag)
  44.                 {
  45.                         Pwm_percentage = Pwm_High*1000 / Pwm_All;
  46.                         LCD1602_PrintChar(1,12,0x30+Pwm_percentage/100);
  47.                         LCD1602_PrintChar(1,13,0x30+Pwm_percentage%100/10);
  48.                         LCD1602_PrintChar(1,14,'.');
  49.                         LCD1602_PrintChar(1,15,0x30+Pwm_percentage%10);
  50.                         LCD1602_PrintChar(1,16,'%');
  51.                         
  52.                         LCD1602_PrintChar(1,5,0x30+Pwm_All/10000);
  53.                         LCD1602_PrintChar(1,6,0x30+Pwm_All%10000/1000);
  54.                         LCD1602_PrintChar(1,7,0x30+Pwm_All%1000/100);
  55.                         LCD1602_PrintChar(1,8,0x30+Pwm_All%100/10);
  56.                         LCD1602_PrintChar(1,9,0x30+Pwm_All%10);
  57.                         LCD1602_PrintChar(2,6,0x30+Pwm_High/10000);
  58.                         LCD1602_PrintChar(2,7,0x30+Pwm_High%10000/1000);
  59.                         LCD1602_PrintChar(2,8,0x30+Pwm_High%1000/100);
  60.                         LCD1602_PrintChar(2,9,0x30+Pwm_High%100/10);
  61.                         LCD1602_PrintChar(2,10,0x30+Pwm_High%10);
  62.                         flag = 0; //計(jì)算完一次清零
  63.                 }
  64.                 delay(70000);
  65.         }
  66.         
  67. }

  68. void EXTI0 () interrupt 0
  69. {
  70.                 count++;
  71.         if(count == 1) //第一次下降沿,啟動(dòng)定時(shí)器1
  72.         {
  73.                 TR1 = 1;
  74.                 TR0 = 1;
  75.         }
  76.         if(count == 2) //第二次下降沿,一整個(gè)周期完畢
  77.         {
  78.                 EX0 = 0; //關(guān)閉外部中斷,防止被其他打斷計(jì)算
  79.                 TR1 = 0;        //周期停止計(jì)數(shù)
  80.                 TR0 = 0;        //高電平時(shí)間停止計(jì)數(shù)
  81.                 Pwm_All = TH1; //獲取數(shù)據(jù)
  82.                 Pwm_All = (Pwm_All<<8)+TL1;
  83.                 Pwm_High = TH0;
  84.                 Pwm_High = (Pwm_High<<8)+TL0;
  85.                 TH1 = 0; //清零為下一次做準(zhǔn)備
  86.                 TL1 = 0;
  87.                 TH0 = 0;
  88.                 TL0 = 0;
  89.                 count = 0;
  90.                 flag = 1;        
  91.                 EX0 = 1; //開(kāi)啟下一次計(jì)算
  92.                 TR1 = 0;
  93.                 TR0 = 0;
  94.         }
  95.         
  96. }
復(fù)制代碼

所有資料51hei提供下載:
PWM捕獲占空比.zip (45 KB, 下載次數(shù): 406)



評(píng)分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏24 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:455286 發(fā)表于 2018-12-26 18:33 | 只看該作者
里面注釋詳細(xì),不懂的歡迎提問(wèn)
回復(fù)

使用道具 舉報(bào)

板凳
ID:458917 發(fā)表于 2019-1-1 18:38 來(lái)自觸屏版 | 只看該作者
呢能不能改成在4位的led數(shù)碼管上顯示脈沖寬度的,不知道代碼怎么改
回復(fù)

使用道具 舉報(bào)

地板
ID:277781 發(fā)表于 2019-3-11 21:39 | 只看該作者
初學(xué)菜鳥(niǎo),謝謝!學(xué)習(xí)了!
回復(fù)

使用道具 舉報(bào)

5#
ID:409013 發(fā)表于 2019-4-27 10:58 | 只看該作者
可以只用一個(gè)定時(shí)器來(lái)實(shí)現(xiàn)嗎,大佬有空看一下我的求助
http://www.torrancerestoration.com/bbs/dpj-157890-1.html
回復(fù)

使用道具 舉報(bào)

6#
ID:539092 發(fā)表于 2019-5-27 22:36 | 只看該作者
如果要用定時(shí)中斷測(cè)頻率為100hz的方波的周期并在LCD1602上表示出來(lái),程序應(yīng)該怎么改呢
回復(fù)

使用道具 舉報(bào)

7#
ID:470926 發(fā)表于 2019-6-22 09:17 | 只看該作者
1179839709 發(fā)表于 2019-1-1 18:38
呢能不能改成在4位的led數(shù)碼管上顯示脈沖寬度的,不知道代碼怎么改

可以更改 P0口接上拉電阻接數(shù)碼管更改數(shù)碼管對(duì)應(yīng)的顯示就可以
回復(fù)

使用道具 舉報(bào)

8#
ID:578183 發(fā)表于 2019-7-5 16:24 | 只看該作者
請(qǐng)問(wèn)如何改變占空比,剛剛接觸PWM,不是很明白
回復(fù)

使用道具 舉報(bào)

9#
ID:575294 發(fā)表于 2019-7-5 16:46 | 只看該作者
請(qǐng)問(wèn)老哥,這個(gè)硬件原理圖您用哪個(gè)軟件做的呢?請(qǐng)問(wèn)是 3D MAX嗎?
回復(fù)

使用道具 舉報(bào)

10#
ID:480680 發(fā)表于 2019-7-21 21:45 | 只看該作者
懶惰的家伙 發(fā)表于 2019-7-5 16:24
請(qǐng)問(wèn)如何改變占空比,剛剛接觸PWM,不是很明白

#include <AT89X52.h>

#define MAX 0x50   //定時(shí)上限定義       占空比上限         下面通過(guò)定時(shí)器改變占空比
#define MIN 0x00   //定時(shí)下限定義       占空比下限
#define TIMELINE 11         //時(shí)間分頻常數(shù)
#define TRUE  1
#define FALSE 0             //標(biāo)志位常數(shù)

unsigned int TimeCounter;
bit ArrowFlg = 0;         //方向標(biāo)志位
unsigned char upCounter,downCounter;    //增加計(jì)數(shù)器和減少計(jì)數(shù)器

sbit LED=P0^0;

//T0的中斷服務(wù)子函數(shù)
void T0Deal() interrupt 1 using 0
{
        TH0=0xf1;
        TL0=0xf1;
        TR0=1;
        TimeCounter++;  //定時(shí)計(jì)數(shù)器增加
        if(TimeCounter == TIMELINE)
        {
                if((upCounter == MAX)&&(downCounter == MIN))  //計(jì)數(shù)方向標(biāo)志位切換
    {
      ArrowFlg = FALSE;
    }
                if((upCounter == MIN)&&(downCounter == MAX))
    {
      ArrowFlg= TRUE;
    }
                if(ArrowFlg == 1)   //如果是增加計(jì)數(shù)
    {
      upCounter++;
      downCounter--;
    }
                else               //如果是減少計(jì)數(shù)
    {
      upCounter--;
      downCounter++;
    }
                TimeCounter=0;
        }
}
//延時(shí)函數(shù)
void Delay(unsigned int i)
{
        unsigned int j;
        while(i--)
        {
                for(j=0;j<32;j++);     //延時(shí)
        }
}

void main()
{
        upCounter = MIN;
        downCounter = MAX;     //計(jì)數(shù)器初始化
        TMOD = 0x01;          //設(shè)置定時(shí)器工作方式
        TH0 = 0xF0;
        TL0 = 0xF0 ;          //T0初始化值
        EA = 1;
        ET0 = 1;              //開(kāi)中斷
        TR0 = 1;              //啟動(dòng)T0
        while(1)
        {
                LED=0;            //輸出變化的PWM波形
                Delay(downCounter);   
                LED=1;
                Delay(upCounter);
        }
}

回復(fù)

使用道具 舉報(bào)

11#
ID:588275 發(fā)表于 2019-7-23 23:48 | 只看該作者
求電路原理圖
回復(fù)

使用道具 舉報(bào)

12#
ID:544565 發(fā)表于 2019-8-16 12:21 來(lái)自觸屏版 | 只看該作者
學(xué)習(xí)一下哈
回復(fù)

使用道具 舉報(bào)

13#
ID:633597 發(fā)表于 2019-10-31 23:43 | 只看該作者
我是新手看不懂
回復(fù)

使用道具 舉報(bào)

14#
ID:385637 發(fā)表于 2019-11-1 15:16 | 只看該作者
有點(diǎn)沒(méi)搞明白這個(gè)占空比是怎么計(jì)算的,頻率就可以計(jì)算,兩個(gè)下降沿就一個(gè)完整周期,看你程序TR0與TR1都是同時(shí)開(kāi)同時(shí)關(guān)的,那計(jì)時(shí)的時(shí)間不是都一樣嗎,怎么計(jì)算出占空比?
回復(fù)

使用道具 舉報(bào)

15#
ID:633998 發(fā)表于 2019-11-1 18:16 | 只看該作者
Pwm_All = (Pwm_All<<8)+TL1;這是什么意思��?有什么作用嗎?
回復(fù)

使用道具 舉報(bào)

16#
ID:143996 發(fā)表于 2019-12-17 23:46 | 只看該作者
有哪位編譯通過(guò)的嗎。交流一下。編譯一直無(wú)法通過(guò)
回復(fù)

使用道具 舉報(bào)

17#
ID:24486 發(fā)表于 2020-2-12 09:24 | 只看該作者
學(xué)習(xí)一下,謝謝分享。
回復(fù)

使用道具 舉報(bào)

18#
ID:24486 發(fā)表于 2020-2-15 21:10 | 只看該作者
學(xué)習(xí)一下,謝謝分享。
回復(fù)

使用道具 舉報(bào)

19#
ID:713651 發(fā)表于 2020-4-11 16:13 | 只看該作者
你這個(gè)能讀出來(lái)嗎?
回復(fù)

使用道具 舉報(bào)

20#
ID:937848 發(fā)表于 2021-6-15 14:06 | 只看該作者
請(qǐng)問(wèn)LCD1602的頭文件能給出來(lái)嗎 編譯的時(shí)候報(bào)錯(cuò)了
回復(fù)

使用道具 舉報(bào)

21#
ID:937848 發(fā)表于 2021-6-15 17:13 | 只看該作者
頭文件怎么寫(xiě)呀 樓主 求救!
回復(fù)

使用道具 舉報(bào)

22#
ID:962202 發(fā)表于 2021-8-27 17:29 | 只看該作者
看看謝分享啦,學(xué)習(xí)中如何捕獲PWM然后轉(zhuǎn)換PWM或者驅(qū)動(dòng)MOS
回復(fù)

使用道具 舉報(bào)

23#
ID:881546 發(fā)表于 2022-7-20 15:19 | 只看該作者
定時(shí)器工作模式 TMOD = 0x19什么意思?
回復(fù)

使用道具 舉報(bào)

24#
ID:228452 發(fā)表于 2022-7-20 20:48 | 只看該作者
TMOD(Timer Mode) is an SFR. The address of this register is 89H. This is not bit-addressable.

TMOD.jpg (191.21 KB, 下載次數(shù): 102)

TMOD.jpg

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
續(xù)我心弦 + 5

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

25#
ID:881546 發(fā)表于 2022-7-21 16:28 | 只看該作者
脈沖輸入的口為什么是P32,我想弄個(gè)八路測(cè)脈沖寬度
回復(fù)

使用道具 舉報(bào)

26#
ID:881546 發(fā)表于 2022-7-21 16:36 | 只看該作者
mick32 發(fā)表于 2022-7-20 20:48
TMOD(Timer Mode) is an SFR. The address of this register is 89H. This is not bit-addressable.

I'm going to have another question on the next floor and if you could help me, I will sincerely appreciate you
回復(fù)

使用道具 舉報(bào)

27#
ID:228452 發(fā)表于 2022-7-21 22:52 | 只看該作者
本帖最后由 mick32 于 2022-7-21 23:20 編輯

"This is not bit-addressable"
If you want to change lets say only 89.0 bit you can change that bit and rest of bits in byte keep the same
Then you can send new byte to 89H register
information is byte wide xxxxxxxx (8 bits)
hope this is of help...
TMOD EQU 089H ; TMOD register

bit addressable

CLR IE.7 or SETB 20H.2

byte addressable

MOV TMOD,#00100010B ;22H

回復(fù)

使用道具 舉報(bào)

28#
ID:228452 發(fā)表于 2022-7-21 23:10 | 只看該作者

"Why is the pulse input port P32, I want to get an eight-way test pulse width"
P3.2 (INT0) and P3.3 (INT1) are hardware specific inputs...
8051 can't follow eight inputs with hardware
You try with software pooling but with big chance to loose real data...
回復(fù)

使用道具 舉報(bào)

29#
ID:228452 發(fā)表于 2022-7-21 23:30 | 只看該作者
"This is not bit-addressable"

TMOD EQU 089H ; TMOD register

bit addressable example

CLR IE.7 or
SETB 20H.2

byte addressable example

MOV TMOD,#00100010B ;22H
回復(fù)

使用道具 舉報(bào)

30#
ID:1078937 發(fā)表于 2023-5-22 16:07 | 只看該作者
shenyuqiu 發(fā)表于 2019-11-1 15:16
有點(diǎn)沒(méi)搞明白這個(gè)占空比是怎么計(jì)算的,頻率就可以計(jì)算,兩個(gè)下降沿就一個(gè)完整周期,看你程序TR0與TR1都是同 ...

因?yàn)槎〞r(shí)器0博主設(shè)置的帶門(mén)控位GATE,當(dāng)INT0高電平時(shí),定時(shí)器0才啟動(dòng);中斷第一次下降沿開(kāi)啟TR0=1不會(huì)立刻啟動(dòng)定時(shí)器1,上升沿之后才啟動(dòng)
回復(fù)

使用道具 舉報(bào)

31#
ID:1079136 發(fā)表于 2023-5-22 19:22 來(lái)自觸屏版 | 只看該作者
這個(gè)有點(diǎn)復(fù)雜了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表