2266|5

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求助大神分析 [复制链接]

采用51单片机和555定时器设计电容参数测量,根据P3.7脚的定时器测量TW 的宽度, 标准计数脉冲的周期为1 微秒,Tw=1.1*R*C,又uln2003A和三个继电器以及四个量程选择按键来选出不同的档位,但在仿真的时候不管选择哪个档位,都能测出某一个电容,有时候还测的是错误的,分析了好久也没头绪,所以来这里求助了。麻烦给位帮忙分析分析。谢谢了


092755eu8vyzh2muecmvxe.jpg.thumb.jpg (97.41 KB, 下载次数: 3)

092755eu8vyzh2muecmvxe.jpg.thumb.jpg
此帖出自51单片机论坛

最新回复

图那么小,根本无法看清,而且测试原理也不说,图中似乎还用电阻串在555的电源回路里并用继电器去切换,如果确实是这样,电路根本就是错的。  详情 回复 发表于 2017-4-18 21:08
点赞 关注
 

回复
举报

3

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
附上程序
主函数
#include
#include "1602.h"
#include "delay.h"

sbit vo = P3^2;             // 用于检测P3.2口的值,计算时间。  计时器0的开与断
sbit tr = P3^7;                                                                 // 产生一个低电平脉冲
                                                                                 // 超量程提示灯
sbit ledclc = P2^7;

sbit con1 = P0^0;                            // 用于控制继电器,实现档位选择
sbit con2 = P0^1;                                                               
sbit con3 = P0^2;                                                               

sbit key1 = P0^3;                                                          // 独立按键部分,用于用户选择量程
sbit key2 = P0^4;
sbit key3 = P0^5;
sbit key4 = P0^6;

sbit led1 = P2^3;                                                          // 量程提示灯
sbit led2 = P2^4;
sbit led3 = P2^5;
sbit led4 = P2^6;


unsigned int tw;                                // 用于获取定时器的数值

float ftemp;                                                                         // 用于计算电容值的中间变量

unsigned long int c;                                                                // 存放电容值

unsigned char need;                                                         // 需要测量时置1,一次测量结束置0
unsigned char R;                            // 表示不同的档位
unsigned char flag;                                  // 数据处理结束置1
unsigned char temp[8];                        // 存放电容值的各个位         
unsigned char zimu1[] = " range is higher";                   //量程太高
unsigned char zimu2[] = "The value of Cap";
unsigned char zimu3[] = "please press key";
unsigned char zimu4[] = "     to measure ";
unsigned char zimu5[] = " range is lower ";        
void process(unsigned long int c);                         // 数据处理函数
void keyscan();                                                                 // 键盘扫描函数
void ledlight(unsigned char R);                                         //        量程指示灯函数
void init_timer0()                                     // 定时器0  初始化   
{
        TMOD = 0x09;                   // gate置1,方式1,16位计时,定时器由P3.2控制开断
        TH0 = 0x00;
        TL0 = 0x00;
        EA   = 1;
        ET0 = 1;                                            
        TR0 = 1;
}
void init_INT1 ()                                                                    // 定时器0  初始化
{
        EA = 1;
        IT1 = 1;                                      // 下降沿触发
        EX1 = 1;
}                  
void main()
{
        ledclc = 1;                                                                    // 超量程提示灯熄灭
        need = 0;                                                // 一开始无需测量
    con1 = con2 = con3 = 0;
        flag = 0;
          init_timer0();                                                                    // 初始化
        init_INT1();
        LCD_init();
        dispchar1(zimu3);
        dispchar2(zimu4);
        while(1)
        {
                  if(need == 1)
                {                                                                                        // 当需要测量时
                        if(vo == 0 ) //vo == 0时检测计数器的值可能还没开始计数,可能计数结束
                        {
                                 if(TH0 != 0x00 || TL0 != 0x00) // 是计数结束 若有读数,用tw 存下
                                 {
                                          tw = TH0 << 8;
                                         tw = tw | TL0;        
                                         TH0 = 0x00;                               // 一次结束,计时器清零
                                         TL0 = 0x00;
           need = 0;    // 需要再次测量时,need置1.避免tw的值被更//改   即不需要测量时,一直保持
                                         EX1 = 1;                                                 // 开外部中断1
                                 }
                                 else          // 反之,证明没有计数,无电容,默认值tw置0
                                 {
                                         tw = 0;
                                 }
                        }

                        ftemp = tw / 1.1  ; // 计算电容值   根据公式 tw = 1.1 * R * C

                        c = (unsigned long int)(ftemp )*100;    //扩大了一百倍   便于后续程序
//取两位小数点
                        process(c);                 // 调用数据处理函数,根据不同的R值进行处理                                                                                                                                                        
                }                                                         
                if(flag == 1 ) // 数据处理结束   每次处理结束,证明需要更新显示的数据
                {
                        if(tw>=50000 || ledclc == 0)                        // 量程超出
                        {
                                dispchar3(zimu1);
                                delay_us(100);               // 量程太高
                                ledclc = 0;
                        }                                                
                        else if(tw<=100 && ledclc == 1)                   //量程太低
                        {
                                dispchar3(zimu5);
                                delay_us(100);
                                ledclc = 0;
                        }
                        else   
                      {
                                dispchar1(zimu2);
                                delay_us(10);
                                disp(temp);
                        }                                                         
                        flag = 0;
                }               
                keyscan();
        }   
}

