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

QQ登錄

只需一步,快速開始

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

在線等,關(guān)于一個(gè)AD采集DA的單片機(jī)程序,值總是固定的一個(gè)問(wèn)題困擾好幾天了

[復(fù)制鏈接]
ID:289777 發(fā)表于 2018-6-10 17:24 | 顯示全部樓層 |閱讀模式
100黑幣
AD檢測(cè)DA輸出的模擬電壓,然后在數(shù)碼管上顯示
我的能顯示,但是數(shù)字總是跳變,這是怎么回事,數(shù)字不穩(wěn)定,數(shù)字的值跳變明顯
占空比明明我已經(jīng)固定了,按理說(shuō)不會(huì)發(fā)生很大的數(shù)字值跳變現(xiàn)象,但是我的依然發(fā)生的跳變很大,這是怎么回事
我的程序在下面,很短,麻煩看一下,占空比是Value
周期是Timer1
主函數(shù)While 里已經(jīng)把占空比固定了,為什么數(shù)字跳變?cè)跀?shù)碼管上還是很明顯??


是中斷的問(wèn)題嗎?但是數(shù)碼管的中斷我已經(jīng)修改好幾了,不管定時(shí)是長(zhǎng)一點(diǎn)還是短,跳變現(xiàn)象都很明顯,怎么辦?

/**************************************************************************************
*                外部輸入AD實(shí)驗(yàn)              *
實(shí)現(xiàn)現(xiàn)象: 具體接線操作請(qǐng)參考視頻
   下載程序后數(shù)碼管前4位顯示外部輸入IN3通道檢測(cè)的AD值,模擬信號(hào)電壓范圍在0-5V
注意事項(xiàng):                     
***************************************************************************************/
#include "reg52.h"    //此文件中定義了單片機(jī)的一些特殊功能寄存器
#include"XPT2046.h"
typedef unsigned int u16;   //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
typedef unsigned char u8;
//--定義使用的IO口--//
sbit PWM=P2^1;
bit DIR;
//--定義一個(gè)全局變量--//
u16 count,value,timer1;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 disp[4];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*******************************************************************************
* 函 數(shù) 名         : delay
* 函數(shù)功能     : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函數(shù)名         :datapros()
* 函數(shù)功能   :數(shù)據(jù)處理函數(shù)
* 輸入           : 無(wú)
* 輸出           : 無(wú)
*******************************************************************************/
void datapros()
{
u16 temp;
static u8 i;
if(i==50)
{
  i=0;
  temp = Read_AD_Data(0xE4);  //   AIN3 外部輸入
}
i++;
disp[0]=smgduan[temp/1000];//千位
disp[1]=smgduan[temp%1000/100];//百位
disp[2]=smgduan[temp%1000%100/10];//個(gè)位
disp[3]=smgduan[temp%1000%100%10];  
}

