本帖最后由 qq543538634 于 2016-8-26 16:57 编辑
我的设计目的是做一个水位测量,把测量数据通过数码管显示,再通过USB发送到PC端。
我的思路是用水来作为导体,当水漫到哪个位置时那个位置就导通。
但在实际测试中发现,水的电阻是50K-100K左右,电阻过大,无论怎样检测位通过水都无法得到低电平,(就是无法导通拉低电平),在proteus中仿真也是得到同样的结果,电阻达到50K,就无法拉低电平。
我看网上的设计思路跟我的也差不多,为什么他们的能检测到电平变化呢。。
下面附上程序,有兴趣的朋友可以互相讨论。。
#include<reg51.h> //头文件
#include<intrins.h>
sbit CLK=P1^1; //时钟控制位
sbit QH=P1^0; //数据输入端(输入给C51)
sbit SH=P1^2; //控制74LS165的读数、移位。高电平时表示移位,低电平时表示置位。SH=0时,从并行端口读入数据,并行口的8位数据将被置入其内部的8个触发器;SH=1时,并行输入被封锁,移位操作开始。
//sbit CLKIN=P^3; //类似CLK时钟控制位,当CLK和CLKIN有一个为低电平并且SH 为高电平时,另一个时钟可以输入。当CLK和CLKIN有一个为高电平时,另一个时钟被禁止。只有在CLK为高电平时CLKIN才可变为高电平。
#define uchar unsigned char //宏定义,为方便编程
#define uint unsigned int
#define INT8U unsigned char
#define INT16U unsigned int
/******************************
数码管显示0-9及其I/O定义
*******************************/
sbit SH_CP=P2^2; //上升沿时,移位存储器移位
sbit DS=P2^1; //串行数据输入端
sbit ST_CP=P2^0; //上升沿时,移位存储器的数据存入存储寄存器中,并数据直接输出
sbit qianwei=P2^3; //千位显示
sbit baiwei=P2^4; //百位显示
sbit shiwei=P2^5; //十位显示
sbit gewei=P2^6; //个位显示
code INT8U SEG_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管显示0-9
uchar a[2]=0;
unsigned long int read_int165()
{
unsigned long int i;
unsigned long int q=0;
unsigned long int sum=0;
unsigned long int total=0;
// CLKIN=1;
SH=0; //从并行口读入数据
_nop_(); //延时
SH=1; //从串行口输出数据
_nop_();
//CLKIN=0;
for(q;q<2;q++) //循环2次
{
for(i=1;i<=8;i++) //从输出口扫描8位数据
{
//向左移1位,右边补0
if(QH==0)
{
sum=i;
}
CLK=0;
_nop_();
CLK=1;
_nop_();
a[q]=sum;
}
}
total=a[0]+a[1];
return total;
}
void delay_ms(unsigned int time)
{
unsigned char j;
for( ; time>0; time-- )
for( j=0; j<200; j++ );
}
/************************************
* 74hc595出口数据输入
*入口参数:d 出口参数:无
*************************************/
void Serial_input_595(INT8U d)
{
INT8U i;
for(i=0;i<8;i++)
{
d<<=1;
DS=CY;
SH_CP=0;
_nop_();
_nop_();
SH_CP=1;
_nop_();
_nop_();
}
SH_CP=0;
}
/************************************
*出口数据输入74HC595存储寄存器
*入口参数:无 出口参数:无
*************************************/
void Parallel_output_595(void)
{
ST_CP=0;
_nop_();
_nop_();
ST_CP=1;
_nop_();
_nop_();
ST_CP=0;
}
/************************************
* 数码管显示函数 在只与单片机情况下,数码管的显示
*入口参数:a 出口参数:无 0
*************************************/
void Shumaguan_xiansh(INT8U t)
{
INT8U x;
unsigned long int c;
qianwei=0;
baiwei=0;
shiwei=0;
gewei=0;
c=0;
x=0;
while(1)
{
c=read_int165();
t=SEG_CODE[c%10];
Serial_input_595(t);
gewei=1;
Parallel_output_595();
delay_ms(5);//延迟函数
gewei=0;
_nop_();
t=SEG_CODE[c/10%10];
Serial_input_595(t);
shiwei=1;
Parallel_output_595();
delay_ms(5);//延迟函数
shiwei=0;
_nop_();
t=SEG_CODE[c/100%10];
Serial_input_595(t);
baiwei=1;
Parallel_output_595();
delay_ms(5);//延迟函数
baiwei=0;
_nop_();
t=SEG_CODE[c/1000%10];
Serial_input_595(t);
qianwei=1;
Parallel_output_595();
delay_ms(5);//延迟函数
qianwei=0;
_nop_();
}
}
void delayms(unsigned int ms)
{
unsigned int i;
while(ms--)
for(i=0;i<600;i++);
}
void ConfigUART(unsigned int baud)
{
SCON = 0x50; //配置串口为模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1为模式2
TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值
TL1 = TH1; //初值等于重载值
ET1 = 0; //禁止T1中断
ES = 1; //使能串口中断
TR1 = 1; //启动T1
}
/* UART中断服务函数 */
void InterruptUART() interrupt 4
{
if (RI) //接收到字节
{
RI = 0; //手动清零接收中断标志位
SBUF = read_int165(); //接收的数据+1后发回,左边是发送SBUF,右边是接收SBUF
}
if (TI) //字节发送完毕
{
TI = 0; //手动清零发送中断标志位
}
}
void main(void)
{
EA = 1; //使能总中断
ConfigUART(9600); //配置波特率为9600
while(1)
{
delayms(100); //150ms发送一次数据
Shumaguan_xiansh();
}
}
|