单片机LCD1602显示程控测量放大器
<div class='showpostmsg'><p> 因为这学期的课程设计我做了这个测量放大器,并且给他加上了单片机的功能以及串行通信的功能,可以说是非常全面的。</p><p>刚开始的时候是放大1000倍,然后放大1000倍的数值可以在单片机中显示。然后我们通过第一模块对他进行筛检,并且通过五个按键实现零到1000倍的衰减衰减后再通过D A C输出。整个过程,我们在测量放大器的基础上做了很多的改进单片机程序相对复杂,然后再试相比来说我们用了七天的时间。还是挺成功的<br />
总体电路图</p>
<p>对应的单片机部分程序:</p>
<p>#include<reg51.h><br />
#include "lcd.h"<br />
#include<absacc.h><br />
#define DAC1208 XBYTE<br />
#define uint unsigned int<br />
#define uchar unsigned char<br />
#define ulong unsigned long</p>
<p>sbit k2 = P3^2;<br />
sbit k3 = P3^3;<br />
sbit k4 = P3^4;<br />
sbit k5 = P3^5;<br />
sbit relay=P2^4;<br />
sbit relayAD=P3^7;</p>
<p>char temp=-1;<br />
int cent;<br />
ulong volt;//测量的电压值<br />
ulong sum;<br />
uchar mode,a,b,y=0,t=0,y1=0,t1=0,y2=0,t2=0,abs=5;<br />
uchar KEY_Scan(uchar mode);<br />
uchar timebit,multiplebit;<br />
uchar vol_buf,multiple_buf,out_buf;<br />
uint multiple=500;<br />
char time=-1;<br />
void delay1us(uint i);<br />
void communication();<br />
void kai_display();<br />
void kai_display1();<br />
void count();<br />
void display1();<br />
void display();</p>
<p>uint vtime; // 用来控制测量地址位的改变<br />
uchar addr;//测量地址位,指示测量的是哪一个模拟值 (其实就是TLC2543的控制字)</p>
<p><br />
sbit CLK=P2^3;//定义时钟信号口<br />
sbit DIN=P2^1;//定义2543数据写入口<br />
sbit DOUT=P2^0;//定义2543数据读取口<br />
sbit CS=P2^2;//定义2543片选信号口</p>
<p>void delay1us(uint i)<br />
{<br />
while(i--);<br />
}<br />
/**********************************************************/<br />
//函数名:read2543(uchar addr)<br />
//功能:2543驱动程序<br />
//调用函数:<br />
//输入参数:addr<br />
//输出参数:<br />
//说明:进行ad转换将结果存于volt变量中 addr为测量位地址<br />
/**********************************************************/<br />
void read2543(uchar addr) //读取数值volt是被缩小两倍的电压<br />
{<br />
uint ad=0;<br />
uchar i;<br />
CLK=0;<br />
CS=0;//片选段,启动2543<br />
addr<<=4;//对地址位预处理<br />
for(i=0;i<12;i++) //12个时钟走完,完成一次读取测量<br />
{<br />
if(DOUT==1)<br />
ad=ad|0x01;//单片机读取ad数据<br />
DIN=addr&0x80;//2543读取测量地址位<br />
CLK=1;<br />
;;;//很短的延时<br />
CLK=0;//产生下降沿,产生时钟信号<br />
;;;<br />
addr<<=1;<br />
ad<<=1;//将数据移位准备下一位的读写<br />
}<br />
CS=1;//关2543<br />
ad>>=1;<br />
volt=ad;//取走转换结果<br />
volt=volt*1221*2;//例子的满量程为5V,转换分辩率为12位(2的12次方=4096) 。即最大值是255,5/4096=1221mV,即例子中的1V代表实际1221mV <br />
}</p>
<p>void communication()<br />
{<br />
if(RI != 0)<br />
{<br />
RI = 0; //接收收据后进行清0<br />
temp = SBUF; //读取数据存入temp中<br />
}<br />
if(temp==0)<br />
{ <br />
time=0;//选择相应的指令<br />
abs=0;<br />
temp=-1;<br />
}<br />
else if(temp==1)<br />
{ <br />
time=1;<br />
abs=1;<br />
temp=-1;<br />
}<br />
else if(temp==2)<br />
{ <br />
time=2;<br />
abs=2;<br />
temp=-1;<br />
}<br />
else if(temp==3)<br />
{ <br />
time=3;<br />
temp=-1;<br />
}<br />
else if(temp==4)<br />
{<br />
time=4;<br />
temp=-1;<br />
}<br />
}<br />
#define K0 0<br />
#define K1_MODE 1<br />
#define K2_ADD 2<br />
#define K3_DEC 3<br />
#define K4 4<br />
uchar KEY_Scan(uchar mode)<br />
{<br />
uchar key=1;<br />
if(key&&(time>=0&&time<=4))<br />
{<br />
key=0;<br />
if(time==0)<br />
{<br />
return K0;<br />
}<br />
else if(time==1)<br />
{<br />
return K1_MODE;<br />
}<br />
else if(time==2)<br />
{<br />
return K2_ADD;<br />
}<br />
else if(time==3)<br />
{<br />
return K3_DEC; <br />
}<br />
else if(time==4)<br />
{<br />
return K4; <br />
}<br />
}<br />
else if(time>=5&&time<=-1)<br />
{<br />
key=1; <br />
}<br />
if(a)<br />
{<br />
key=1;<br />
}<br />
return 5; <br />
}</p>
<p>void kai_display()<br />
{<br />
LCD_Dispstring(0,0,"WangZheng And");<br />
LCD_Dispstring(0,1,"GuoXuKang's Work");<br />
}</p>
<p>void kai_display1()<br />
{<br />
uchar key;<br />
key=KEY_Scan(0);<br />
if(key==K4||b==K4) //模式选择 直流<br />
{<br />
relay=1;<br />
relayAD=1;<br />
display();<br />
b=K4; //便于按一次直流,之后一直是直流<br />
LCD_Dispstring(2,0,"DIR: V");<br />
LCD_Dispstring(0,1,"M: O: V"); <br />
}<br />
if(key==K3_DEC||b==K3_DEC) //交流档位<br />
{<br />
relay=0;<br />
relayAD=0;<br />
display1();<br />
b=K3_DEC;<br />
LCD_Dispstring(2,0,"ALT: V");<br />
LCD_Dispstring(0,1,"M: O: V"); <br />
}<br />
}<br />
void display()//直流显示<br />
{<br />
ulong invol;<br />
float ivol;<br />
count();<br />
ivol=(volt*1.000*multiple)/1000;<br />
invol=(long)ivol;<br />
vol_buf=volt/10000000+0x30; <br />
vol_buf=volt/1000000+0x30; <br />
vol_buf='.';<br />
vol_buf=(volt/100000)%10+0x30;<br />
vol_buf=(volt/10000)%10+0x30;<br />
vol_buf=(volt/1000)%10+0x30;<br />
vol_buf='\0';</p>
<p> multiple_buf=multiple/1000+0x30; <br />
multiple_buf=multiple/100%10+0x30; <br />
multiple_buf=multiple/10%10+0x30;<br />
multiple_buf=multiple%10+0x30;<br />
multiple_buf='\0';</p>
<p> out_buf=invol/10000000+0x30; <br />
out_buf=invol/1000000+0x30; <br />
out_buf='.';<br />
out_buf=(invol/100000)%10+0x30;<br />
out_buf=(invol/10000)%10+0x30;<br />
out_buf=(invol/1000)%10+0x30;<br />
out_buf='\0';</p>
<p> LCD_Dispstring(6,0,vol_buf);<br />
LCD_Dispstring(2,1,multiple_buf);<br />
LCD_Dispstring(8,1,out_buf);<br />
}<br />
void display1()//交流显示<br />
{<br />
ulong invol,trans;<br />
float ivol;<br />
count();<br />
trans=volt*0.825;<br />
ivol=(volt*0.825*multiple)/1000;<br />
invol=(long)ivol;<br />
vol_buf=trans/10000000+0x30; <br />
vol_buf=trans/1000000+0x30; <br />
vol_buf='.';<br />
vol_buf=(trans/100000)%10+0x30;<br />
vol_buf=(trans/10000)%10+0x30;<br />
vol_buf=(trans/1000)%10+0x30;<br />
vol_buf='\0';</p>
<p> multiple_buf=multiple/1000+0x30; <br />
multiple_buf=multiple/100%10+0x30; <br />
multiple_buf=multiple/10%10+0x30;<br />
multiple_buf=multiple%10+0x30;<br />
multiple_buf='\0';</p>
<p> out_buf=invol/10000000+0x30; <br />
out_buf=invol/1000000+0x30; <br />
out_buf='.';<br />
out_buf=(invol/100000)%10+0x30;<br />
out_buf=(invol/10000)%10+0x30;<br />
out_buf=(invol/1000)%10+0x30;<br />
out_buf='\0';</p>
<p> LCD_Dispstring(6,0,vol_buf);<br />
LCD_Dispstring(2,1,multiple_buf);<br />
LCD_Dispstring(8,1,out_buf);</p>
<p>}</p>
<p>void count()<br />
{<br />
if(multiple<=999&&multiple>=0)<br />
{<br />
if(abs==0)<br />
{<br />
multiple++;<br />
if(multiple%10==9||t==1)<br />
{<br />
y++;<br />
t=1; //到9后下一次变为0<br />
if(y==2)<br />
{<br />
t=0;<br />
multiple=multiple-10;<br />
y=0;<br />
}<br />
}<br />
<br />
abs=5;<br />
}<br />
if(abs==1)<br />
{<br />
multiple=multiple+10;<br />
if((multiple/10%10==9)||t1==1)<br />
{<br />
y1++;<br />
t1=1;<br />
if(y1==2)<br />
{<br />
t1=0;<br />
multiple=multiple-100;<br />
y1=0;<br />
}<br />
}<br />
abs=5;<br />
}<br />
if(abs==2)<br />
{ <br />
multiple=multiple+100;<br />
if((multiple/100==9)||t2==1)<br />
{<br />
y2++;<br />
t2=1;<br />
if(y2==2)<br />
{<br />
t2=0;<br />
multiple=multiple-1000;<br />
y2=0;<br />
}<br />
}<br />
abs=5;<br />
}<br />
}<br />
if(multiple<0)//y用来监视从1减小,然后维持,最小为0<br />
{<br />
multiple=0;<br />
}<br />
if(multiple>999)//y用来监视从1减小,然后维持,最小为0<br />
{<br />
multiple=999;<br />
}<br />
}</p>
<p>void main(void)<br />
{<br />
LCD_Init(); //LCD初始化<br />
kai_display();//最初显示<br />
delay1us(50);<br />
LCD_Clear();//清除</p>
<p> TMOD = 0x22; //设置定时器T1为方式2<br />
TH1 = 0xfd; <br />
TL1 = 0xfd;<br />
TH0=0x06;<br />
TL0=0x06;<br />
EA=1;<br />
ET0=1;<br />
TR0=1;<br />
SCON = 0x50; //设置串口为方式1接收,REN = 1<br />
PCON = 0x00; //SMOD = 0;,波特率不加倍<br />
TR1 = 1; //开启定时器T1<br />
TI = 1;<br />
relay=0;<br />
relayAD=0;<br />
while(1)<br />
{<br />
read2543(addr);//调用2543驱动程序测量地址为0<br />
communication(); <br />
kai_display1();<br />
}<br />
}<br />
void DA_OUT(int i)<br />
{<br />
int num,num1,num2;<br />
num=i*4.099*8;<br />
num=num>>3;<br />
num1=num>>8;<br />
num2=num&0xff;<br />
DAC1208=num2;<br />
k2=num1&0x01;<br />
k3=num1&0x02;<br />
k4=num1&0x04;<br />
k5=num1&0x08;<br />
}<br />
void f1 () interrupt 1<br />
{<br />
cent++;<br />
if(cent==5000)<br />
{<br />
cent=0;<br />
DA_OUT(multiple);<br />
}<br />
}</p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页:
[1]