51单片机制作简易数字电压表

首先打开proteus软件导入各个元器件,并连线。

 接下来介绍下adc0808的导入方法

 频率发生器的导入方法:

 接下来就要编写c程序了,代码都是经过测试的,可以方型复制使用。

#include"reg52.h"               // 引入头文件
#define uint unsigned int       // 把无符号整型简写成 uint
sbit START = P3^0;              //  START接到P3.0口
sbit EOC = P3^1;                //  EOC接到P3.1口
sbit OE = P3^2;                 // OE接到P3.2口
sbit RS = P3^3;                  // RS接到P3.3口
sbit RW = P3^4;                  // RW接到P3.4口
sbit E = P3^5;                   // E接到P3.5口
uint dianya=0;                   //  定义 电压=0
unsigned char str[]={"0123456789.V"};  // 定义lcd显示需要的字符

// 延时函数(不精确的延时)
void delay(uint t){
	uint i=0, j=0;
	for(i=0; i<t; i++){
		for(j=0; j<120; j++);
	}
}

//   模拟转数字 ADC函数  根据时序表来写
void adc(){
	START=0;         
	START=1;
	delay(5);
	START=0;
	while(EOC != 1);
	OE = 1;
	dianya =P2;
	OE = 0;
}

//  lcd写数据函数 写dat首字母
void xdat(unsigned char dat){
	RS = 1;
	RW = 0;
	E = 0;
	P1 = dat;
	delay(5);
	E = 1;
	E = 0;
}

//  lcd写命令函数  写命令首字母xml
void xml(unsigned char ml){
	RS = 0;
	RW = 0;
	E = 0;
	P1 = ml;
	delay(5);
	E = 1;
	E = 0;
}


//  lcd初始化函数
void lcdinit(){
	xml(0x38);
	xml(0x0c);
	xml(0x06);
	xml(0x01);
}

//  更新显示函数
void gengxin(){
	uint v1=0, v2=0, v3=0;    // 定义电压的个位,十分位,百分位变量
	dianya=dianya*100/51;      // 根据电压显示和实际的比例做出先扩大100倍在缩小51倍
	v1 = dianya/100;           // 个位是电压值÷100的整数部分
	v2 = (dianya%100)/10;      // 十分位是电压值÷100的余数在÷10的整数部分
	v3 = dianya%10;            // 百分位是电压值÷10的余数
	
	xml(0x80+0x04);           // 写lcd从第一行第5个字符开始写
	delay(5);                  //  延时5毫秒
	xdat(str[v1]);             // 写字符串str的第v1位
	delay(5);                  //  延时5毫秒
	xdat(str[10]);             // 写字符串str的第10位(.)
	delay(5);                  //  延时5毫秒
	xdat(str[v2]);              // 写字符串str的第v2位
	delay(5);                  //  延时5毫秒
	xdat(str[v3]);             // 写字符串str的第v3位
	delay(5);                  //  延时5毫秒
	xdat(str[11]);              // 写字符串str的第11位(V)
	delay(5);                 //  延时5毫秒
}

// 主函数
void main(){
	lcdinit();        // lcd初始化
	while(1){
		adc();           // 读电压值
		gengxin();        // 更新显示电压值
	}
}

最后就是编译成hex文件并导入proteus中仿真了,然后调节滑动变阻器,就可以发现电压表的值和lcd的值是一样的了,肯定会有误差,而且这个误差没有办法消除。

经过了一段时间的学习,回来又复习一下原来学习的东西,从新写了一遍,大家看看是不是有所进步呢?今天发现proteus也会卡顿,弄得1602没有任何反应,最后我的解决办法是把89c51删除了,从新导入了一个89c52,从新连线,问题解决了。更新一下下面的写法,并使用了c语言的指针语法,证明51中可以使用指针。

下面是程序把1602的显示初始化等函数分成了另外一个文件

下面是主程序adc.c文件的内容,他来调用1602文件中的函数

#include"1602_lcd.h"
sbit start = P3^5;
sbit eoc = P3^6;
sbit oe = P3^7;


void adc(uint * pd)
{
	start = 0;
	start =1;
	delay(2);
	start=0;
	while(eoc != 1);
	oe=1;
	*pd=P2;
	oe=0;
}


void display(uc*sp,uint * pd)
{
	uint dianya,v1,v2,v3;
	dianya=*pd*100/51;
	v1=dianya/100;
	v2=dianya/10%10;
	v3=dianya%10;
	
	writecom(0x80);
	writedat(*(sp+v1));
	writedat('.');
	writedat(*(sp+v2));
	writedat(*(sp+v3));
	writedat('V');
}

int main()
{
	uc str[]="0123456789";
	uint dianya=0;
	uc *sp=str;
	uint * pd = &dianya;
	
	lcd_init();
	
	while(1)
	{
		adc(pd);
		display(sp,pd);
	}
	return 0;
}

下面是1602的头文件

#include<reg52.h>
#define uint unsigned int
#define uc unsigned char
	
sbit RS = P3^0;
sbit RW = P3^1;
sbit E = P3^2;
	
//初始化1602
void lcd_init();


// 写命令函数
void writecom(uc com);


// 写数据函数
void writedat(uc dat);


// 延时函数
void delay(uc t);

下面是1602头文件所对应的.c文件

#include"1602_lcd.h"

// 延时函数
void delay(uc t)
{
	uc i=0, j=0;
	for(i=0;i<t;i++)
	{
		for(j=0;j<120;j++);
	}
}