void timer0()  interrupt 1                      // 定时器0中断  用于超量程提示
{        TMOD = 0x09;                   // gate置1,方式1,16位计时,定时器由P3.2控制开断
        TH0 = 0x00;
        TL0 = 0x00;
        ledclc = 0;
}

void exint1        () interrupt 2          // 外部中断0  用于产生低脉冲,启动555定时器
{
        unsigned char a;
        tr = 1;                                                            // tr端一个负脉冲
        a = 20;
        while(--a);
        tr = 0;
        a = 20;
        while(--a);
        tr = 1;                               // tr端负脉冲结束           大约40us的负脉冲
        need = 1;                                                                                // 表示需要测量
        ledclc = 1;                                                                            // 关闭先前的超量程提示
        EX1 = 0;                 // 暂时关闭外部中断,一次测量结束,再开放外部中断
}

void process(unsigned long int c)
{
                if(R == 1)          // 10M         的电阻                   量程10pf ~ 5000pf
                {
                        c = c /10;                  
                        lcd_pos(0x4a);
                           LCD_write_Data(' ');
                        LCD_write_Data('p');
                        LCD_write_Data('f');
                        LCD_write_Data(' ');
                        LCD_write_Data(' ');
                }
                if(R == 2)                  // 100k 的电阻               量程5nf~ 500nf
                {
                        c = c /100;                  
                        lcd_pos(0x4a);
                           LCD_write_Data(' ');
                        LCD_write_Data('n');
                        LCD_write_Data('f');
                        LCD_write_Data(' ');
                        LCD_write_Data(' ');                        
                }
                if(R == 3)                      //1k欧姆 的电阻                   量程0.5uf ~ 50uf
                {
                        c = c /1000;                 // 扩大了一百倍 单位  c = tw/500   uf
                        lcd_pos(0x4a);
                           LCD_write_Data(' ');
                        LCD_write_Data('u');
                        LCD_write_Data('f');
                        LCD_write_Data(' ');
                        LCD_write_Data(' ');                     
                }
                if(R == 4)                 //100欧姆 的电阻                   量程50uf ~ 500uf
                {
                        c = c /100;                  // 扩大了一百倍 单位  c = tw/500   uf
                        lcd_pos(0x4a);
                           LCD_write_Data(' ');
                        LCD_write_Data('u');
                        LCD_write_Data('f');
                        LCD_write_Data(' ');
                        LCD_write_Data(' ');                                                        
                }
                temp[0] = c / 100000;                                // 千位
                temp[1] = c / 10000 % 10;                        // 百位                                       
                temp[2] = c / 1000 % 10;                           // 十位
                temp[3] = c / 100 %10;                            // 个位        
                temp[4] = c / 10 % 10;            
                temp[5] = c  % 10;
                flag = 1;
}
void keyscan()
{
        if(key1 == 0)
        {
                delay_ms(10);
                if(key1 == 0)                                        //  b3按下
                {
                        while(key1==0);
                        R = 1;        // 10M 的电阻               量程10pf~ 5000pf(5nf)
                        con1 = 1;
                        con3 = 1;
                        con2 = 0;
                        ledclc = 1;
                        dispchar3(zimu2);
                        disp(temp);dispchar1(temp) ;

                        /*dispchar2(zimu4);*/
                }
        }
        if(key2 == 0)                                                                           //  b4按下
        {
                delay_ms(10);
                if(key2 == 0)
                {
                        while(key2==0);
                        R = 2;             // 100k 的电阻               量程5nf~ 500nf
                        con1 = 0;
                        con3 = 1;
                        con2 = 0;
                        ledclc = 1;
                        dispchar3(zimu2);
                        disp(temp);
                }
        }

        if(key3 == 0)                                                                             //  b5按下
        {
                delay_ms(10);
                if(key3 == 0)
                {
                        while(key3==0);
                        R = 3;
                        con1 = 0;       // 1k欧姆 的电阻                   量程0.5uf ~ 50uf
                        con2 = 0;
                        con3 = 0;
                        ledclc = 1;
                        dispchar3(zimu2);
                        disp(temp);
                }
        }
        if(key4 == 0)                                                                             //  b6按下
        {
                delay_ms(10);
                if(key4 == 0)
                {
                        while(key4==0);
                        R = 4;
                        con1 = 0;       // 100欧姆 的电阻           量程50uf ~ 500uf
                        con2 = 1;
                        con3 = 0;
                        ledclc = 1;
                        dispchar3(zimu2);
                        disp(temp);
                }
        }
        ledlight(R);
}        
void ledlight(unsigned char R)
{
        if(R == 1)
        {
                led1 = 1;
                led2 = 1;
                led3 = 1;
                led4 = 0;
        }
        if(R == 2)
        {
                led1 = 1;
                led2 = 1;
                led3 = 0;
                led4 = 1;
        }
        if(R == 3)
        {
                led1 = 1;
                led2 = 0;
                led3 = 1;
                led4 = 1;
        }
        if(R == 4)
        {
                led1 = 0;
                led2 = 1;
                led3 = 1;
                led4 = 1;
        }
}

