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

QQ登錄

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

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

關(guān)于單片機(jī)ADC采樣值0-255怎么映射到PWM0-100

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:232366 發(fā)表于 2023-6-4 13:55 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
用單片機(jī)定時(shí)器0做了個(gè)PWM模擬輸出實(shí)現(xiàn)了50HZ輸出周期為20Ms,占空比剛剛好對(duì)應(yīng)為0-255級(jí)此變量"PWM_DUTY"對(duì)應(yīng)0-255變化脈寬對(duì)應(yīng)0-100變化沒(méi)什么問(wèn)題了.問(wèn)題1:怎么才能結(jié)合ADC對(duì)外部電位器采樣的數(shù)值0-255映射到對(duì)應(yīng)的脈寬0-100之間電位器滿程調(diào)節(jié)呢?
問(wèn)題2:比如需要限制某一個(gè)脈寬值比如脈寬1Ms-2.5M變化怎么才能把ADC數(shù)值映射到0-255滿程調(diào)節(jié)呢?
sbit PWM_OUT_GPIO=P2^0;


unsigned char PWM_DUTY=128;//此時(shí)脈寬剛剛好百分之50
uint8 ADC_Value=0;

void XPT2046_Allot()//XPT2046-ADC芯片數(shù)據(jù)分頻函數(shù)
{               
        ADC_Value=Start_XPT2046_ADC(PIN0_0_XP_ADC_8BIT,8);//啟動(dòng)ADC轉(zhuǎn)換芯片函數(shù) 此函數(shù)第一個(gè)形參設(shè)置模式和通道 第二個(gè)為設(shè)置轉(zhuǎn)換的位數(shù) 范圍8-12
}




void Timer0Init()        //100微秒@12MHz"八位自動(dòng)"
{
        TMOD &= 0xF0;        //設(shè)置定時(shí)器模式
        TMOD |= 0x02;        //設(shè)置定時(shí)器模式
        TL0 = 0xb2;                //設(shè)置定時(shí)初始值
        TH0 = 0xb2;                //設(shè)置定時(shí)重載值
        TF0 = 0;                //清除TF0標(biāo)志
        TR0 = 1;                //定時(shí)器0不啟動(dòng)
        ET0 = 1;                //允許定時(shí)器0申請(qǐng)中斷
        EA  = 1;                //開(kāi)啟所有中斷
}


void main()
{
        while(1)
        {
                XPT2046_Allot();//XPT2046-ADC芯片數(shù)據(jù)分頻函數(shù)
        }
}

void Timer0Interrupt() interrupt 1
{   
        if(PWM_Cnt<PWM_DUTY)
        {
                PWM_OUT_GPIO=1;
        }
        else
        {
                PWM_OUT_GPIO=0;
        }
        PWM_Cnt++;
}



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

使用道具 舉報(bào)

沙發(fā)
ID:883242 發(fā)表于 2023-6-4 15:52 | 只看該作者
總要知道ADC函數(shù)輸出值的范圍吧,不知道這個(gè)誰(shuí)也不會(huì)算。
回復(fù)

使用道具 舉報(bào)

板凳
ID:232366 發(fā)表于 2023-6-4 16:07 | 只看該作者
Hephaestus 發(fā)表于 2023-6-4 15:52
總要知道ADC函數(shù)輸出值的范圍吧,不知道這個(gè)誰(shuí)也不會(huì)算。

八位ADC數(shù)值0-255
回復(fù)

使用道具 舉報(bào)

地板
ID:232366 發(fā)表于 2023-6-4 16:09 | 只看該作者
SHANWAZI 發(fā)表于 2023-6-4 16:07
八位ADC數(shù)值0-255

ADC_Value=Start_XPT2046_ADC(PIN0_0_XP_ADC_8BIT,8);“PIN0_0_XP_ADC_8BIT”此變量就是設(shè)置ADC位數(shù)的目前是八位
回復(fù)

使用道具 舉報(bào)

5#
ID:883242 發(fā)表于 2023-6-4 16:13 | 只看該作者
SHANWAZI 發(fā)表于 2023-6-4 16:07
八位ADC數(shù)值0-255

ADC輸出0~255,PWM_DUTY范圍0~255你算什么�。克銈€(gè)寂寞?
回復(fù)

使用道具 舉報(bào)

6#
ID:213173 發(fā)表于 2023-6-4 16:41 | 只看該作者
PWM_DUTY = ADC_Value*256/100;
回復(fù)

使用道具 舉報(bào)

7#
ID:232366 發(fā)表于 2023-6-4 16:55 來(lái)自手機(jī) | 只看該作者
wulin 發(fā)表于 2023-6-4 16:41
PWM_DUTY = ADC_Value*256/100;

這樣寫(xiě)用示波器看占空比最大才40左右
回復(fù)

使用道具 舉報(bào)