// 写数据函数
void writedat(uc dat)
{
	RS = 1;
	RW = 0;
	E = 0;
	P1 = dat;
	delay(5);
	E = 1;
	E = 0;
}


// 写命令函数
void writecom(uc com)
{
	RS = 0;
	RW = 0;
	E = 0;
	P1 = com;
	delay(5);
	E = 1;
	E = 0;
}	


//初始化1602
void lcd_init()
{
	writecom(0x38);
	writecom(0x0c);
	writecom(0x06);
	writecom(0x01);
}

上面这种写法是把1602单独写成了一个库文件的方式,以后需要用到1602的时候只需要把库文件1602.c和1602.h导入项目后,就能调用里面写好的函数了,不用从头在想一遍过程了。可以节省一些时间。

  • 9
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
介绍了一种基于STC89C51单片机数字电压表设计方法。该方案根据数据采集的工作原理来实现数字电压的测量, 然后完成单片机与PC的通信, 以将所测量的电压值通过串口传送给PC, 并在PC上进行显示。   数字电压表设计和开发已有很多类型和款式, 传统的数字电压表有自己的特点, 它们适合在现场做手工测量, 而要完成远程测量并对测量的数据做进一步处理, 运用传统的数字电压表是无法完成的。为此, 本文设计了基于PC通信的数字电压表, 该表既可以完成测量数据的传递, 又可借助PC进行测量数据的处理。所以, 这种类型的数字电压表无论在功能和实际应用上, 都具有传统数字电压表无法比拟的优点, 这使得它的开发和应用都具有良好的前景。   本系统主要由硬件和软件两部分构成, 硬件主要包括数据采集电路, 单片机最小数据采集系统, 单片机与PC机的接口电路等。软件主要有单片机数据采集程序, 单片机与上位机通信程序,以及上位机数据处理程序。   该新型数字电压表测量的电压类型为直流,测量范围为0 ~5 V, 下位机采用的单片机为STC89C51, AD转化采用的是最常见的ADC0809,可通过RS232串行口与PC机进行通信, 以传送所测量的直流电压数据。图1所示是该数字电压表的数据采集电路。电路的设计已做到了最小化,即没有用任何附加逻辑器件做接口电路, 便可实现单片机对ADC0809转换芯片的操作。图1中的ADC0809是8位的模数转化芯片, 片内有8路模拟选通开关以及相应的通道锁存译码电路, 转化时间大约为100 μs左右。在电路应用中, 首先要指定ADC0809的数据通道, 当外部电压进入芯片后, STATR 信号由高到低, 在脉冲的下降沿ADC0809开始转换, 同时管脚EOC电平变低, 表示转化正在进行, 转化完成之后, 管脚EOC的电平变高, 表示一次转化结束。
下面是一个使用Java制作左移特效文字视频并将其保存到本地的简单示例: ```java import javafx.application.Application; import javafx.embed.swing.SwingFXUtils; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.stage.Stage; import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; public class LeftMoveTextVideo extends Application { private static final int WIDTH = 800; // 视频宽度 private static final int HEIGHT = 600; // 视频高度 private static final int FRAME_RATE = 30; // 帧率 private static final int DURATION = 5; // 视频时长(秒) @Override public void start(Stage primaryStage) { primaryStage.setTitle("左移特效文字视频"); // 创建画布 Canvas canvas = new Canvas(WIDTH, HEIGHT); GraphicsContext gc = canvas.getGraphicsContext2D(); // 设置背景颜色 gc.setFill(Color.BLACK); gc.fillRect(0, 0, WIDTH, HEIGHT); // 设置字体样式 Font font = Font.font("Arial", FontWeight.BOLD, 48); gc.setFont(font); gc.setFill(Color.WHITE); Group root = new Group(canvas); Scene scene = new Scene(root, WIDTH, HEIGHT, Color.BLACK); primaryStage.setScene(scene); primaryStage.show(); // 创建视频帧保存目录 File framesDir = new File("frames"); framesDir.mkdir(); // 生成每一帧的图片,并保存到本地 for (int frame = 0; frame < FRAME_RATE * DURATION; frame++) { gc.clearRect(0, 0, WIDTH, HEIGHT); double x = frame * WIDTH / (FRAME_RATE * DURATION); gc.fillText("Left Move Effect", x, HEIGHT / 2); // 保存当前帧到本地 WritableImage snapshot = root.snapshot(new SnapshotParameters(), null); File outputFile = new File(framesDir, String.format("frame%05d.png", frame)); try { ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", outputFile); } catch (IOException e) { e.printStackTrace(); } } System.out.println("视频帧已保存到本地!"); } public static void main(String[] args) { launch(args); } } ``` 在这个例子中,我们使用JavaFX创建一个800x600像素大小的窗口,并在窗口中绘制“Left Move Effect”文字。然后,我们将每一帧的画面保存为单独的PNG图像文件(帧数和时长由常量定义)。最后,所有的帧都保存在一个名为"frames"的目录中。 运行这个Java程序后,你将在项目目录下看到一个名为"frames"的文件夹,其中包含所有的视频帧。你可以使用视频编辑软件(如Adobe Premiere、Final Cut Pro等)将这些帧合并为一个完整的视频文件,并将其保存到本地。 请注意,这只是一个简单的示例,用于演示如何制作一个左移特效文字视频。如果你需要更复杂的视频特效或更高的视频质量,可能需要使用更专业的视频处理库或工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尚久龙

你的鼓励是我最大的动力!谢谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值