#define uchar unsigned char #define uint  unsigned int #define ulong unsigned long
sbit RS=P2^0;          //LCD命令/数据端 sbit RW=P2^1;          //LCD读/写端 sbit LCDE=P2^2;         //LCD使能端
sbit MCP_CS=P2^3;       //MCP3001与ATS52的管脚接线定义 sbit MCP_DO=P2^4; sbit MCP_CLK=P2^5; uint  measure;
uchar flag;         //Busy标志 uchar code dis[]={\"Measure Start\ //显示 uchar code dis1[] = {\"Distance:\  //显示表头 uchar code dis2[] = {\"01234567.cm\ //显示代码 uchar code dis3[]={\"Out Measure!\ //显示
uchar dis_buf[6];       //显示缓冲区 void L_delay(void);       //短延时 void delay_ms(uint n);      //延时函数 uint read_MCP(void);      //读MCP3001
void init_1602(void);      //1602初始化函数  void busy(void);       //LCD忙标志判断函数 void dat_wrt(uchar dat);     //写数据子函数
void cmd_wrt(uchar cmd);     //写命令子函数      uint distance(void);      //距离计算函数 void lcd_start(uchar start);    //设定显示位置函数 void LCD_Clear(void);      //LCD清屏函数
uchar dat_adj(uint dat1);     //显示数据调整函数 void print(uchar *str);      //字符串显示函数  void disp(uint dat);      //显示子函数
uint average(void);       //算术平均滤波程序
/****************************主函数*******************************/ main() {
init_1602();
print(dis);        //显示测量开始  delay_ms(1000);   while(1)  {
measure=distance();
disp(measure);      //显示高度   delay_ms(100);  }
}
/**************************延时函数**************************/ void delay_ms(uint n) {
uint j;     while(n--)     {
for(j=0;j<125;j++);     } }
/***************************短延时****************************/ void L_delay(void) {
uchar i;
for(i=0;i<5;i++)_nop_(); }
/************************读MCP3001函数*************************/ uint read_MCP(void) {
uchar i;  uint temp=0;
MCP_CS=1;          L_delay();
MCP_CS=0;        //CS置低,开始采样数据  for(i=0;i<13;i++)      //读转换的10位数据  {
MCP_CLK=0;   L_delay();   MCP_CLK=1;   temp<<=1;
if(MCP_DO==1)temp|=0x01;  }
MCP_CS=1;
temp&=0x03ff;       //获取有效转换值  return(temp); }
/************************LCD忙标志判断函数*******************/ void busy(void) {
flag=0x80;        //赋初值 高位为1 禁止
while (flag&0x80)      //读写操作使能位禁止时等待 继续检测     {
P0=0xff;
RS=0;         //指向地址计数器
RW=1;         //读
LCDE=1;        //信号下降沿有效
flag=P0;       //读状态位 高位为状态         LCDE=0;     } }
/************************写数据子函数************************/ void dat_wrt(uchar dat) {
busy();         //检测 读写操作使能吗     LCDE=0;
RS=1;         //指向数据寄存器     RW=0;          //写     P0=dat;         //写数据     LCDE=1;         //高电平有效     LCDE=0; }
/*************************写命令子函数************************/ void cmd_wrt(uchar cmd) {
LCDE=0;
busy();         //检测 读写操作使能吗     P0=cmd;         //命令
RS=0;          //指向命令计数器     RW=0;          //写
LCDE=1;         //高电平有效     LCDE=0; }
/***********************距离计算函数***************************/ uint distance(void) {
uint temp1;
temp1=average();
if((temp1>160)&(temp1<960))    //在正常测量范围?  {
temp1=13569/(temp1+7)-4;   //转换测量数据  }    else  {
temp1=0x00ff;      //超出测量范围,返回错误标志  }
return(temp1); }
/************************算术平均滤波程序**********************/
uint average(void) {
uchar i;  uint av_dat;  ulong ave=0;
for(i=0;i<10;i++)      //连续读取10个数据值  {
ave+=read_MCP();     //读转换数据   L_delay();  }
av_dat=(uint)(ave/10);     //求平均值  return(av_dat); }
/*************************1602初始化函数************************/ void init_1602(void) {
cmd_wrt(0x01);       //清屏
cmd_wrt(0x0c);       //开显示,不显示光标,不闪烁
cmd_wrt(0x06);       //完成一个字符码传送后,光标左移,显示不发生移位
cmd_wrt(0x38);       //16×2显示,5×7点阵,8位数据接口 }
/************************设定显示位置函数************************/ void lcd_start(uchar start) {
cmd_wrt(start|0x80); }
/************************LCD清屏函数****************************/ void LCD_Clear(void) {
cmd_wrt(0x01);       //写入清屏指令  delay_ms(1); }
/************************显示数据调整函数************************/ uchar dat_adj(uint dat1) {
uchar i;
dis_buf[0]=(uchar)(dat1/10);   //十位  dis_buf[1]=(uchar)(dat1%10);   //个位  dis_buf[2]=11;  dis_buf[3]=12;
if(dis_buf[0]==0)i=1;  return(i); }
/**************************字符串显示函数**************************/ void print(uchar *str) {
while(*str!='\\0')      //直到字符串结束  {
dat_wrt(*str);
str++;        //指向下一个字符  } }
/***************************显示子函数****************************/ void disp(uint dat) {
uchar temp,j;  if(dat!=0x00ff)  {
temp=dat_adj(dat);   LCD_Clear();   lcd_start(0x00);
print(dis1);       //显示文字
lcd_start(0x45+temp);     //确定显示起始位置   for(j=temp;j<4;j++)      //写显示数据    dat_wrt(dis2[dis_buf[j]]);  }  else  {
LCD_Clear();
lcd_start(0x42+temp);     //确定显示起始位置   print(dis3);  } }