亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

標(biāo)題: stc12c5a60s2 0-30電壓測量 有注釋 [打印本頁]

作者: 不將就123    時間: 2019-11-7 19:09
標(biāo)題: stc12c5a60s2 0-30電壓測量 有注釋
#include <STC12C5A60S2.H>
#include "intrins.h"

#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long


/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER   0x80            //ADC 電源控制位  10000000  0X80  /
#define ADC_FLAG    0x10            //ADC 完成標(biāo)志          00010000  0x10
#define ADC_START   0x08            //ADC 啟動ADC開關(guān) 00001000        0x08  /
#define ADC_SPEEDLL 0x00            //420 轉(zhuǎn)換速度          00000000        0x00  /
#define ADC_SPEEDL  0x20            //280 轉(zhuǎn)換速度          00100000  0x20
#define ADC_SPEEDH  0x40            //140 轉(zhuǎn)換速度          01000000  0x40
#define ADC_SPEEDHH 0x60            //70  轉(zhuǎn)換速度          01100000        0x60


/*----------------------------------------------------------------------------------------------
meidangzuidivoltage:表示AD最高電壓5V對應(yīng)10bit_AD轉(zhuǎn)換的最小電壓是多少 5/1024= 0.00488V 也就是AD在
//10bit下測量的最小電壓,
//那么在計算AD電壓值的時候?qū)⒐?“GetADCResult(ch)*5/1024”分兩步進(jìn)行 方便后面對數(shù)據(jù)分離顯示到
//1602上面  先計算ADC_jiancedaozuidivoltage=5*10000000/1024  先將這個數(shù)放大100萬倍
//最后在算AD_jie_guo=(ADC_jiancedaozuidivoltage*GetADCResult(ch);
----------------------------------------------------------------------------------------------*/
ulong  ADC_jiancedaozuidivoltage,temp,AD_jie_guo;          //長整形數(shù)據(jù)  16bit

float OVP;                 //定義一個浮點數(shù)  以保留小數(shù)點 提高進(jìn)度

uint num,i,vlue;//ADC_mV,ADC_RESX,VCC_V=5.2;

sbit    lcden = P2^7;
sbit    rs = P2^6;
sbit    rw = P2^5;
sbit    LED = P3^0;

void Delay(uint n);              //延時函數(shù)
uint GetADCResult(uchar ch);                 // ad轉(zhuǎn)換函數(shù)
void InitADC();                                         //ad初始化函數(shù)
void OCP_1();                                         //過壓 欠壓  提醒函數(shù)聲明
float count(uchar ch);       //AD值100次平均值函數(shù)
//ulong  count(uchar ch);  //ad計算函數(shù)測量0-5V時候用的
uchar code table[20]= {"     Shu Kong QuDong"};        //  開機(jī)畫面的布置
uchar code table2[20]={"     CQDZ Alan V1.01"};


/*-----------------
  延時函數(shù)
  -----------------*/
void delayms(uint xms)           //延時函數(shù)
{                                       
     uint i,j;                                         
         for(i=xms;i>0;i--)
           for (j=960;j>0;j--);
}

/*--------------------
寫命令
---------------------*/
void   lcd_write_com(uchar com)
{

         rw=0;
                 rs=0;        //寫命令狀態(tài)
                 P0=com;
                 lcden=1;
             delayms(5);
                 lcden=0;
}

/**-----------------
寫數(shù)據(jù)
--------------- ***/
void  write_date_(uchar date)
{
         rw=0; //寫數(shù)據(jù)
                 rs=1; //寫數(shù)據(jù)狀態(tài)
                 P0=date;
                 delayms(5);
                 lcden=1;  //使能
             delayms(5);
                 lcden=0;   
}

/*---------------
初始化顯示屏
---------------*/
void lcd_init(void)
{

                  lcden=0;
                  lcd_write_com(0x38); //設(shè)置8位格式,2行,5*7
                  lcd_write_com(0x0c); //整體顯示,關(guān)光標(biāo),不顯示
                  lcd_write_com(0x06); // 設(shè)定輸入方式,增量不移位
                  lcd_write_com(0x01);//清屏幕
                  delayms(5);  //延?


}

/*-----------------------
函數(shù)名稱    格式定義
函數(shù)的介紹  在某個屏幕位置上顯示一個字符,X(0-16),y(1-2)
X:表示字的格式 一共16個  Y:表示行 一共2行
-------------------------*/
//格式定義

void lcd_disp_char(uchar y,uchar x, uint dat)
{
         uint  address;
             if(y==1)                   //y為1  在第一行
                   address=0x80+0x10+4+x;          //整屏左移動以后 從新定義新的起始位置 但是要加上之前移動后的地址
             else
               address=0xc0+0x10+x;           //y為2 在第二行  X顯示字的位置   0XC0是 0x80+0x40的結(jié)果

           lcd_write_com(address);          //寫入要寫的位置
                   write_date_( dat);       //寫入你要寫的數(shù)據(jù)         
}        


/*------------------
顯示函數(shù)2
-------------------*/
void  disp()
{

     AD_jie_guo = count(0);   //經(jīng)過上面的計算求出來100次的平均值存放在AD_jie_guo里面


/*-------------------------------------------------------------------------------
        //擴(kuò)大電壓   我的量程是0-30V  分壓電阻是 10k 2k 電阻比的6  反推 當(dāng)測試電壓為5v
   //的時候 最高電壓為30V 測量后調(diào)試OK 因電阻誤差 調(diào)整了數(shù)據(jù)為6.02  
  //同時這里也可以用(temp/0.167)/100  這個是電壓比也就是30V分壓為5V  
  //然后5/30=0.167的結(jié)果也是一樣的
---------------------------------------------------------------------------------*/
         temp=((ADC_jiancedaozuidivoltage*AD_jie_guo)*6.02)/100;
//         temp=(temp*6.02)/100;    //備用算法 這樣太占用位置 我把這步合并到上面了         
                 
                                                          
        //0x30是顯示數(shù)字 0-9 30表示第一個數(shù)0  
        lcd_disp_char(1,0, temp%10000000/1000000+0x30 );   //十位
        lcd_disp_char(1,1, temp%1000000/100000+0x30);   //個位       
        lcd_disp_char(1,2,'.' );                                 // 小數(shù)點
        lcd_disp_char(1,3, temp%100000/10000+0x30 ); //個分位
        lcd_disp_char(1,4, temp%10000/10000+0x30 ); //百分位
        lcd_disp_char(1,5,'V' );
}
                                          //count(0)
/*-----------------------------------
名稱  開機(jī)畫面                  
功能  開機(jī)的時候顯示一下銘牌
      for來完成 屏幕左移動
----------------------------------*/
void init()

{       



//        lcd_write_com(0x80+0x10);  //定義顯示的位置 起始地址       
        lcd_write_com(0x80);           //定義顯示的位置 起始地址

        for(num=0;num<20;num++)
         {       
               
                        write_date_(table[num]);               //初始化屏幕的初始數(shù)字“0000”
                        delayms(5);                         
     }
                 
//        lcd_write_com(0x80+0x40+0x10);   //定義第二排,顯示的地址 0x80是顯示屏寄存器第一排起始地址
        lcd_write_com(0xc0);                  //定義顯示的位置 起始地址
    for(num=0;num<20;num++)                         //0x40是第二排起始地址
      {
                   write_date_(table2[num]);
                   delayms(5);                  
          }

          for(num=0;num<20;num++)        //整屏左移動 這里的21就是指可以移動多少格  
          {                                                        //可以是100可以是1000 相當(dāng)于是電子屏幕一樣

              lcd_write_com(0x18);        //0x18是整屏左移 指令
                  delayms(50);
          }       
          

}



void main()

{       

       
    lcd_init();
        init();
    InitADC();                      //Init ADC sfr

        ADC_jiancedaozuidivoltage=(49600000)/1024;  //5V參考電壓,計算分度值的時候,數(shù)值過小會出現(xiàn)很大偏差
                                                          //所以放大1000萬倍 這樣精度會高一些

    while (1)
    {
       disp();
           OCP_1();
    }
}

/*************************
*  功能        ADC轉(zhuǎn)換函數(shù)
*  帶結(jié)果返回  帶結(jié)果返回
**************************/

uint GetADCResult(uchar ch)  //參數(shù)的定義“ch”初始化就是為0  所以這里的“ch”應(yīng)該是用來設(shè)置用哪個端口     
{                                                   //來設(shè)置AD的 這個“ADC_POWER|ADC_SPEEDLL|ch|ADC_START”;或出來的結(jié)果是
                          //10001000   后面三個0對應(yīng)的是 CHS2 CHS1 CHS0 查表格 剛好是P1.0口
                                             //作為AD模擬輸入的。如果要改變端口就要給ch賦值 假如要P1.2 就需要賦值為ch=0x02;
        ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ch|ADC_START;    //配置相關(guān)項目打開  
        _nop_();
        _nop_();
        _nop_();                                            //4個機(jī)器時間的延時 以保障轉(zhuǎn)換完成
        _nop_();       
        while(!(ADC_CONTR&ADC_FLAG));   //判斷是否轉(zhuǎn)換完成
        ADC_CONTR &= ~ADC_FLAG;               //關(guān)閉ADC同時清零
    vlue = (ADC_RES*4+ADC_RESL);  //返回結(jié)果10bit  也就是電壓值         ,左移幾次就乘以2的幾次方
                                     //右移幾次就除以2的幾次方  這里的ADC_RES*4相當(dāng)于ADC_RES<<2 左移了2
        Delay(2);                                        //延時一下
        return vlue;

}
/******************************
*  功能:計算1結(jié)果函數(shù) 將10bit的結(jié)果計算為對應(yīng)電壓值MV
*  函數(shù)類型    float 型  浮點型
*  帶結(jié)果返回  帶結(jié)果返回
******************************/
/*
ulong count(uchar ch)
{      
        ADC_RESX=GetADCResult(ch);
        ADC_mV=(VCC_V*(long)ADC_RESX*10000/1024+5)/10;//強(qiáng)制轉(zhuǎn)換長整型運(yùn)算,得到結(jié)果mV(4舍5入)
        return ADC_mV;
}*/




/******************************
*  功能:計算2結(jié)果函數(shù) 將10bit的結(jié)果計算為對應(yīng)電壓值MV
*  函數(shù)類型    float 型  浮點型  保留小數(shù)點 提高精度
*  帶結(jié)果返回  帶結(jié)果返回
*  同時對GetADCResult(ch)采樣100次求平均值 提高進(jìn)度
******************************/

float count(uchar ch)
{
    float AD_val;     //定義處理后的數(shù)值A(chǔ)D_val為浮點數(shù)  初始狀態(tài)AD_val為0 經(jīng)過100次變化后
        uchar n;                  //AD_val值為100次的GetADCResult(ch)這個變化值 然后在除以100就是平均值

        for(n=0;n<100;n++)
         
        AD_val += GetADCResult(ch); //轉(zhuǎn)換100次求平均值(提高精度)
        AD_val /= 100;                          //意思是GetADCResult(ch)經(jīng)過了100次轉(zhuǎn)換后的值保存到了AD_val里面 然后在
                                  //除以100 就是求平均值 這樣的精度高一點
//        AD_val=(AD_val*5)/1024; //AD的參考電壓是單片機(jī)上的5v,所以乘5即為實際電壓值,因為為分段計算這個就
                            //暫時不用  如果測量0-5v就可以這樣計算
        OVP = ( AD_val*4.96 ) / 1024;  //為過壓 欠壓 提醒做 前期的計算 方便后面使用
        return AD_val;

}                                                                         
/*-------------------------------------------------------------------------------
函數(shù)功能   過壓ovp 欠壓 檢測    cpu供電VCC測量的是4.96V 本程序用的也是4.96V
下面計算也用4.96V。
計算方案:
   通過計算AD基礎(chǔ)值變化也就是"0-5V"的變化情況,然后人為的乘以擴(kuò)量程倍率“6.02”
得到的就是要過壓去,欠壓保護(hù)的值。
例如:現(xiàn)在要電壓達(dá)到10v的時候啟動欠壓提醒
計算過程:方法一
本次計算實際是通過vlue = (ADC_RES*4+ADC_RESL);在0-1024之間變化的值來確認(rèn)模擬
電壓輸入是多少的 如 1024/4.96V(VCC)*(VIN)模擬量,那么對應(yīng)10v的模擬量電壓應(yīng)該為
10/6.02=1.7V,那么它vlue = (ADC_RES*4+ADC_RESL)就要變化到多少才是對應(yīng)的1.7V呢,
通過公式1024/4.96V(vcc)*1.7V(vin)=350;
通過計算它的值在1.7V的時候vlue = (ADC_RES*4+ADC_RESL)=350. 那么我們通過判斷
這個vlue = (ADC_RES*4+ADC_RESL)的數(shù)據(jù)也可以判斷對應(yīng)保護(hù)電壓,但是計算很麻煩
所以我們把這個麻煩的過程直接讓程序計算好,然后直接用對應(yīng)系數(shù)1.7V即可。
方法二
這個就是我在float count(uchar ch)函數(shù)里面計算好了的(OVP)如下
OVP =( AD_val*4.96 ) / 1024;
OVP必須是float類型的數(shù)據(jù)保留小數(shù)點 不然誤差大,只要保留了小數(shù)點誤差非常小
通過上面計算好的這個過程然后我們要計算欠壓就非常好算了,例如我要12V欠壓
直接用12V/6.02這個系數(shù) 得到的就是你要的AD模擬量大小  12/6.02約等于2.0V
只要判斷OVP到了2.0就說明12V到了 做什么處理就看使用者了 可以報警 可以切斷電源

本程序我是10V欠壓 計算 10/6.02約等于1.7V  我判斷是OVP>1.7 也就是對應(yīng)的欠壓過壓點
到了 我是點亮LED,低于1.7也就是10V 就關(guān)閉LED;   
----------------------------------------------------------------------------------*/
void OCP_1()
{



       if(OVP > 1.7)   //高于10V  10/6.02=1.7
                   {
                  LED = 0;
                                                 //  調(diào)試的時候用的   通過判斷temp來判斷是否過壓 如果過壓就啟動保護(hù)  
                 }
           if(OVP < 1.7) //低于10v    10/6.02=1.7
                   {
                  LED = 1;
                 
                 }   
}





