『壹』 能帮帮编写个单片机数字电压表仿真设计的程序代码吗用C语言。
数字电压表仿真实例,可以参考一下。
『贰』 单片机设计制作数字电压表
数字电压表是诸多数字化仪表的核心与基础,电压表的数字化是将连续的模拟量如直流电压转换成不连续的离散的数字形式并加以显示,这有别于传统的以指针加刻度盘进行读数的方法,避免了读数的误差和视觉疲劳。目前数字万用表的内部核心部件是A/D转换器,转换器的精度很大程度上影响着数字万用表的准确度,本设计—数字电压表 A/D转换器采用ADC0808对输入模拟信号进行转换,控制核心AT89S51在对转换的结果进行运算和处理,最后驱动输出装置显示数字电压信号。数字电压表是诸多数字化仪表的核心与基础,电压表的数字化是将连续的模拟量如直流电压转换成不连续的离散的数字形式并加以显示,这有别于传统的以指针加刻度盘进行读数的方法,避免了读数的误差和视觉疲劳。目前数字万用表的内部核心部件是A/D转换器,转换器的精度很大程度上影响着数字万用表的准确度,本设计—数字电压表 A/D转换器采用ADC0808对输入模拟信号进行转换,控制核心AT89S51在对转换的结果进行运算和处理,最后驱动输出装置显示数字电压信号。并可以在LED上进行显示,可以显示电压值的小数点后两位。
关键词:单片机 数字电压表 AT89S51 ADC0808
系统总体设计要求:利用单片机AT89S51和ADC0809对直流电压0~5V进行采集,并在LED上进行显示,可以显示电压值的小数点后两位。
1. 实验任务
利用单片机AT89S51与ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,但要求使用的元器件数目最少。 2. 电路原理图
图1.28.1
3. 系统板上硬件连线
a) 把“单片机系统”区域中的P1.0-P1.7与“动态数码显示”区域中的ABCDEFGH端口用8芯排线
连接。
b) 把“单片机系统”区域中的P2.0-P2.7与“动态数码显示”区域中的S1S2S3S4S5S6S7S8端口用8
芯排线连接。
c) 把“单片机系统”区域中的P3.0与“模数转换模块”区域中的ST端子用导线相连接。 d) 把“单片机系统”区域中的P3.1与“模数转换模块”区域中的OE端子用导线相连接。 e) 把“单片机系统”区域中的P3.2与“模数转换模块”区域中的EOC端子用导线相连接。 f) 把“单片机系统”区域中的P3.3与“模数转换模块”区域中的CLK端子用导线相连接。 g) 把“模数转换模块”区域中的A2A1A0端子用导线连接到“电源模块”区域中的GND端子上。 h) 把“模数转换模块”区域中的IN0端子用导线连接到“三路可调电压模块”区域中的VR1端子上。 i) 把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“模数转换模块”区域中的
D0D1D2D3D4D5D6D7端子上。
4. 程序设计内容
i. 由于ADC0809在进行A/D转换时需要有CLK信号,而此时的ADC0809的CLK是接在AT89S51单片机的
P3.3端口上,也就是要求从P3.3输出CLK信号供ADC0809使用。因此产生CLK信号的方法就得用软件来产生了。
『叁』 基于单片机的数字电压表设计 (请不要完成抄袭)
我给你看看我以前做过的数字电压表,汇编的
COM EQU 50H ;指令寄存器
DAT EQU 51H ;数据寄存器
RS EQU P2.1 ;LCD寄存器选择信号
RW EQU P2.2 ;LCD读/写选择信号
E EQU P2.3 ;LCD使能信号
ORG 0000H
LJMP MAIN ;主程序入口地址
ORG 000BH
LJMP BT0 ;T0中断入口
ORG 0030H ;主程序,初始化
MAIN:
MOV SP,#60H
LCALL INT
MOV 30H,#30H ;电压整数位
MOV 31H,#02EH ;小数点位
MOV 32H,#30H ;小数个位
MOV 33H,#30H ;小数十位
MOV 34H,#30H ;小数百位
MOV 35H,#56H ;字符"V"
MOV R7,#30H
LCALL STR0 ;显示字符串0
LCALL DELAY
LCALL STR1 ;显示森尘游字符串1
LCALL DELAY
LCALL N2 ;显示Voltage=0.000V
;***********定时器初始化程序***********
MOV TMOD,#00H ;定时器T0设为方式0
MOV TH0,#00H ;装入定时常数定时100us
MOV TL0,#00H
SETB TR0 ;启动T0
MOV 24H,#08H;装入T0中断次数
MOV IE,#82H ;开中断
LP:
此销MOV R7,#30H ;显示缓冲区首地址
LCALL DISPLY
SJMP LP ;循环显示
LED1:CLR P3.0
RET
DISPLY: ;LCD显示子程序
MOV COM,#0CAH
LCALL PR1
MOV DAT,30H
LCALL PR2
MOV DAT,31H
LCALL PR2
MOV DAT,32H
LCALL PR2
MOV DAT,33H
LCALL PR2
MOV DAT,34H
LCALL PR2
MOV DAT,35H
LCALL PR2
RET
STR0:
MOV COM,#01H
LCALL PR1
MOV COM,#06H
LCALL PR1
MOV COM,#090H ;设置DDRAM地址
LCALL PR1 ;调写指令代码子兄唯程序
MOV DPTR,#TAB4
MOV R2,#16
MOV R3,#00H
WRIN0:
MOV A,R3
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
INC R3
DJNZ R2,WRIN0
MOV COM,#0D0H
LCALL PR1
MOV DPTR,#TAB5
MOV R2,#16
MOV R3,#00H
WRIN1:
MOV A,R3
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
INC R3
DJNZ R2,WRIN1
MOV R3,#10H
ZUOYI:
MOV COM,#18H
LCALL PRX
DJNZ R3,ZUOYI
LCALL DELAY00
LCALL DELAY00
LCALL DELAY00
LCALL DELAY00
RET
RET
STR1:
MOV COM,#01H ;LCD清0命令
LCALL PR1 ;调写指令代码子程序
MOV COM,#06H ;输入方式命令,光标右移
LCALL PR1 ;调写指令代码子程序
MOV COM,#40H
LCALL PR1
MOV R5,#20H
MOV DPTR,#ZI
MOV R4,#0
LOOP1:MOV A,R4
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
INC R4
DJNZ R5,LOOP1
MOV COM,#80H
LCALL PR1
MOV DPTR,#TAB2
MOV A,#00H
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
MOV A,#01H
MOV DPTR,#TAB2
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
MOV A,#02H
MOV DPTR,#TAB2
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
MOV A,#03H
MOV DPTR,#TAB2
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
MOV R1,#00H
MOV R0,#0dH
MOV DPTR,#TAB3
LOOP2:MOV A,R1
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
INC R1
DJNZ R0,LOOP2
RET
N2: MOV COM,#0C0H
LCALL PR1
MOV DPTR,#TAB1
MOV R2,#10
MOV R3,#00H
WRIN:
MOV A,R3
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
INC R3
DJNZ R2,WRIN
RET
TAB1: DB "VOLTAGE = "
TAB2: DB 00H
DB 01H
DB 02H
DB 03H
DB 04H
DB 05H
TAB3:DB "10701 tcw "
ZI: DB 009H,00AH,00CH,01FH,00CH,00AH,00CH,009H
DB 004H,004H,01FH,004H,00AH,00AH,011H,000H
DB 004H,004H,01FH,01FH,01FH,004H,007H,000H
DB 004H,00EH,010H,00EH,000H,00EH,003H,000H
TAB4:DB " welcome ! "
TAB5:DB "DESIGN BY tcw"
TAB6:DB "123456"
;********************************************************************
;定时器T0中断服务子程序,读取ADC0809第0通道的A/D转换结果并化为显示值*
;********************************************************************
BT0:
PUSH ACC
PUSH PSW
MOV PSW,#08H
CLR TR0
MOV TH0,#00H ;重新装入初值
MOV TL0,#00H
DEC 24H
MOV A,24H
JNZ RTN1
MOV 24H,#08H
LCALL ADC
RTN1: SETB TR0
POP PSW
POP ACC
RETI
ADC:
MOV DPTR,#0F6FFH
MOV A,#0 ;选择通道0
MOVX @DPTR,A ;启动AD转换
MOV A,#40H
DJNZ ACC,$
MOVX A,@DPTR
MOV 22H,A
MOV 21H,#0CCH
CJNE A,21H,BJ0
BJ0:JNC LED
SJMP LL0
LL0:SETB P3.0
SJMP LL
LED:LCALL LED1
LL: MOV A,22H
MOV B,#05H ;A/D转换结果化为显示值
MUL AB ;(AD*5)/256
MOV 30H,B ;AD*5的高字节为整数部分
MOV B,#0AH
MUL AB ;AD*5的低字节为/256的结果,为小数部分
MOV 32H,B ;二进制小数换为10进制数
MOV B,#0AH
MUL AB
MOV 33H,B
MOV B,#0AH
MUL AB
MOV 34H,B
MOV A,30H
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 30H,A
MOV A,32H
MOVC A,@A+DPTR
MOV 32H,A
MOV A,33H
MOVC A,@A+DPTR
MOV 33H,A
MOV A,34H
MOVC A,@A+DPTR
MOV 34H,A
RET
TAB: DB "0123456789"
;*****************************************
;****LCD间接控制方式下的初始化子程序******
;*****************************************
INT:
LCALL DELAY
MOV COM,#38H ;设置工作方式
LCALL PR1
MOV COM,#01H
LCALL PR1
MOV COM,#06H
LCALL PR1
MOV COM,#0CH
LCALL PR1
RET
DELAY: ;延时子程序
MOV R6,#0FH
MOV R7,#00H
DELAY1:
NOP
DJNZ R7,DELAY1
DJNZ R6,DELAY1
RET
DELAY00: ;延时子程序
MOV R6,#0FFH
MOV R7,#0FFH
DELAY0:
NOP
DJNZ R7,DELAY1
DJNZ R6,DELAY1
RET
;*********************************************
;*******LCD间接控制方式下的驱动子程序*********
;*********************************************
;2 写指令代码子程序
PRX:
PUSH ACC
CLR RS
SETB RW
PR110:
MOV P0,#0FFH
SETB E
LCALL DELAY00
NOP
MOV A,P0
CLR E
JB ACC.7,PR11
CLR RW
MOV P0,COM
SETB E
CLR E
POP ACC
RET
PR1:
PUSH ACC
CLR RS
SETB RW
PR11:
MOV P0,#0FFH
SETB E
LCALL DELAY
NOP
MOV A,P0
CLR E
JB ACC.7,PR11
CLR RW
MOV P0,COM
SETB E
CLR E
POP ACC
RET
;3 写显示数据子程序
PR2:
PUSH ACC
CLR RS
SETB RW
PR21:
MOV P0,#0FFH
SETB E
LCALL DELAY
MOV A,P0
CLR E
JB ACC.7,PR21
SETB RS
CLR RW
MOV P0,DAT
SETB E
CLR E
POP ACC
RET
END
『肆』 单片机双路数字电压表,之前一哥们给的程序如下可以实现循环测量显示IN0,IN1电压,现要求如下
说好200分的……
#include "reg52.h"
const unsigned char LED7Code[]={ //共阴极7段显示
0x3F, // 0
0x06, /桐谨/ 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void delay(unsigned int i) /*延时1014i+13 机器周期*/
{ int j;
for(;i>0;i--)
for(j=0;j<125;j++);
}
void delayus(unsigned char i) /*延时8i+10 机器周期*/
{while(i>0)
i--;
}
sbit start=P3^0;
sbit clk=P3^3;
sbit eoc=P3^2;
sbit oe=P3^1;
sbit add1=P3^4;
sbit add2=P3^5;
sbit add3=P3^6;
sbit key1=P2^5;
sbit key2=P2^6;
main()
{
unsigned char i,j=0;
long U=0;
unsigned char flag=0; //循环与否标志
unsigned char key1_tmp=1,key2_tmp=1; //两个按余轮锋键状态暂存
while(1)
{
add1=j%2;add2=0;add3=0; //通道地址
clk=1;
start=0;
start=1;
start=0; //启动转换
eoc=1;
clk=0; delayus(5); //clk信号下降沿对eoc信号线进行检测
while(!eoc)
{
clk=1; delayus(5);
clk=0; delayus(5);
eoc=1;
}
oe=1; //0808输出允许
P0=0xff; //单片机从P0口读取数据
U=P0*5L*100/256;
for(i=0;i<100;i++)
{
P1=LED7Code[j%2]; P2=0xfe; delay(1); P1=0;
P1=LED7Code[U/100]|0x80; P2=0xfd; delay(1); P1=0; /竖晌/|0x80目的是加小数点
P1=LED7Code[U%100/10]; P2=0xfb; delay(1); P1=0;
P1=LED7Code[U%10]; P2=0xf7; delay(1); P1=0;
key1=1; //按键1
if(!key1&&key1_tmp)
{flag=!flag;key1_tmp=key1;break;} //当按键1检测到下降沿时,循环标志置取反
key2=1; //按键2
if(!key2&&key2_tmp)
{j++;key2_tmp=key2;break;} //当按键2检测到下降沿时,通道地址加一
key1_tmp=key1;
key2_tmp=key2;
}
if(flag)
j++; //通道地址加一
}
}
『伍』 用单片机设计一个自动切换量程的数字电压表,做了出了一点问题
既然你设计有20V的量程,而你的运放电路那块是正向放大,正向放大,最小的放大倍数都是1 ,如果你输入20V电压,运放饱和了, 并且也超过了ADC的输入范围,你的ADC的参考电压是5V,则输入到ADC的电压最大就是5V。可以将运放设计成反向放大。数据由单片机处理再反向过来。还有,如果是反向放大的话,输入信号20V,则超过了运放的电源电压。差模输入电压范围一般是低于运放的电源电压的,共模输入也是一样,你可以看看运放手册就知道了。所以如果要做到20V的输入量程,要么在输入的地方做一级电阻分压,降低输入到运放的电压到<10V以下。要么就提高运放的电源电压,建议正电压>24V。但是做反向放大的注意输入阻抗,一般电压表的输入阻抗越大越好。还有做好输入端的保护,在负输入端加一个22V的稳扮亩压管比较妥当,防止过牙烧毁运放。在ADC的输入的地方加一个5.6V的稳压管,防止运放输出过大损坏ADC
只看你的运放这个电路,放大倍数是1, 11, 101,是否有误差出现?
你的量程切换这块,考虑2个问题,
1. 如果输入电压变化很快,你的切换将会很多,基本上输入到数码管上,你是看不清楚的,所以在软件上加一个平均滤波算法,使得显示更稳定。当然如果只厅昌森是做电压表的话,硬件上加一级有源低通滤波器的话就更好,1,可以滤除高频干扰,2,可以使采集的信号变化缓慢,利于采集的稳定和显示。在加上软件滤波算法。可以进一步稳定。
2. 电子开关切换是需要时间的,如果检测到信号过小,需要切换到大量程,先不要断开当前量程开关,而是要先打开大量程开关,再来关闭小量程开关。可以防止切换的一瞬间,因运放处于开环状态,输出一个大尖峰电压到ADC。在硬件上,可以在模拟电子开关和反馈电阻之间接入一个小电容,也可以防止进入开关状态。还有,这个电容还可以起到滤迅乎除高频干扰的作用。
代码就不看了。累的很。。。。
好了,打字打的好累,哎,可惜没有分!
『陆』 单片机双路循环显示数字电压表设计(c语言)
你好!
你的这个可以实现,c语言编写代码吗?