8#
ID:232366 發(fā)表于 2023-6-4 17:02 來(lái)自手機(jī) | 只看該作者
wulin 發(fā)表于 2023-6-4 16:41
PWM_DUTY = ADC_Value*256/100;

假如ADC輸出值為255計(jì)算得到的是655.36這?
回復(fù)

使用道具 舉報(bào)

9#
ID:883242 發(fā)表于 2023-6-4 17:26 | 只看該作者
SHANWAZI 發(fā)表于 2023-6-4 16:55
這樣寫(xiě)用示波器看占空比最大才40左右

這不就對(duì)了嗎,你軟件里面最大占空比是255,你以為是100,那么100/255不就是40%嗎???
回復(fù)

使用道具 舉報(bào)

10#
ID:232366 發(fā)表于 2023-6-4 17:40 來(lái)自手機(jī) | 只看該作者
Hephaestus 發(fā)表于 2023-6-4 17:26
這不就對(duì)了嗎,你軟件里面最大占空比是255,你以為是100,那么100/255不就是40%嗎???

那怎么換算過(guò)來(lái)使他剛剛好ADC值0-255變化 使占空比0-100呢?
回復(fù)

使用道具 舉報(bào)

11#
ID:232366 發(fā)表于 2023-6-4 17:45 來(lái)自手機(jī) | 只看該作者
Hephaestus 發(fā)表于 2023-6-4 17:26
這不就對(duì)了嗎,你軟件里面最大占空比是255,你以為是100,那么100/255不就是40%嗎???

那比如 我要在某一個(gè)占空比之間變化比如默認(rèn)為1ms-2.5ms 之間變化 怎么才能把這其中的值對(duì)應(yīng)到ADC的0-255電位器滿里程調(diào)節(jié)呢 電位器跳到最小就是1毫秒最大就是2.5毫秒?程序該怎么改?
回復(fù)

使用道具 舉報(bào)

12#
ID:883242 發(fā)表于 2023-6-4 18:19 | 只看該作者
SHANWAZI 發(fā)表于 2023-6-4 17:40
那怎么換算過(guò)來(lái)使他剛剛好ADC值0-255變化 使占空比0-100呢?

5樓已經(jīng)回復(fù)你了。
回復(fù)

使用道具 舉報(bào)

13#
ID:232366 發(fā)表于 2023-6-4 22:52 來(lái)自手機(jī) | 只看該作者
Hephaestus 發(fā)表于 2023-6-4 18:19
5樓已經(jīng)回復(fù)你了。

感謝感謝  看來(lái)還是我的程序有問(wèn)題 思路不對(duì)
回復(fù)

使用道具 舉報(bào)

14#
ID:123289 發(fā)表于 2023-6-5 11:06 | 只看該作者
最簡(jiǎn)單的方案:
將0-255所對(duì)應(yīng)的PWM0-100值計(jì)算出來(lái),建立一個(gè)數(shù)組。即完成對(duì)應(yīng)關(guān)系了。
回復(fù)

使用道具 舉報(bào)

15#
ID:232366 發(fā)表于 2023-6-5 16:10 | 只看該作者
yzwzfyz 發(fā)表于 2023-6-5 11:06
最簡(jiǎn)單的方案:
將0-255所對(duì)應(yīng)的PWM0-100值計(jì)算出來(lái),建立一個(gè)數(shù)組。即完成對(duì)應(yīng)關(guān)系了。

老師能否舉個(gè)例指導(dǎo)一下???
回復(fù)

使用道具 舉報(bào)

