| 
 | 
 
 樓主 |
發表於 2012-11-12 22:59:40
|
顯示全部樓層
 
 
 
 本帖最後由 antlu 於 2012-11-12 11:07 PM 編輯  
 
 
 
今天把問題完成了 89c2051完成版 閃爍也變小了!! 跟公式比較算是"符合"了!! 浮點數佔4BYTE 長度也夠!! 
 
 
 
 
 
 
 
 
 
 
 
/*----------------------------------------------- 
   7段顯示共陰 電感計 89C2051用 
                        目前更改中断優先 ip=0x80; 11/11 
   閃爍問題 顯示副程式 DataPort=0 放前面 
   把顯示的延遲時間降低為10ms 
   先把頻率顯示做出來 a*10=1秒的計數 再除以100就是每秒 xxx.xkhz 
   最後把公式套進去 本電路使用 100uH 1500pF  
------------------------------------------------*/ 
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 
//#include<stdio.h> 
//#include<intrins.h> 
bit OVERFLOWFLAG; 
bit TIMERFLAG; 
unsigned int LVint; 
#define DataPort P1//P0.0~P0.7 七段顯示的段顯示(共陰極) 
#define DrivePort P3//驅動共陰極顯示器 
unsigned char code  dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共陰7段值0~9 
//unsigned char code  dofly_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共陽7段值0~9 
unsigned char code dofly_WeiMa[4]={ 0xfe,0xfd,0xfb,0xf7};//共陰位碼1>>秒, 位碼2>>10秒,位碼3>>分, 位碼4>>10分,  
//unsigned char code dofly_WeiMa[8]={ 0x01,0x02,0x04,0x08, 0x01,0x02,0x04,0x08 };//{ 0x01,0x02,0x04,0x08, 0x10,0x20,0x40,0x80 };//共陽位碼1>>秒, 位碼2>>10秒,位碼3>>分, 位碼4>>10分,  
unsigned char TempData[4]; //存??示值的全局?量,把段碼的資料存到要顯示的緩衝器上面,利用類似查表的對應方式,送出至顯示器. TempData[ ] 是放置要顯示的7段資料 
void Get_L (void); 
void Display_Data_Operation(void); 
void Display(char n,char Num); 
void DelayUs2x(unsigned char t); 
void Init_Timer0(void); 
void Init_Timer1(void); 
void DelayUs2x(unsigned char t); 
void DelayMs(unsigned char t); 
/*------------------------------------------------ 
                    主程序 
------------------------------------------------*/ 
main() 
{ 
 Init_Timer0();      //初始化定时器0 
 Init_Timer1();      //初始化定时器1 
while(1) 
 { 
  if(TIMERFLAG)      //定时100ms到,做数据处理 
    { 
          Get_L();//把計數的頻率轉換成LVint成為電感值 
     Display_Data_Operation();//把 電感值LV轉成顯示  
        } 
    Display(0,4);//平常一直顯示 
  } 
} 
 
 
 
/*------------------------------------------------ 
                    定时器0初始化子程序 
                                        本程序用于计数 
------------------------------------------------*/ 
void Init_Timer0(void) 
{ 
 TMOD |= 0x01 | 0x04;          //使用模式1,16位计数器,使用"|"符号可以在使用多个定时器时不受影响                      
 TH0=0x00;              //给定初值 
 TL0=0x00;          
 EA=1;            //总中断打开 
 ET0=1;           //定时器中断打开 
 TR0=1;           //定时器开关打开 
} 
/*------------------------------------------------ 
                    定时器1初始化子程序 
                                        本程序用于定时 
------------------------------------------------*/ 
void Init_Timer1(void) 
{ 
 TMOD |= 0x20;          //使用模式2,8位定时器,使用"|"符号可以在使用多个定时器时不受影响  
 TH1=(256-230);   //给定初值,这里使用定时器最大值从0开始计数一直到256溢出自動重載 
 TL1=(256-230);   //11.0592 ---250us 
 EA=1;            //总中断打开 
 ET1=1;           //定时器中断打开 
 TR1=1;           //定时器开关打开 
// 你沒設IP暫存器,要設timer1中斷優先權, 
 IP=0x08;//單晶片微電腦大  建議 
} 
 
/*------------------------------------------------ 
                 定时器0中断子程序 
------------------------------------------------*/ 
void Timer0_isr(void) interrupt 1 
{ 
 TH0=00;              //重新给定初值 
 TL0=00;  
 OVERFLOWFLAG=1;  //溢出标志 
} 
/*------------------------------------------------ 
                 定时器1中断子程序 
------------------------------------------------*/ 
void Timer1_isr(void) interrupt 3 
 { 
  static unsigned int i;//自動載入模式 
   i++; 
   if(i==400)       //100ms 计数时间单位,得出100ms脉冲个数 x10就是1s中脉冲个数,即为频率 Hz  
    { 
     i=0; 
     TR0=0;        //2个定时器关闭 
     TR1=0; 
     TIMERFLAG=1;  //标志位清零 
   } 
 } 
 
void DelayUs2x(unsigned char t) 
  {    
   while(--t); 
  } 
 
void DelayMs(unsigned char t) 
  {      
   while(t--) 
    { 
     DelayUs2x(226);//for 11.0592 
         DelayUs2x(226); 
    } 
   } 
 
//-------------------------------------------------------------------------------------------- 
void Display_Data_Operation(void)//以時間分秒為共同語言, 數字轉換成7段顯示 
{ 
 TempData[3]=dofly_DuanMa[LVint/1000];  
 if(LVint<1000)//去零顯示 
   TempData[3]=0; 
 TempData[2]=dofly_DuanMa[LVint%1000/100];// 
 if(LVint<100) 
  TempData[2]=0; 
 TempData[1]=dofly_DuanMa[LVint%100/10];// 
 TempData[0]=dofly_DuanMa[LVint%10];// 
Display(0,4); 
}         
//-------------------------------------------------------------------------------------------- 
void Display(char n,char Num)// 把七段顯示出去,假如Startflag==1 則輸出RELAY,已經不管controlBit了 0516 
     { 
      unsigned char nu; 
      n=0; 
          for(nu=0;nu<Num;nu++) 
           {  
       DataPort=0;//SIMON大建議 
           DataPort= TempData[nu]; //  
       DrivePort= dofly_WeiMa[nu];        
       DelayMs(10); //減少閃爍 
//       DataPort=0;//改到前方 SIMON大建議 
       }            
      } 
 
 
void Get_L (void) 
   { 
//   unsigned  long int a;變更為float 1770>>1482 
    float LV,sq,a; 
 
           a=TL0+TH0*256;//读取计数值 這是1/10 秒的數值 
//     a=a*10; 
//         sq=(a/1000)*(a/1000);//這很重要,不能改成 (a*a/1000000) 
    sq=(a*a/10000);//code= 1482 >>1431 
        LV=(1000000/(sq*39.4*0.00146))-90;//顯示成微亨利單位 90uH 1460pF 
 
//     LV=a*10/100;//顯示頻率 a*10 LM311 100uH 1500pF 共振439.5k a=439500所以要再除100 
         LVint=LV;//change to 整數 
         TR0=1;                     //2个定时器打开 
         TR1=1; 
         TH0=0;                     //保证计数器初值为0 
         TL0=0; 
 
         TIMERFLAG=0;               //打开计时计数标志 
    } 
 |   
 
 
 
 |