⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 measur_the_rate_of_fluid_flow.txt

📁 基于单片机的超声波流量计,1. 研究了时差法超声波流量计的测量原理
💻 TXT
字号:
#include<reg51.h>
#include<math.h>
#include<absacc.h>
#define uchar unsigned char   
#define uint unsigned int  
static const char c_keyCode[16]={0x00,0x01,0x02,0x03,
            0x04,0x05,0x06,0x07,
            0x08,0x09,0x0a,0x0b,
            0x0c,0x0d,0x0e,0x0f};
uint keyFlag;                  //定义按键标志位
void ScanKeys(void);           //扫描键盘模块
uchar KeyJudge(void);          //按键预处理
void KeyHandle(uchar keyIndex);  //按键处理模块
void Delay (unsigned int value);    //延时模块         
unsigned char temp; 
unsigned char key; 
unsigned char i,j; 
//主单片机主程序,无参数,无返回值
循环调用显示、键扫描
main()  
{  p0=0xff;
   p2=0xff;
Key();
   tx()
  while(1)
{  js();
  LED();
}
}
//从单片机主程序
cdpj()
{   tx();
p1_0=0;
p1_7=1;
p1_2=1; p1_2=0; p1_2=1; 
p1_2=1; p1_2=0; p1_2=1;
p1_2=1; p1_2=0; p1_2=1;
while(1)
{ p1_0=0;
p1_5=1&&p1_6=0;
csjs();
p1_0=0;
p1_5=0&&p1_6=1;


csjs();}}

//超声波接收数据处理子程序
csjs()  
{  data uint  ta,tb,tc;
  delay1ms(uint t)
int1=0;
P2_0=0&&P2_1=0;
tc=tb-ta;
return tc;
}
delay1ms(uint t)
{ 
for(i=0;i<t;i++)
for(j=0;j<120;j++)
}
//主单片机流速流量计算子程序
js()
{ data uint v;
  data uint q;
v=(C*C*tc)/(4*d*tane);
 q=pi*d*d*v/4;}

//主从单片机通信子程序
unsigned char Tx_Buffer[12];     //发送缓冲区
unsigned char Rx_Buffer[12];     //接收缓冲区
unsigned char Rx_Counter;       //接收数据指针
bit Send_Mode_Flg;            
//发送模式标志位,当该标志位为1时候允许发送,系统复位后该标志位被清零
void Init(void);                 //初始化子函数
void int0(void);                 //外部中断0服务子函数
void Send_Data(void);            //发送数据子函数
void Hand_Shake(void);           //握手信号产生子函数
void Send(unsigned char Tx_Data);  //发送一个字节子函数
void Receive(void);               //串行口接收中断服务子函数
tx()
{
     Init();                      //调用初始化函数进行系统初始化
	 for(;;)                      //主程序循环
	 {
	 ......                        
//在需要发送的时候将发送标志置位,允许发送
	 if(Send_mode_Flg==1)        //如果允许发送
	 {
	 Hand_Shake();               //调用握手函数通知另一块单片机不能进入发送状态
	 Send_Data();                 //发送缓冲区中的数据
	 Send_Mode_Flg=0;           //将发送模式标志位清除
	 }
	 ......
	 }
	 }                         
 //初始化子函数,包括对变量的初始化,对外位引脚信号的初始化以及对单片机相关工作寄存器的初始化
	void Init(void)
 {
//初始化变量和外部引脚
     Send_Mode_Flg=0;             //清除发送模式标志位
	   Rx_Counter=0;               //指针复零
	   P1_1=1;                     //外部引脚设置为高电平
//相关工作寄存器初始化
	   SCON=0x10;                  //串行口工作方式0        
	   EA=1;                        //开单片机中断
	   ES=1;                         //开串行中断
	   IT0=1;                        //设置为负脉冲触发方式
	   EX0=1;                       //开外部中断0
	   }
//字节发送子函数,调用其将传递入函数Tx_Data中的一个字节通过串行口发送出去
void Send(unsigned char Tx_Data)
{
  SBUF=Tx_Data;
  while(TI==0);                         //等待发送完成
  TI=0;                                //清除TI标志,准备下一次发送
  }
//数据发送子函数,将发送缓冲区内的12个字节数据连续发送
void Send_Data(void)
{
  unsigned char i;
  for(i=0;i<12;i++)
  {
    Send(Tx_Buffer[i]);
	}
	}
//串行口中断子函数,用于接收数据
	void Receive(void)interrupt 4 using 2
	{
	if(RI==1)                           //如果该中断由接收数据引起
	{
	RI=0;                              //清除标志位,准备下一次接收
	Send_Mode_Flg=0;                   //清除发送模式标志,不允许发送
 //以下是连续接收12个字节的数据且将其放入接收缓冲区内
   if(Rx_counter<=10)
   {
   Rx_Buffer[Rx_counter]=SBUF;
   if(Rx_counter=10)
   {
   Rx_counter=0;
   }
   else
   {
   Rx_counter++;
   }
     }
   }
   }
//外部中断0服务子函数,当接收到一个外部中断后不允许单片机进入发送状态,准备接收另外一块单片机发送的数据
  void Int0(void)interrupt 0 using 3
  {
  Send_Mode_Flg=0;
  }
//握手信号子函数,使用外部引脚P1.1产生一个负脉冲,通知另外一块单片机该单片机即将发送数据
  void Hand_Shake(void)
  {
  unsigned char i;
  P1_1=0;
  for(i=0;i<10;i++)                      //软件延时,得到一个脉冲宽度
  P1_1=1;
  }
