找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2661|回复: 4
打印 上一主题 下一主题
收起左侧

用51单片机制作万用表,不能用,请大家帮忙看看

[复制链接]
跳转到指定楼层
楼主
下面的是程序,和仿真,是之前一位坛友分享的,我画了一个PCB,PCB的原理图如下:


#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/***************引脚声明*********************/
#define lcd P0
sbit rs=P2^7;     //LCD液晶控制端
sbit en=P2^6;
sbit SPK=P1^7;  //蜂鸣器引脚
sbit CS=P1^2;   //CS位定义为P1.2引脚
sbit CLK=P1^0;  //CLK位定义为P1.0引脚
sbit DIO=P1^1;  //DIO位定义为P1.1引脚
sbit key=P2^5;  //定义按键引脚
sbit a=P2^0;             //模拟量通道选择端
sbit b=P2^1;             //模拟量通道选择端
sbit c=P2^2;             //模拟量通道选择端

/***********LCD显示数组**************************/
uchar code table0[]="  DCV(0-5V)  ";
uchar table1[]="  V=0000.00 v";
uchar code table2[]="  DCI(0-100mA)";
uchar table3[]="  I=0000.00mA";
uchar code table4[]="  R(0-1k)    ";
uchar table5[]="  R=000.0   ";

/***************全局变量************************/
uchar flag=0;      //换挡标志位


void delay(uint count)              //延时
{
uint i,j;
for(i=0;i<count;i++)
  for(j=0;j<120;j++);
}

/*************LCD1602驱动程序************************/
void w_cmd(uchar com)                    //lcd1602写命令
{
rs=0;
lcd=com;
en=1;
delay(5);
en=0;
}

void w_data(uchar dat)           //lcd1602读数据
{
rs=1;
lcd=dat;
en=1;
delay(5);
en=0;
}

void w_str(uchar *s)       //lcd1602写字符串
{
   while(*s)  w_data(*s++);
}

void init()              //lcd1602初始化
{
en=0;
w_cmd(0x38);
w_cmd(0x0c);
w_cmd(0x06);
w_cmd(0x01);
}

/*****************************************************
函数功能:将模拟信号转换成数字信号
***************************************************/
unsigned char  A_D()
{
unsigned char i,dat;
  CS=1;   //一个转换周期开始
  CLK=0;  //为第一个脉冲作准备
  CS=0;  //CS0,片选有效
  DIO=1;    //DIO1,规定的起始信号  
  CLK=1;   //第一个脉冲
  CLK=0;   //第一个脉冲的下降沿,此前DIO必须是高电平
  DIO=1;   //DIO1 通道选择信号  
  CLK=1;   //第二个脉冲,第23个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
  CLK=0;   //第二个脉冲下降沿

  DIO=0;   //DI0,选择通道0
  CLK=1;    //第三个脉冲
  CLK=0;    //第三个脉冲下降沿
  DIO=1;    //第三个脉冲下沉之后,输入端DIO失去作用,应置1
  CLK=1;    //第四个脉冲
  for(i=0;i<8;i++)  //高位在前
    {
     CLK=1;         //第四个脉冲
     CLK=0;
     dat<<=1;       //将下面储存的低位数据向右移
  dat|=(unsigned char)DIO;   //将输出数据DIO通过或运算储存在dat最低位
   }            
   CS=1;          //片选无效
return dat;  //将读书的数据返回     
}
/**********************报警程序************************/
void BaoJing(void)
{  
         uinti, j;
         for(i = 0; i < 200; i++)    //产生脉冲使蜂鸣器发出声音
         {
        SPK = 0; for (j = 0; j < 100; j++);
        SPK = 1; for (j = 0; j < 100; j++);
  }   
}
/*********************按键判定************************************/
void keyscan()
{
         if(key==0)                    //判断是否按下
         {
                  delay(10);
                  if(key==0)
                  {
                          while(!key);
                          flag++;
                          if(flag>3)flag=0;

                  }
         }
}
/*******************定时器1初始化程序******************/
void Timer1_Init(void) //
{
         TMOD=0x11;  
         TH1= ( 65535 - 50000 ) / 256;   //0.2ms
         TL1= ( 65535 - 50000 ) % 256;
         ET1=1;              
         TR1=1;      
         EA=1;
}
/*******************定时器1中断程序********************/
void Timer1 ( void ) interrupt 3  //定时器1中断函数 0.2ms
{
         TH1= ( 65535 - 50000) / 256;  
         TL1= ( 65535 - 50000 ) % 256;
         keyscan();   //按键判定
}