16#
ID:647261 發(fā)表于 2023-6-5 16:22 | 只看該作者
  1. sbit PWM_OUT_GPIO=P2^0;


  2. unsigned char PWM_DUTY=50;//此時(shí)脈寬剛剛好百分之50
  3. uint8 ADC_Value=0;

  4. void XPT2046_Allot()//XPT2046-ADC芯片數(shù)據(jù)分頻函數(shù)
  5. {               
  6.         ADC_Value=Start_XPT2046_ADC(PIN0_0_XP_ADC_8BIT,8);//啟動(dòng)ADC轉(zhuǎn)換芯片函數(shù) 此函數(shù)第一個(gè)形參設(shè)置模式和通道 第二個(gè)為設(shè)置轉(zhuǎn)換的位數(shù) 范圍8-12
復(fù)制代碼

回復(fù)

使用道具 舉報(bào)

17#
ID:647261 發(fā)表于 2023-6-5 17:11 | 只看該作者
不知道為什么,直接弄成代碼改,只顯示一部分,我的建議更改如下:
unsigned char PWM_DUTY=50; 這里的PWM_DUTY應(yīng)該是0~100,不要做成0~255
PWM_DUTY = ADC_Value * 100 /255,這里出來(lái)的就是百分比了,比如ADC值127,算出來(lái)就是49,也就是49%
PWM_Cnt++;后面再加一句 if(PWM_Cnt ==100)PWM_Cnt=0;
就是設(shè)置100個(gè)數(shù),對(duì)應(yīng)100%,和DUTY對(duì)比
回復(fù)

使用道具 舉報(bào)

18#
ID:232366 發(fā)表于 2023-6-5 17:40 | 只看該作者
sttt300 發(fā)表于 2023-6-5 17:11
不知道為什么,直接弄成代碼改,只顯示一部分,我的建議更改如下:
unsigned char PWM_DUTY=50; 這里的PWM ...

感謝老師辛勤回復(fù)!首先這方法我已經(jīng)試過(guò)了!目的是實(shí)現(xiàn)占空比0-99變化很方便。但是還是沒(méi)達(dá)到目的�。�!
首先周期是固定的我要讓ADC采樣到的數(shù)值0-255均勻分布出來(lái)取對(duì)應(yīng)上這占空比!
比如默認(rèn)脈寬是1毫秒狀態(tài)對(duì)應(yīng)電位器為最小值狀態(tài)。如果調(diào)節(jié)電位器脈寬從1毫秒開(kāi)始變化到2.5毫秒也就是電位器擰到最大就是2.5毫秒。問(wèn)題是這我始終弄不明白??????
回復(fù)

使用道具 舉報(bào)

19#
ID:232366 發(fā)表于 2023-6-5 17:41 | 只看該作者
sttt300 發(fā)表于 2023-6-5 17:11
不知道為什么,直接弄成代碼改,只顯示一部分,我的建議更改如下:
unsigned char PWM_DUTY=50; 這里的PWM ...


目前程序已修改了剛剛好占空比是0-99的。

unsigned char data PWM_DUTY=50;//調(diào)節(jié)此變量就可以調(diào)節(jié)占空比0-99變化

void Timer0Interrupt() interrupt 1
{   
        PWM_Cnt++;
        if(PWM_Cnt>=100)//總周期為10ms
        {
                PWM_Cnt=0;
        }

        if(PWM_Cnt<PWM_DUTY)//高電平的半個(gè)周期
        {
                PWM_OUT_GPIO=1;
        }
        else
        {
                PWM_OUT_GPIO=0;//低電平的半個(gè)周期
        }
}
回復(fù)

使用道具 舉報(bào)

20#
ID:123289 發(fā)表于 2023-6-6 15:16 | 只看該作者
1、周期需要固定時(shí),用一個(gè)變量PT表達(dá)周期,再用一個(gè)變量PA表示高或低電平的寬度。
2、要達(dá)到u%(1%)的精度,PA:PT必須<u%。

回復(fù)

使用道具 舉報(bào)

21#
ID:1034262 發(fā)表于 2023-6-6 18:19 | 只看該作者
PWM = ADC*100/255
回復(fù)

使用道具 舉報(bào)

22#
ID:232366 發(fā)表于 2023-6-6 18:45 來(lái)自手機(jī) | 只看該作者
yzwzfyz 發(fā)表于 2023-6-6 15:16
1、周期需要固定時(shí),用一個(gè)變量PT表達(dá)周期,再用一個(gè)變量PA表示高或低電平的寬度。
2、要達(dá)到u%(1%)的精度 ...

這就有點(diǎn)深?yuàn)W咯!
回復(fù)

使用道具 舉報(bào)

23#
ID:123289 發(fā)表于 2023-6-7 10:33 | 只看該作者
例:PT=100ms,PA=5ms,用P01做PWM輸出。輸出脈沖寬度=PA,周期=PT
用定時(shí)器做個(gè)定時(shí)為1ms的中斷。中斷服務(wù)程序這樣寫(xiě):
1、如果PT=PA=0,就復(fù)位PT=100ms,PA=5ms,跳至第4步;否則執(zhí)行下一步。(計(jì)時(shí)PWM周期到了,復(fù)位進(jìn)入下個(gè)周期)
2、PA<>0,執(zhí)行PA-1;反之PA=0,放弁不做。(計(jì)時(shí)PWM脈沖輸出寬度,計(jì)滿之后不再計(jì)了)
3、PT<>0,執(zhí)行PT-1;反之PT=0,放弁不做。(計(jì)時(shí)PWM周期,計(jì)滿之后不再計(jì)了)
4、P01 = PA。(這里需要修改,自己去想)。
5、中斷返回退出 。
這里的1ms就是u,1ms/PT=1ms/100ms=1%,就是PWM能達(dá)到的精度。
回復(fù)

使用道具 舉報(bào)

24#
ID:232366 發(fā)表于 2023-6-7 16:42 | 只看該作者
yzwzfyz 發(fā)表于 2023-6-7 10:33
例:PT=100ms,PA=5ms,用P01做PWM輸出。輸出脈沖寬度=PA,周期=PT
用定時(shí)器做個(gè)定時(shí)為1ms的中斷。中斷服 ...

感謝老師辛勤回復(fù)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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