这是1602.c

#include "1602.h"
#include "delay.h"

void LCD_write_com(unsigned char com)
{  
         RS_CLR;
         RW_CLR;
         EN_SET;
         com = pro_data(com);
         P1 = com;
         delay_us(300);
         EN_CLR;
}

void LCD_write_Data(unsigned char Data)
{
         RS_SET;
         RW_CLR;
         EN_SET;
         Data = pro_data(Data);  
         P1 = Data;
         delay_us(300);
         EN_CLR;
}

void LCD_init(void)
{
  /* LCD_write_com(0x38);                             // 显示模式设置
   delay_ms(5);
   LCD_write_com(0x38);
   delay_ms(5);
   LCD_write_com(0x38);
   delay_ms(5); */
   LCD_write_com(0x38);  
   LCD_write_com(0x08);                             // 显示关闭
   LCD_write_com(0x01);                             // 显示清屏
   LCD_write_com(0x06);                             // 显示光标移动设置
   delay_ms(5);
   LCD_write_com(0x0c);                             // 显示开及光标设置
}
void lcd_pos(unsigned char pos)
{
        LCD_write_com(0x80|pos);
}
void disp(unsigned char *p)                                        // 第二行显示数据
{
        unsigned char i;
        lcd_pos(0x43);
        for(i=0;i<6;i++)
    {
                if(i==4)
                {
                        LCD_write_Data(0x2e);        
                }
                LCD_write_Data('0'+(*p));
                p++;
        }
}
void dispchar1(unsigned char *p)                // 第一行显示需要显示的提示字符串
{
        lcd_pos(0x00);
        while(*p != '\0')
        {
                LCD_write_Data(*p);
                p++;
        }
        lcd_pos(0x4c);
        LCD_write_Data('f');         
}

void dispchar2(unsigned char *p)                 // 第二行显示需要显示的提示字符串
{
        lcd_pos(0x40);
        while(*p != '\0')
        {
                LCD_write_Data(*p);
                p++;
        }         
}
void dispchar3(unsigned char *p)                 // 第一行显示  第二行清空
{
        unsigned char i;
        lcd_pos(0x00);
        while(*p != '\0')
        {
                LCD_write_Data(*p);
                p++;
        }
        lcd_pos(0x40);
        for(i=0;i<16;i++)
        {
                LCD_write_Data(' ');
        }         
}
unsigned char pro_data(unsigned char mda)           //数据处理函数,将高位和低位互换
{
        unsigned char enddat;
        unsigned char i;
        enddat = 0;
        for(i=0;i<8;i++)
        {
                enddat = enddat << 1;
                if(mda & 0x01 == 1)
                {
                        enddat = enddat | 0x01;
                }
                else
                {
                        enddat = enddat | 0x00;
                }               
                mda = mda >> 1;
        }
        return enddat;
}


#ifndef __1602_h__
#define __1602_h__

#include

sbit RS = P2^2;   //定义端口
sbit RW = P2^1;
sbit EN = P2^0;

#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1

unsigned char pro_data(unsigned char mda);
void LCD_write_com(unsigned char com);
void LCD_write_Data(unsigned char Data);
void LCD_init(void);
void lcd_pos(unsigned char pos);
void disp(unsigned char *p);
void dispchar1(unsigned char *p);
void dispchar2(unsigned char *p);
void dispchar3(unsigned char *p);

#endif




#include "delay.h"
void delay_us(uint cnt)
{
        uchar i;
        for(;cnt>0;cnt--)
        {
                for(i=0;i<12;i++)
                {
                        ;
                }
        }
}
void delay_ms(uint cnt){
        uchar i;
        for(;cnt>0;cnt--)
        {
                for(i=0;i<125;i++)
                {
                        ;
                }
        }
}



#ifndef __delay_h__
#define __delay_h__

#define uchar unsigned char
#define uint  unsigned int
void delay_us(uint cnt);
void delay_ms(uint cnt);
#endif
此帖出自51单片机论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
求帮助
此帖出自51单片机论坛
 
 
 

回复

4008

帖子

0

TA的资源

版主

4
 
太长了,把你硬件软件都搞清楚需要很多时间。
此帖出自51单片机论坛
 
 
 

回复

2721

帖子

0

TA的资源

纯净的硅(中级)

5
 
我也不会
此帖出自51单片机论坛
 
 
 

回复

1万

帖子

139

TA的资源

版主

6
 
图那么小,根本无法看清,而且测试原理也不说,图中似乎还用电阻串在555的电源回路里并用继电器去切换,如果确实是这样,电路根本就是错的。
此帖出自51单片机论坛
 
个人签名上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表