本人在2010年12月份開始制作單片機控制電瓶放電容量檢測儀,經過半個月的努力完成了此項目。在其中遇到的問題數不勝數,但還是用時間和大量精力解決了現有問題。
工作原理:單片機控制放電容量檢測儀是由單片機時鐘控制電路,電子負載,單片機AD轉換電壓電流檢測電路等組成。首先檢測電瓶的當前電壓,根據電壓的大小判斷電瓶是什么狀態,如果小于10.5V說明已經放電結束,檢測儀不能工作,當電壓在充滿電后方可開始準備工作,當按下按鈕S后,啟動信號輸入單片機,單片機內部定時器開始計時,觸發繼電器開始吸合控制電子負載對電瓶進行放電。電子負載是利用控制場效應管的導通角實現恒流放電的。同時單片機AD轉換檢測電流電壓然后送到單片機在通過數碼管顯示出來。當放電電壓不足10.5V時,單片機控制內部定時器停止計時,并將結果鎖存起來,通過數碼管顯示出來。
以下是電子負載的程序資料,原理圖和實物圖
////////////2010.12.09.21:00///////////////////
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define shum P0 //數碼
#define saom P1 //數碼掃描
char ddisp[4]={0,0,0,0};
char ddosp[4]={0,0,0,0};
char code DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar hour=0,min=0,sec=0,rou=0;
uchar deda=0;
bit d_05s=0;
uchar set=0;
void delay(uint k);
sbit out=P3^7;
sbit shut=P3^3;
sbit s=P3^0;
sbit P3_2=P3^2;
/*-----------------------走時函數--------------------------*/
void init_timer()
{
TMOD=0x01;
TH0=(65536-12000)/256; //定時器采用定時4ms. 初值為12000
TL0=(65536-12000)%256;
IE=0x82;
}
/*-----------------------4ms定時中斷服務函數--------------------------*/
void T0_srv(void) interrupt 1
{
TH0=(65536-12000)/256; //定時器采用定時4ms. 初值為12000
TL0=(65536-12000)%256;
deda++ ;
}
/*----------------------時,分,秒單元及走時單元轉換-------------------------*/
void conv()
{
if(deda<=100)d_05s=0;
else d_05s=1;
if(deda>=250){sec++;deda=0;}
if(sec==60){min++;sec=0;}
if(min==60){hour++;min=0;}
if(hour==24){hour=0;}
rou=(sec+min*60)*5;
}
void diyi()
{
ddisp[3]=min/10;
ddisp[2]=min%10;
ddisp[1]=sec/10;
ddisp[0]=sec%10;
}
void dier()
{
ddisp[3]=rou/60/10;
ddisp[2]=rou/60%10;
ddisp[1]=rou%60/10;
ddisp[0]=rou%60%10;
}
/*-------------------走時時間顯示函數部分-------------------------*/
void disp()
{ char j,scan;
scan=0xf7;
for(j=0;j<4;j++)
{
shum=0xff;
saom=scan;
P0=DATA_7SEG[ddisp[j]];
delay(4);
scan>>=1;
}
}
void scan_key()
{
if(s==0)
{
delay(1);
if(s==0)
{
hour=0,min=0,sec=0;out=0;
TR0=1;
}
}
if(shut==1)
{
delay(1);
if(shut==1)
{
TR0=0;
out=1;
}
}
}
/*--------掃描按鍵函數--------*/
void jianpan()
{
delay(1);
if(P3_2==0)set++;
if(set>=2)set=0;
F0:if(P3_2==0)goto F0;
}
/*--------延時函數-------------*/
void delay(uint k)
{
uint i,j;
for(i=0;j<k;i++)
{
for(j=0;j<120;j++);
}
}
/*-----------------主函數-------------------------------------*/
void main()
{
init_timer();
while(1)
{
scan_key();
if(P3_2==0)jianpan();
switch(set)
{
case 0:conv();diyi();disp();break;
case 1:conv();dier();disp();break;
default:break;
}
}
}
// ADC0809模數轉換
//ADC0809采樣通道3輸入的模擬量,轉換后結果顯示在數碼管上
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define shum P1 //數碼
#define saom P2 //數碼掃描
char code tab[10]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F};
char disp[4]={0,0,0,0};
//ADC0809引腳定義
sbit OE=P3^7;
sbit EOC=P3^1;
sbit ST=P3^5;
uchar i;
//延時
void delay(int x)
{
int i,j;
for(i=0;i<x;i++)
for(j=1;j<120;j++);
}
//顯示轉換結果
void display_led(int count2)//數碼管模塊
{char j,scan;
disp[3]=count2%10;
disp[2]=count2%100/10;
disp[1]=count2/100%10;
disp[0]=count2/1000;
scan=0xdf;
for(j=0;j<4;j++)
{
shum=0xff;
saom=scan;
P1=tab[disp[j]];
delay(4);
scan>>=1;
}
}
// 主程序
void main()
{
ST=1;
EOC=1;
OE=1;
//選擇ADC0809通道3(0111)
//高4位設通道地址為0111
while(1)
{
ST=1;
ST=0;
for(i=0;i<1;i++);
ST=1;//啟動轉換
while(EOC==0); //等待轉換結果
OE=0; //允許輸出
display_led(P0); //顯示A/D轉換結果
OE=1; //關閉輸出
}
}