/*******************************************************************************
* 函數(shù)名         :DigDisplay()
* 函數(shù)功能   :數(shù)碼管顯示函數(shù)
* 輸入           : 無(wú)
* 輸出           : 無(wú)
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<4;i++)
{
  switch(i)  //位選,選擇點(diǎn)亮的數(shù)碼管,
  {
   case(0):
    LSA=0;LSB=0;LSC=0; break;//顯示第0位
   case(1):
    LSA=1;LSB=0;LSC=0; break;//顯示第1位
   case(2):
    LSA=0;LSB=1;LSC=0; break;//顯示第2位
   case(3):
    LSA=1;LSB=1;LSC=0; break;//顯示第3位
  }

  P0=disp[ i];//發(fā)送數(shù)據(jù)
  delay(40); //間隔一段時(shí)間掃描
  P0=0x00;//消隱
}  
}
  1. /*******************************************************************************
  2. * 函 數(shù) 名       : main
  3. * 函數(shù)功能   : 主函數(shù)
  4. * 輸    入       : 無(wú)
  5. * 輸    出      : 無(wú)
  6. *******************************************************************************/
  7. void Timer1Init()
  8. {
  9. TMOD|=0X10;//選擇為定時(shí)器1模式,工作方式1,僅用TR1打開啟動(dòng)。
  10. TH1 = 0xFF;
  11. TL1 = 0xff;   //1us
  12.   
  13. ET1=1;//打開定時(shí)器1中斷允許
  14. EA=1;//打開總中斷
  15. TR1=1;//打開定時(shí)器   
  16. }
  17. void Timer1Init1()
  18. {
  19. TMOD|= 0x01;
  20.    TH0 = 0x0D8;
  21.     TL0 = 0x0F0;
  22.     ET0 = 1;
  23.     TR0 = 1;  
  24. }
  25. void main()
  26. {
  27.     Timer1Init1();
  28. Timer1Init();  //定時(shí)器1初始化

  29. while(1)
  30. {   
  31.       
  32.    value=34;
  33.   if(timer1>200)  //PWM周期為1000*1us
  34.   {
  35.    timer1=0;
  36.   }
  37.   if(timer1 <value)
  38.   {
  39.    PWM=1;
  40.   }
  41.   else
  42.   {
  43.    PWM=0;
  44.   }
  45.   
  46. }  
  47. }
  48.     void Time(void) interrupt 1  //3 為定時(shí)器1的中斷號(hào)  1 定時(shí)器0的中斷號(hào) 0 外部中斷1 2 外部中斷2  4 串口中斷
  49. {
  50.       TH0 = 0x0D8;
  51.     TL0 = 0x0F0;
  52. count++ ;
  53.        if(count==20)
  54.        {count=0;
  55.    
  56.        datapros();  //數(shù)據(jù)處理函數(shù)
  57.   DigDisplay();//數(shù)碼管顯示函數(shù)
  58.           }

  59. }
  60. void Time1(void) interrupt 3    //3 為定時(shí)器1的中斷號(hào)  1 定時(shí)器0的中斷號(hào) 0 外部中斷1 2 外部中斷2  4 串口中斷
  61. {
  62. TH1 = 0xFF;
  63. TL1 = 0xff;   //1us
  64. timer1++;
  65.       
  66. }
復(fù)制代碼

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
yrbneumann5288 + 5 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:123289 發(fā)表于 2018-6-10 18:46 | 顯示全部樓層
你可以用斷點(diǎn)調(diào) 試一下,看看究競(jìng)何處在跳動(dòng)。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2018-6-10 21:14 | 顯示全部樓層
你這個(gè)程序根本不可能正常運(yùn)行!T1中斷周期1us,CPU得到中斷請(qǐng)求到響應(yīng)中斷需要時(shí)間,執(zhí)行中斷任務(wù)也需要時(shí)間,這個(gè)過(guò)程遠(yuǎn)遠(yuǎn)超過(guò)1us,也就是說(shuō)執(zhí)行T1中斷任務(wù)一次時(shí)間已經(jīng)丟掉好多次中斷請(qǐng)求,何況T0中斷的優(yōu)先級(jí)高于T1中斷,執(zhí)行T0中斷任務(wù)一次也不知丟掉多少次T1中斷請(qǐng)求,那么你的PWM就是極不穩(wěn)定,怎么可能得到穩(wěn)定的AD/DA值,甚至主程序根本無(wú)法正常運(yùn)行。根據(jù)經(jīng)驗(yàn),普通51單片機(jī)在12M晶振條件下中斷周期小于10us主程序就不能正常運(yùn)行,不信你寫個(gè)小程序試試,
回復(fù)

使用道具 舉報(bào)

ID:289777 發(fā)表于 2018-6-10 22:06 | 顯示全部樓層
wulin 發(fā)表于 2018-6-10 21:14
你這個(gè)程序根本不可能正常運(yùn)行!T1中斷周期1us,CPU得到中斷請(qǐng)求到響應(yīng)中斷需要時(shí)間,執(zhí)行中斷任務(wù)也需要時(shí) ...

