基于STC89C52电位器式传感器位移测量仪的设计
本文的位移测量仪的设计要求为:采集和处理测量电路的信号,显示测量位移,测量范围是0-50mm精度为0.1mm。设计能和计算机进行通信的标准接口,并将测量数据发送到计算机。
位移传感器模块使用米朗科技KPM12型直线位移传感器,它是一种非线绕电位器式传感器,它也是一种线性电位器式传感器,其原理相当简单,类似于滑动变阻器。 将计算机的波特率与单片机串口通信的波特率设置相同均为9600,完成了通信的相关初始化后,通过指令让系统通过通信模块完成数据的传输,最后再计算机串口调试助手可以看到测量结果。 关键词: 位移传感器;51单片机;A/D转换
单片机源程序如下:
- /*=============================================================*/
- #include<reg52.h> //器件配置文件
- #include <intrins.h>
- #include "lcd.h"
- #define u8 unsigned char
- #define u16 unsigned int
- #define uchar unsigned char
- #define uint unsigned int
-
- unsigned char voltage[] = {'0','0','0','.','0',0};
- unsigned int circuit,aa,bb,cc,dd,ac,setv1,setv2;
- float u,k;
- unsigned int j,ppm,cp;
- uint dat=0,shidu;
-
- void ConfigUART(unsigned int baud); //串行口配置函数
- void ConfigTimer0(); //定时器0配置函数
- void SendData(unsigned char ch); //字符发送函数
- void SendString(char *s); //字符串发送函数
- void AlarmJudge(void); //警报
- void delayms(unsigned int ms);
- void UartSend(); //串口数据发送函数
- //AD管脚
- sbit ADCS =P3^5;
- sbit ADCLK =P3^2;
- sbit ADDI =P3^3;
- sbit ADDO =P3^4;
- sbit Buzzer_P = P2^1; // 蜂鸣器的管脚
- sbit KEY = P1^3; // “设置”按键的管脚
- sbit KeyDown_P = P1^4; // 按键的管脚
- uint set_value = 30;
- uint set_value_count = 0; //警报设置菜单
- uint key_count=1;
-
- /***********************************
- 函数名: Adc0832
- 功能: 启动AD转换将值储存于 dat
-
- ***********************************/
- unsigned int Adc0832(unsigned char channel)
- {
- uchar i=0;
- uchar j;
- uchar ndat=0;
- // uchar Vot=0;
- if(channel==0)channel=2; // 10
- if(channel==1)channel=3; // 11
-
- ADDI=1;
- _nop_();
- _nop_();
- ADCS=0; //拉低CS端 开始
- _nop_();
- _nop_();
- ADCLK=1; //拉高CLK端
- _nop_();
- _nop_();
- ADCLK=0; //拉低CLK端,形成下降沿1 第一个脉冲的下降沿,此前DIO必须是高电平
- _nop_();
- _nop_();
- ADCLK=1; //拉高CLK端
-
- ADDI=channel&0x1; //
-
- _nop_();
- _nop_();
-
- ADCLK=0; //拉低CLK端,形成下降沿2
-
- _nop_();
- _nop_();
-
- ADCLK=1;//拉高CLK端
-
- ADDI=(channel>>1)&0x1;
-
- _nop_();
- _nop_();
-
- ADCLK=0;//拉低CLK端,形成下降沿3
-
- ADDI=1;//控制命令结束 输入端DI失去作用,应置1
-
- _nop_();
- _nop_();
-
-
- dat=0;
-
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收数据 (或)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- dat<<=1; //左移一位
- if(i==7)dat|=ADDO; //将输出数据DO通过或运算储存在dat最低位
- }
-
-
- for(i=0;i<8;i++) //验证
- {
- j=0;
- j=j|ADDO; //收数据
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- j=j<<7; //从 ADD0开始
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
-
-
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高数据端,回到初始状态
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad data
- }
- void Conut(void)
- {
- circuit=shidu/256; // 数字量
-
- u=(float)circuit;
- k=(float)circuit;
- u=u*0.5977;
- u=u*10; //提取一位小数
- k=k*0.5977;
-
- cp=(int)k; // 警报值
-
- ppm=(int)u;
- aa=ppm/1000;
- bb=ppm%1000/100;
- cc=ppm%100/10;
- dd=ppm%10;
-
- setv1 = set_value/10;
- setv2 = set_value%10;
-
-
- voltage[0] = (char)('0'+ aa);
- voltage[1] = (char)('0'+ bb);
- voltage[2] = (char)('0'+ cc);
- voltage[4] = (char)('0'+ dd);
-
- }
- /***********************************
- 函数名: delayms()
- 功能: 延时 ms 毫秒
- ***********************************/
- void DelayMs(uint time)
- {
- uint i,j;
- for(i=0;i<time;i++)
- for(j=0;j<112;j++);
- }
- /***********************************
- 函数名: LcdDisplay()
- ***********************************/
- void LcdDisplay(void)
- { LCD1602_write_com(0x80+3);
- LCD1602_write_word("KPM12-150mm");
-
- LCD1602_write_com(0x80+0+0x40);
- LCD1602_write_word(" ");
-
- LCD1602_write_com(0x80+2+0x40);
- LCD1602_write_word("X=");
- LCD1602_write_com(0x80+4+0x40);
- LCD1602_write_data(0x30+aa);
- LCD1602_write_com(0x80+5+0x40);
- LCD1602_write_data(0x30+bb);
- LCD1602_write_com(0x80+6+0x40);
- LCD1602_write_data(0x30+cc);
- LCD1602_write_com(0x80+7+0x40);
- LCD1602_write_word(".");
-
- LCD1602_write_com(0x80+8+0x40);
- LCD1602_write_data(0x30+dd);
- LCD1602_write_com(0x80+9+0x40);
- LCD1602_write_word("mm");
-
- LCD1602_write_com(0x80+12+0x40);
- LCD1602_write_word("!=");
- LCD1602_write_com(0x80+14+0x40);
- LCD1602_write_data(0x30+setv1);
- LCD1602_write_com(0x80+15+0x40);
- LCD1602_write_data(0x30+setv2);
-
-
- }
- void LcdDisplay2(void)
- {
- LCD1602_write_com(0x80+3+0x40);
- LCD1602_write_word("cccc");
-
- LCD1602_write_com(0x80+3);
- LCD1602_write_word("aaa");
-
-
- }
- /***********************************
- 函数名:AlarmJudge
- 警报
- ***********************************/
- void AlarmJudge(void)
- {
- if(cp > set_value)
- {
-
- Buzzer_P=0;
- delayms(50);
- Buzzer_P=1;
- delayms(50);
-
-
- }
- else
- {
- Buzzer_P=1;
-
- }
- }
- /* UART字符发送函数 */
- void SendData(unsigned char ch)
- {
- SBUF = ch; //启动发送
- while(!TI); //等待结束
- TI = 0;
- }
- /* UART字符串发送函数 */
- void SendString(unsigned char *s)
- {
- while(*s) //循环发送
- {
- SendData(*s++);
- }
- }
- void UartSend()
- {
- SendString("x=");
- SendString(voltage);
- SendString("mm \r\n");
- }
- /* 串口配置函数,baud-通信波特率 */
- 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
- EA = 1; //打开总中断
- }
- /* UART中断服务函数 */
- void InterruptUART() interrupt 4
- {
- if(RI) //接收到字节
- {
- RI = 0; //清零接收中断标志位
- }
- if(TI) //字节发送完毕
- {
- TI = 0; //清零发送中断标志位
- }
- }
- /***********************************
- 主函数
- ***********************************/
- void main()
- {
- Init_LCD1602();
-
- ConfigUART(9600); //配置串行口工作模式及参数
-
-
-
- while(1)
- {
-
-
- shidu=Adc0832(0); //获取AD值
- Conut(); //计算
-
-
- if(KEY==0) //按键
- {
-
- DelayMs(30);
- if(KEY==0) //去抖
- while(!KEY);
- {
- LCD1602_write_com(0x01); //清屏指令
- key_count++; //菜单计数
- }
-
- if(key_count==3)
- key_count=1;
- LCD1602_write_com(0x01); //清屏指令
-
- }
- if(key_count==1) //界面1
- {
-
- LcdDisplay();
-
-
-
- if(KeyDown_P==0) //判断按键2
- {
-
- DelayMs(30);
- if(KeyDown_P==0)
- while(!KeyDown_P);
- {
- set_value_count++;
- set_value = set_value+10; //按一次+10mm
-
-
- }
-
- if(set_value_count==7)
- {
- set_value = 30;
- set_value_count=0;
-
- }
-
-
- }
-
- }
-
-
- if(key_count==2) //界面2
- {
-
- LcdDisplay2();
-
- }
-
-
- UartSend(); //串口发送
-
- for(j=0;j<30000;j++); //延时读取
-
-
-
-
- AlarmJudge();
- }
- }
复制代码
Keil代码与Proteus仿真51hei附件下载:
位移传感器.zip
(85.9 KB, 下载次数: 20)
|