当前位置: 首页 > article >正文

63 基于单片机的四个速度比较

所有仿真详情导航:

PROTEUS专栏说明-CSDN博客

目录

一、主要功能

二、硬件资源

三、主程序编程

四、资源下载


一、主要功能

        基于51单片机,采用四个滑动变阻器连接数模转换器模拟四个速度值,通过LCD1602显示,然后检测出最高的值,其他三个与之相减,绝对值小于10的速度找出,这时候采用四个LED灯分别对应四个速度,绝对值小于10的速度对应的状态灯亮起

具体动态效果看B站演示视频(高清需要跳转到B站看)

基于单片机的四个速度比较_哔哩哔哩_bilibili

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

三、主程序编程

#include <REGX52.H>
#include<intrins.h>
#include<stdio.h>
#include <stdlib.h>
#include "Delay.h"
#include "LCD1602.h"
#define uchar unsigned char
#define uint unsigned  int

sbit ADC_CS=P2^5;                 //adc0832引脚
sbit ADC_CLK=P2^6;
sbit ADC_DI=P2^7;
sbit ADC_DO=P2^4;
sbit ADC_CS1=P1^0;                 //adc0832引脚
sbit ADC_CLK1=P1^1;
sbit ADC_DI1=P1^2;
sbit ADC_DO1=P1^3;
sbit s1led = P3^5;
sbit s2led = P3^6;
sbit s3led = P3^7;
sbit s4led = P2^3;
static double u,u1,u2,u3;      //定义浓度变量
uchar get_AD_Res()            //ADC0832启动读取函数
{
	 unsigned char i,ch;

ADC_CS=0; //片选,DO为高阻态
ADC_DO=0;
Delay(2);

ADC_CLK=0;
Delay(2);
ADC_DI=1;
ADC_CLK=1;//第一个脉冲,起始位
Delay(2);

ADC_CLK=0;
Delay(2);
ADC_DI=1;
ADC_CLK=1;//第二个脉冲,DI=1表示双通道单极性输入
Delay(2);

ADC_CLK=0;
Delay(2);
ADC_DI=0; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0时选择通0(CH1)
ADC_CLK=1;
Delay(2);

ADC_DI=0; //DI转为高阻态,失去输入意义;
ADC_DO=1; //DO脱离高阻态为输出数据作准备

ADC_CLK=1;
Delay(2);
ADC_CLK=0; //第一个下降沿,为去数准备;
Delay(2); //这里加一个脉冲AD才能正确读出数据,不加的话读出的数据少一位,且是错的。

for (i=0; i<8; i++) //读取数据
    {
    ADC_CLK=1;
    Delay(2);
    ADC_CLK=0;
    Delay(2);
    ch=(ch<<1)|ADC_DO;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数
   }
  
     ADC_CS=1;//取消片选,一个转换周期结束
   return(ch);//把转换结果返回
}

uchar get_AD_Res_CH1() // 读取CH1端口的AD值
{
    	 unsigned char i,ch;

ADC_CS=0; //片选,DO为高阻态
ADC_DO=0;
Delay(2);

ADC_CLK=0;
Delay(2);
ADC_DI=1;
ADC_CLK=1;//第一个脉冲,起始位
Delay(2);

ADC_CLK=0;
Delay(2);
ADC_DI=1;
ADC_CLK=1;//第二个脉冲,DI=1表示双通道单极性输入
Delay(2);

ADC_CLK=0;
Delay(2);
ADC_DI=1; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0时选择通0(CH1)
ADC_CLK=1;
Delay(2);

ADC_DI=0; //DI转为高阻态,失去输入意义;
ADC_DO=1; //DO脱离高阻态为输出数据作准备

ADC_CLK=1;
Delay(2);
ADC_CLK=0; //第一个下降沿,为去数准备;
Delay(2); //这里加一个脉冲AD才能正确读出数据,不加的话读出的数据少一位,且是错的。

for (i=0; i<8; i++) //读取数据
    {
    ADC_CLK=1;
    Delay(2);
    ADC_CLK=0;
    Delay(2);
    ch=(ch<<1)|ADC_DO;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数
   }
  
     ADC_CS=1;//取消片选,一个转换周期结束
   return(ch);//把转换结果返回
}


uchar get_AD_Res1()            //ADC0832启动读取函数
{
	 unsigned char i,ch;

ADC_CS1=0; //片选,DO为高阻态
ADC_DO1=0;
Delay(2);

ADC_CLK1=0;
Delay(2);
ADC_DI1=1;
ADC_CLK1=1;//第一个脉冲,起始位
Delay(2);

ADC_CLK1=0;
Delay(2);
ADC_DI1=1;
ADC_CLK1=1;//第二个脉冲,DI=1表示双通道单极性输入
Delay(2);

ADC_CLK1=0;
Delay(2);
ADC_DI1=0; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0时选择通0(CH1)
ADC_CLK1=1;
Delay(2);

ADC_DI1=0; //DI转为高阻态,失去输入意义;
ADC_DO1=1; //DO脱离高阻态为输出数据作准备

ADC_CLK1=1;
Delay(2);
ADC_CLK1=0; //第一个下降沿,为去数准备;
Delay(2); //这里加一个脉冲AD才能正确读出数据,不加的话读出的数据少一位,且是错的。

for (i=0; i<8; i++) //读取数据
    {
    ADC_CLK1=1;
    Delay(2);
    ADC_CLK1=0;
    Delay(2);
    ch=(ch<<1)|ADC_DO1;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数
   }
  
     ADC_CS1=1;//取消片选,一个转换周期结束
   return(ch);//把转换结果返回
}