//显示子程序
void LED(uint m)                        //函数定义 
 { 
  uchar data type[4];           //定义数组type[4]存放千、百、十、个位的字型码
  uchar data i;                
  uchar data j;               
  uchar code num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   
type[3]=num[(m/1000)];          //将千位数的字型码赋给type[3]
   m=m%1000;
type[2]=num[(m/100)];           //将百位数的字型码赋给type[2]
   m=m%100;
type[1]=num[(m/10)];            //将十位数的字型码赋给type[1]
   m=m%10;
type[0]=num[m];                //将个位数的字型码赋给type[0]
//======================数码显示=====================//
for(i=0;i<4;i++)       //将四个位上的字型码顺次输出
  {
  Bb=type[i];          //将字型码首先赋值给可按位寻址char型变量B 
   for(j=0;j<8;j++)    //将8个位从低到高顺次输出
    {
     p3_0=c;
     p3_1=0;     //由p3_1产生脉冲(上升沿)
     p3_1=1;
     Bb=Bb<<1;   //Bb右移一位
}
}
}
//====================看门狗子程序=====================// 
void tran() /*发送一字节数据子函数*/
{unsigned char i;
for(i=0; i<8; i++)
{ acc=com; /*将数据放入a中*/
si=c;
sck=0; /*sck产生一个上跳变*/
sck=1;
com=com<<1; /*左移一位*/
}return;}
main()
{com=0x06; /*发写读使能命令*/
cs=0;
tran();
cs=1;
com=0x01; /*发写状态字命令*/
cs=0;
tran();
com=0x00; /*定时1.4s*/
tran();
cs=1;
}
cs=0; /*产生cs脉冲*/
cs=1;}}
//====================键盘行列扫描子程序=====================// 
void Key(void)
{
uchar keyPtr;
while(1)
{
     keyPtr=KeyJudge();                        //键盘扫描判断
if(keyPtr!=0x55)                               //如果按某键则进行相应处理
{
KeyHandle(keyPtr);                             //按键处理模块
}
}
}
void ScanKeys(void)                             //扫描键盘模块
{
uchar scanValue=0xef;                           //定义扫描初值
uchar iScan,scanTempUchar;
for(iScan=0;iScan<4;iScan++)
{
   P2=scanValue;                               //发扫描值
   scanTempUchar=P2;                          //读入扫描值
   if((scanTempUchar&0x01)==0x00)              //第1列被按
{
      keyFlag|=(0x0001<<(iScan*4+0));            //置此键的标志位
}
else
{
  keyFlag&=~(0x0001<<(iScan*4+0));              //清此键的标志位
}
if((scanTempUchar&0x02)==0x00)                  //第2列被按
{
      keyFlag|=(0x0001<<(iScan*4+1));            //置此键的标志位
}
else
{
  keyFlag&=~(0x0001<<(iScan*4+1));               //清此键的标志位
}
if((scanTempUchar&0x04)==0x00)            //第3列被按
{
      keyFlag|=(0x0001<<(iScan*4+2));       //置此键的标志位
}
else
{
  keyFlag&=~(0x0001<<(iScan*4+2));         //清此键的标志位
}
if((scanTempUchar&0x08)==0x00)             //第4列被按
{
      keyFlag|=(0x0001<<(iScan*4+3));        //置此键的标志位
}
else
{
  keyFlag&=~(0x0001<<(iScan*4+3));          //清此键的标志位
}
scanValue=scanValue<<1|0x01;                 //置下一次扫描值
}
}
uchar KeyJudge(void)                         //按键预处理
{
uchar j,counterKeyPressedNum;
uchar keyRet=0x55;                   //初始按键返回码设定为无按码0x55
uint uintTemp;
ScanKeys();                         //扫描键盘
if(keyFlag!=0)
{
Delay(1000);                         //延时以消除抖动
ScanKeys();
P2=0x0f;
while((P2&0x0f)!=0x0f);                //没松开按键就等按键松开
counterKeyPressedNum=0;
for(j=0;j<16;j++)
{
   uintTemp=((uint)0x0001)<<j;
if((keyFlag&uintTemp)==uintTemp)    //依次检测键盘扫描标志KeyFlag
{                                //如某位置一则按键个数寄存器加一
   counterKeyPressedNum++;
keyRet=j;
}
}
if(counterKeyPressedNum>1)            //如果不止一个键被按则返回无按码0x55
{
return 0x55;                           //本处也可进行多按键处理
}
else                                //某键被按,返回此键的标识码
{
return(keyRet);
}
}
return(0x55);                    //如果无键被按则返回无按码0x55
}
void KeyHandle(uchar keyIndex)
{
switch(c_keyCode[keyIndex])
{
case 0x00.0x0f:
LED();
case 0x0a:
flag1==1;
case 0x0b:
flag2==1;
case 0x0c:
flagc==1;
case 0x0d:
flagd==1;
case 0x0e:
flage==1;
case 0x0f:
flagf==1;
}
if(flagf==1&& flag1==1&& flag2!=1)
{
 if(flagc==1&&flagd!=1)
       {d=d+1;}
     else if(flagc!=1&& flagd==1)
       {d=d-1;}
}
else if(flagf==1&& flag2==1 &&flag1!=1)
{
   if(flagc==1&& flagd!=1)
      {c=c+1;}
 else if(flagc!=1&& flagd==1)
      {c=c-1;}}
return d,c;}
void Delay(unsigned int value)       //延时模块
{
  while(value!=0)
{
value..;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -