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

QQ登錄

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

搜索
查看: 3513|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)1602電壓電流表程序中的幾個(gè)問(wèn)題不懂,求解釋

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
//stc12c5a60                        
#include<STC12C5A60S2.h>
#include<stdio.h>
#include<intrins.h>//頭文件

#define uchar unsigned char//宏定義
#define uint unsigned int//宏定義
#define ulint unsigned long int//宏定義
#define N 21//ADC中值濾波次數(shù),必須為基數(shù)
#define ISP_TRIG() ISP_TRIG=0x5A,ISP_TRIG=0xA5//ISP觸發(fā)命令

sbit rs=P3^5;//液晶RS
sbit rw=P3^6;//液晶RW
sbit e=P3^4;//液晶E

void AD_init(void);//ADC初始化
void delay(uint z);//延時(shí)函數(shù)
uint AD_get(uchar haha );//讀ADC的數(shù)值
void LCD_data(uchar shuju);//寫數(shù)據(jù)
void zhiling(uchar zhilin);//寫指令
void LCD_init(void);//初始化LCD
void tablex(uint tab);//數(shù)據(jù)分解
uint filter(uchar dat);//中值濾波
void timer_init(void);//定時(shí)器初始化

uchar h1,h2,h3,h4;//LCD顯示變量
ulint mas,maz;//容量計(jì)算

uchar table[]="0123456789";//顯示數(shù)組
uchar table1[]=".VAWa";

void main()
{
        ulint tempv,tempa;//存放電壓電流值
        AD_init();//ADC初始化
        timer_init();//定時(shí)器初始化
        LCD_init();//LCD初始化
        while(1)
        {
                tempv=filter(0x88);//設(shè)置ADC通道0、開(kāi)始轉(zhuǎn)換
                tablex(tempv*3);//分解數(shù)據(jù)
                zhiling(0x80);//LCD地址
                LCD_data(table[h1]);//
                LCD_data(table[h2]);//
                LCD_data(table1[0]);//
                LCD_data(table[h3]);//
                LCD_data(table[h4]);//
                LCD_data(table1[1]);//顯示

                tempa=filter(0x8f);//設(shè)置ADC通道7、開(kāi)始轉(zhuǎn)換
                if(tempa<=10)//防止數(shù)據(jù)成負(fù)數(shù)
                        tempa=10;
                mas=tempa*3-30;//計(jì)算容量取樣賦值
                tablex(tempa*3-30);//減去LM358失調(diào)的數(shù)值
                zhiling(0x88);//LCD地址
                LCD_data(table[h1]);
                LCD_data(table1[0]);
                LCD_data(table[h2]);
                LCD_data(table[h3]);
                LCD_data(table[h4]);
                LCD_data(table1[2]);

                tablex((tempv*3/10)*((tempa*3-30)/10)/10);//計(jì)算功率
                zhiling(0x80+0x40);
                LCD_data(table[h1]);
                LCD_data(table[h2]);
                LCD_data(table1[0]);
                LCD_data(table[h3]);
                LCD_data(table[h4]);
                LCD_data(table1[3]);

                tablex(maz/1000);//顯示MAH
                zhiling(0x88+0x40);
                LCD_data(table[h1]);
                LCD_data(table1[0]);
                LCD_data(table[h2]);
                LCD_data(table[h3]);
                LCD_data(table[h4]);
                LCD_data(table1[4]);

        }
}
//-------------------------------------------------------------
void delay(uint z)///////////////延時(shí)程序
{
   uint x,y;
   for(x=z;x>0;x--)
   for(y=19;y>0;y--);
}
void AD_init(void)/////////////////////初始化ADC
{
P1ASF=0xff;//P1口全部作為模擬功能AD使用
ADC_RES=0;//清零轉(zhuǎn)換結(jié)果寄存器高8位
ADC_RESL=0;//清零轉(zhuǎn)換結(jié)果寄存器低2位
ADC_CONTR=0x80;//開(kāi)啟AD電源
delay(5);//等待1ms,讓AD電源穩(wěn)定
}

uint AD_get(uchar haha )//ADC讀數(shù)
{
        uint rew;
        ADC_CONTR=haha;//開(kāi)啟AD轉(zhuǎn)換
        _nop_(); _nop_(); _nop_(); _nop_();//要經(jīng)過(guò)4個(gè)CPU時(shí)鐘的延時(shí)
        while(!(ADC_CONTR&0x10));//等待轉(zhuǎn)換完成
        ADC_CONTR&=0xe7;//關(guān)閉AD轉(zhuǎn)換,ADC_FLAG位由軟件清0
        rew=ADC_RES*4+ADC_RESL;//組合成10位
        delay(1);//等待
        return rew;//返回ADC值
}
void zhiling(uchar zhilin)//寫指令
{
        e=0;
        rs=0;
        rw=0;
        P0=zhilin;
        delay(20);
        e=1;
        delay(20);
        e=0;
}
void LCD_data(uchar shuju)//寫數(shù)據(jù)
{
        e=0;
        rs=1;
        rw=0;
        P0=shuju;
        delay(20);
        e=1;
        delay(20);
        e=0;
}
void LCD_init(void)//初始化LCD
{
delay(300);
zhiling(0x38);
delay(100);
zhiling(0x38);
delay(100);
zhiling(0x38);
delay(100);
zhiling(0x38);
zhiling(0x38);
zhiling(0x08);
zhiling(0x01);
zhiling(0x06);
zhiling(0x0c);
}
void tablex(uint tab1)//數(shù)據(jù)分解
{
        h1=tab1/1000;//1023//1
        h2=tab1%1000/100;//023//0
        h3=tab1%100/10;//23//2
        h4=tab1%10;//3
}
uint filter(uchar dat)//中位值濾波
{
   uint value_buf[N];
   uint count,i,j,temp;
   for(count=0;count<N;count++)
   {
                         AD_init();//初始化ADC
      value_buf[count] = AD_get(dat);//讀ADC數(shù)值
      delay(1);
   }
   for (j=0;j<N-1;j++)
   {
      for (i=0;i<N-j;i++)
      {
         if ( value_buf[ i]>value_buf[i+1] )
         {
            temp = value_buf[ i];
            value_buf[ i] = value_buf[i+1];
            value_buf[i+1] = temp;
         }
      }
   }
   return value_buf[(N-1)/2];
}
void timer_init(void)//定時(shí)器初始化
{
        TMOD=0x01;/////////設(shè)置工作方式1
        TH0=(65536-50000)/256;///////賦值
        TL0=(65536-50000)%256;
        EA=1;ET0=1;//開(kāi)總中斷;開(kāi)定時(shí)器中斷
        TR0=1;////////啟動(dòng)計(jì)數(shù)器
}


程序如上,原貼連接:http://www.torrancerestoration.com/bbs/dpj-131969-1.html
看了很久其中幾句就是看不懂,哪位大神給講解下呀,謝謝
問(wèn)題是下面幾句看不懂
tablex(tempv*3);//分解數(shù)據(jù)

if(tempa<=10)//防止數(shù)據(jù)成負(fù)數(shù)
                        tempa=10;
                mas=tempa*3-30;//計(jì)算容量取樣賦值
                tablex(tempa*3-30);//減去LM358失調(diào)的數(shù)值

tablex(maz/1000);//顯示MAH


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

使用道具 舉報(bào)

沙發(fā)
ID:213173 發(fā)表于 2019-8-7 09:34 | 只看該作者
軟件都是基于硬件條件編寫的,離開(kāi)硬件電路圖,有些代碼是很難讀懂的?v觀這程序,原作者的ADC電壓取樣電路可能是直接或通過(guò)分壓電阻取樣、電流取樣電路可能是毫歐級(jí)取樣電阻經(jīng)運(yùn)算放大器LM358放大取樣。經(jīng)軟件濾波后獲取10位ADC數(shù)據(jù),這些數(shù)據(jù)并不能直接顯示電壓和電流,需要經(jīng)過(guò)運(yùn)算和補(bǔ)償才能得到接近實(shí)際電壓和電流的值,并將此值通過(guò)LCD1602顯示出來(lái)。
回復(fù)

使用道具 舉報(bào)

板凳
ID:18488 發(fā)表于 2019-8-7 13:21 | 只看該作者

這個(gè)是電路圖能給幫忙講講嗎謝謝
回復(fù)

使用道具 舉報(bào)

地板
ID:213173 發(fā)表于 2019-8-8 06:34 | 只看該作者
maomaochong 發(fā)表于 2019-8-7 13:21
這個(gè)是電路圖能給幫忙講講嗎謝謝

樓主找的這個(gè)程序只能算是習(xí)作,有很多不成熟的地方。其運(yùn)算ADC結(jié)果的方法也是粗淺的,以致樓主看不明白。
十位ADC結(jié)果換算成10進(jìn)制(4舍5入):毫伏=(參考電壓*十位ADC結(jié)果*10000/1024+5)/10。
再將此值按前置電路的分壓比放大或運(yùn)放放大倍數(shù)縮小,才能得到取樣點(diǎn)的實(shí)際值。
回復(fù)

使用道具 舉報(bào)

5#
ID:56665 發(fā)表于 2019-8-8 08:38 | 只看該作者
tablex(tempv*3);//分解數(shù)據(jù), 就是10K電阻RP2調(diào)到了1.67K的位置。
回復(fù)

使用道具 舉報(bào)

6#
ID:18488 發(fā)表于 2019-8-9 10:10 | 只看該作者
maomaochong 發(fā)表于 2019-8-7 13:21
這個(gè)是電路圖能給幫忙講講嗎謝謝

非常感謝我研究研究
回復(fù)

使用道具 舉報(bào)

7#
ID:18488 發(fā)表于 2019-8-9 10:11 | 只看該作者
m182892 發(fā)表于 2019-8-8 08:38
tablex(tempv*3);//分解數(shù)據(jù), 就是10K電阻RP2調(diào)到了1.67K的位置。

不理解
回復(fù)

使用道具 舉報(bào)

8#
ID:112138 發(fā)表于 2021-5-11 21:40 | 只看該作者

這個(gè)程序應(yīng)該是不全的,不知道什么原因。tempv*3的意思是電壓取樣1/3,這是硬件決定的,所以結(jié)果要*3.
AD值讀出來(lái)不是電壓值,要和基準(zhǔn)電壓AD換算轉(zhuǎn)成電壓值再分解顯示的,這個(gè)直接顯示肯定是錯(cuò)的,這個(gè)程序是不能用的。還有MAZ是什么莫名其妙的突然就蹦出來(lái)顯示。搞不懂樓主轉(zhuǎn)過(guò)來(lái)看過(guò)沒(méi)有
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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