uchar get_AD_Res_CH11() // 读取CH1端口的AD值
{
    	 unsigned char i,ch;

ADC_CS1=0; //片选,DO为高阻态
ADC_DO1=0;
Delay(2);

ADC_CLK1=0;
Delay(2);
ADC_DI1=1;
ADC_CLK1=1;//第一个脉冲,起始位
Delay(2);

ADC_CLK1=0;
Delay(2);
ADC_DI1=1;
ADC_CLK1=1;//第二个脉冲,DI=1表示双通道单极性输入
Delay(2);

ADC_CLK1=0;
Delay(2);
ADC_DI1=1; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0时选择通0(CH1)
ADC_CLK1=1;
Delay(2);

ADC_DI1=0; //DI转为高阻态,失去输入意义;
ADC_DO1=1; //DO脱离高阻态为输出数据作准备

ADC_CLK1=1;
Delay(2);
ADC_CLK1=0; //第一个下降沿,为去数准备;
Delay(2); //这里加一个脉冲AD才能正确读出数据,不加的话读出的数据少一位,且是错的。

for (i=0; i<8; i++) //读取数据
    {
    ADC_CLK1=1;
    Delay(2);
    ADC_CLK1=0;
    Delay(2);
    ch=(ch<<1)|ADC_DO1;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数
   }
  
     ADC_CS1=1;//取消片选,一个转换周期结束
   return(ch);//把转换结果返回
}

void main()					  //主函数
{	
	int values[4];
  int max_value;
	int i;
	s1led = 0;
	s2led = 0;
	s3led = 0;
	s4led = 0;
	LCD_Init();         //显示屏初始化
	LCD_ShowString(1,1,"1:");//显示
	LCD_ShowString(1,7,"2:");
	LCD_ShowString(2,1,"3:");
	LCD_ShowString(2,7,"4:");
	while(1)
	{
	    u=get_AD_Res();
		  u=u/255*100;
			u1=get_AD_Res_CH1();
		  u1=u1/255*100;
			u2=get_AD_Res1();
		  u2=u2/255*100;
			u3=get_AD_Res_CH11();
		  u3=u3/255*100;
				
		  values[0]=u;
		  values[1]=u1;
			values[2]=u2;
			values[3]=u3;
		
		  max_value = values[0];
    for (i = 1; i < 4; i++)
		{
        if (values[i] > max_value)
					{
            max_value = values[i];
          }
				}
		LCD_ShowNum(1,14,max_value,3);
		
	
		  LCD_ShowNum(1,3,u,3);
	    LCD_ShowNum(1,9,u1,3); 
			LCD_ShowNum(2,3,u2,3);
	    LCD_ShowNum(2,9,u3,3); 
				
				
				 // 判断剩余值与最大值的差值是否大于30,控制LED
        for (i = 0; i < 4; i++) {
            if (abs(values[i] - max_value) > 30) {
                // 对应LED亮
                if (i == 0) {
                    s1led = 1;
                } else if (i == 1) {
                    s2led = 1;
                } else if (i == 2) {
                    s3led = 1;
                } else if (i == 3) {
                    s4led = 1;
                }
            } else {
                // 对应LED灭
                if (i == 0) {
                    s1led = 0;
                } else if (i == 1) {
                    s2led = 0;
                } else if (i == 2) {
                    s3led = 0;
                } else if (i == 3) {
                    s4led = 0;
                }
            }
        }
		
		  
	}
	
	
}



四、资源下载

全部资料(源程序、仿真文件、安装包、演示视频):
链接: https://pan.baidu.com/s/1mPGnG9dU8bJ2l5sTD7apnw?pwd=zejf 提取码: zejf 
--来自百度网盘超级会员v4的分享


http://www.kler.cn/a/427663.html

相关文章:

  • PMP–一、二、三模、冲刺–分类–10.沟通管理
  • 基于微信小程序的教学质量评价系统
  • mysql 1主2从搭建
  • v-on:click后面可以加什么
  • 并查集—河工oj
  • 利用PHP和GD库实现图片切割
  • 项目五 李白个人生平
  • 可供参考的GitHub国内镜像
  • DApp浏览器能否集成在自己开发的DApp里?
  • 安全审计系统
  • Mac如何安装SVN
  • 扫描IP段内的使用的IP
  • 经典的CNN架构
  • 在玩“吃鸡”的时候游戏崩溃要如何解决?游戏运行时崩溃是什么原因?
  • k8s-Informer之Reflector的解析
  • 在Node.js局域网调试https的Vue项目
  • el-select的搜索功能
  • BOM模型
  • pytest中使用conftest做测试前置和参数化
  • 项目搭建:guice,jdbc,maven