/*主函数*/                                                                  
void main()
{
uint adval;
unsigned long int temp;
init();     //液晶初始化      
Timer1_Init();  //定时器1初始化  
while(1)
  {

          if(flag==0)              //直流电压测量
          {     
                          c=0;b=0;a=0;    //通道选择
                          w_cmd(0x80);
                          w_str(table0);
                          adval=A_D();    //进行A/D转换
                          temp=adval*5.0/255* 2*100;  //转换成实际电压并放大100
                          if(temp>500)
                          {
                                   BaoJing();   //超量程报警
                                   w_cmd(0xc0+0x00);      
                                   w_str("  V= .OL v  ");
                                   delay(500);
                          }
                          else
                          {
                                   table1[4]=temp/100000+0x30;
                                   table1[5]=temp%100000/10000+0x30;
                                   table1[6]=temp%10000/1000+0x30;
                                   table1[7]=temp%1000/100+0x30;
                                   table1[9]=temp%100/10+0x30;
                                   table1[10]=temp%10+0x30;                  
                                   w_cmd(0xc0+0x00);      
                                   w_str(table1);         
                                   delay(10);
                          }
          }

          if(flag==1)        //         直流电流测量
          {
                          c=0;b=0;a=1;    //通道选择
                          w_cmd(0x80);
                          w_str(table2);         
                          adval=A_D();    //进行A/D转换
                          temp=adval*0.1/255*5000000/10;
                          if(temp>10000)
                          {
                                   BaoJing();   //超量程报警
                                   w_cmd(0xc0+0x00);      
                                   w_str("  I= .OL mA ");
                                   delay(500);
                          }
                          else
                          {
                                   table3[4]=temp/100000+0x30;
                                   table3[5]=temp%100000/10000+0x30;
                                   table3[6]=temp%10000/1000+0x30;
                                   table3[7]=temp%1000/100+0x30;
                                   table3[9]=temp%100/10+0x30;
                                   table3[10]=temp%10+0x30;  
                                   w_cmd(0xc0+0);     
                                   w_str(table3);

                                   delay(10);
                          }
    }
           if(flag==2)      //         电阻测量
           {   
                          c=0;b=1;a=0;    //通道选择
                          adval=A_D();    //进行A/D转换
                          temp=adval*1.0/(255-adval)*1000;
                          if(temp>50000)
                          {
                                   BaoJing();   //超量程报警
                                   w_cmd(0xc0+0x00);      
                                   w_str("  R= .OL k  ");
                                   delay(500);
                          }
                          else
                          {
                                   w_cmd(0x80);
                                   w_str(table4);

                                   table5[4]=temp/1000+0x30;
                                   table5[5]=temp%1000/100+0x30;                 
                                   table5[6]=temp%100/10+0x30;            
                                   table5[8]=temp%10+0x30;   
                                   w_cmd(0xc0+0);     
                                   w_str(table5);
                                   delay(10);
                          }                                          
           }     
  }
}  



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:584814 发表于 2020-5-20 10:58 | 只看该作者
如果改了人家的图纸,是有可能也要改动程序的相关部分才可以正常工作的。
回复

使用道具 举报

板凳
ID:747209 发表于 2020-5-21 10:44 | 只看该作者
man1234567 发表于 2020-5-20 10:58
如果改了人家的图纸,是有可能也要改动程序的相关部分才可以正常工作的。

没有改,只是从仿真图画了原理图,生成了PCB
回复

使用道具 举报

地板
ID:187802 发表于 2020-5-21 12:20 | 只看该作者
AD的时序要弄正确
回复

使用道具 举报

5#
ID:755472 发表于 2020-5-21 12:24 | 只看该作者
感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表