那我定時(shí)器中斷1 改成了100us,那么定時(shí)器0 數(shù)碼管掃描的定時(shí)我是往大的方向改還是小的方向改?
定時(shí)器1 改成100us,那我的周期timer1 是從1000改到100好還是繼續(xù)保持1000呢?
回復(fù)

使用道具 舉報(bào)

ID:323774 發(fā)表于 2018-6-10 22:31 | 顯示全部樓層
樓上說(shuō)的有道理,51是12MHz時(shí)鐘,指令周期是1/12,對(duì)應(yīng)的是1us,主程序無(wú)法正常運(yùn)行
回復(fù)

使用道具 舉報(bào)

ID:341045 發(fā)表于 2018-6-11 01:06 | 顯示全部樓層
T1中斷設(shè)置有問(wèn)題, TH1=0XFF; TL1=0XFF; 也就是一個(gè)指令周期就中斷, 都沒(méi)空閑在執(zhí)行外部程序了
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2018-6-11 10:35 | 顯示全部樓層
haohaoxue51 發(fā)表于 2018-6-10 22:06
那我定時(shí)器中斷1 改成了100us,那么定時(shí)器0 數(shù)碼管掃描的定時(shí)我是往大的方向改還是小的方向改?
定時(shí)器1 ...

不是修改T1中斷周期這么簡(jiǎn)單,這里有個(gè)程序構(gòu)架的問(wèn)題,T0中斷任務(wù)運(yùn)行需要約5ms,你改T1中斷周期為100us又有多少實(shí)際意義?核心在于你如何調(diào)度時(shí)間!從你的全部任務(wù)看只要開1個(gè)定時(shí)器,中斷周期100~200us產(chǎn)生PWM為宜,AD轉(zhuǎn)換放在中斷里,2ms轉(zhuǎn)換一次,其他任務(wù)放在主循環(huán)處理。局部程序供參考:void Timer0Init(void)                //100微秒@12.000MHz
{
        TMOD |= 0x02;                        //設(shè)置定時(shí)器0自動(dòng)重載模式
        TL0 = 0x9C;                                //設(shè)置定時(shí)初值
        TH0 = 0x9C;                                //設(shè)置定時(shí)重載值
        TF0 = 0;                                //清除TF0標(biāo)志
        TR0 = 1;                                //定時(shí)器0開始計(jì)時(shí)
        EA=1;                                        //開總中斷
        ET0=1;                                        //開定時(shí)器0中斷       
}
void timer0() interrupt        1
{
        timer1++;
        timer2++;
        if(timer1>=100)
                timer1=0;               
        if(timer1<value)
                PWM=1;               
        else
                PWM=0;
        if(timer2>=20)
        {
                timer2=0;       
                temp=Read_AD_Data(0xE4);//AD采樣
                flag=1;//2ms標(biāo)志,供數(shù)據(jù)處理函數(shù)和數(shù)碼管函數(shù)刷新用
        }
}
void DigDisplay()
{
        static u8 i=0;
        if(flag==1)
        {
                flag=0;//2ms標(biāo)志清0
                P0=0x00;//消隱
                switch(i)
                {
                        case(0):
                        LSA=0;LSB=0;LSC=0;P0=smgduan[temp/1000];i++; break;//顯示第0位
                        case(1):
                        LSA=1;LSB=0;LSC=0;P0=smgduan[temp%1000/100];i++; break;//顯示第1位
                        case(2):
                        LSA=0;LSB=1;LSC=0;P0=smgduan[temp%1000%100/10];i++; break;//顯示第2位
                        case(3):
                        LSA=1;LSB=1;LSC=0;P0=smgduan[temp%1000%100%10];i=0; break;//顯示第3位
                }                
        }
}

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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