/*----------------------------
功能   ADC初始化函數(shù)
----------------------------*/
void InitADC()                                //adc初始化函數(shù)
{         
    P1M1 = 0x01;       //設(shè)置P1.0高阻模式                  
    P1M0 = 0x00;       //設(shè)置P1.0高阻模式
       
    P1ASF = 0x01;                   //開放P1.0通道ADC功能  就是8個I/O口全部開放
    ADC_RES = 0;                    //清除之前的結(jié)果
        ADC_RESL = 0;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;   //打開AD電壓  轉(zhuǎn)換速度540
    Delay(2);                       //ADC 延時一下
}


/*----------------------------
延時函數(shù)
----------------------------*/
void Delay(uint n)
{
   uint x;

    while (n--)
    {
        x = 5000;
        while (x--);
    }
}





作者: lqzhang03    時間: 2019-11-8 07:31
好,需要,謝謝。
作者: wshangm    時間: 2019-11-8 10:08
很好!收藏了
作者: 不將就123    時間: 2019-11-8 12:51
一定要記住  當(dāng)I/O口設(shè)置為高阻模式的時候 千萬不要有上拉電阻否則會造成高阻模式處于上拉狀態(tài) 造成誤差

高阻模式的電平是什么
     答  高阻模式的電平為任意電平 可以是高  也可以是低  可以是無窮大   高阻的中心定義就是和電路看上去是斷開的 但實際又沒有斷開   只是阻抗高而已   
高阻模式主要用在哪里 為什么要高阻模式   
     答  高阻模式主要用在總線上面 例如I2C總線   因為總線每次通訊的時候只能和一個IC通訊, 這是為什么呢   因為每一個IC通訊的時候 電平不一樣 如果都通訊就會造成通訊混亂
     從這個描述上看   高阻模式就是一個抗干擾能力強(qiáng)的開關(guān)  但是他比開關(guān)更先進(jìn)  高阻抗 高抗干擾能力 低功耗  而且是一個被動的開關(guān),
    經(jīng)過上面的描述我們可以知道  只要總線上一個IC損壞就會導(dǎo)致整個總線損壞  為什么?因為總線沒有被釋放,出現(xiàn)了通訊混亂
  高阻模式的電平由誰控制
   答   由負(fù)載控制   負(fù)載是低  高阻模式就是低   負(fù)載是高  高阻模式就是高   

  所以在AD轉(zhuǎn)換的時候  用高阻模式提高精度  是唯一途徑
作者: yuanri    時間: 2019-11-8 21:52
好帖謝謝分享!
作者: wyl堅持向前沖    時間: 2020-1-28 01:33
師傅,這個程序如果顯示電流和功率的話,應(yīng)該怎么寫程序呢
作者: 1238    時間: 2020-3-4 20:54
自制STC 12C5A60S2電壓電流表正在學(xué)習(xí)中
作者: Liangkan    時間: 2020-3-5 21:56
這個壇的好就是活躍人多,有東西學(xué)




歡迎光臨 (http://www.denmoz.com/bbs/) Powered by Discuz! X3.1