logo资料库

基于单片机红外线测距的51程序.doc

第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
资料共5页,全文预览结束
//LCD 命令/数据端 //LCD 读/写端 //LCD 使能端 //MCP3001 与 AT89S52 的管脚接线定义 //字符串显示函数 //显示子函数 //算术平均滤波程序 //Busy 标志 //显示 //显示表头 #include #include #define uchar unsigned char #define uint unsigned int #define ulong unsigned long sbit RS=P2^0; sbit RW=P2^1; sbit LCDE=P2^2; sbit MCP_CS=P2^3; sbit MCP_DO=P2^4; sbit MCP_CLK=P2^5; uint measure; uchar flag; uchar code dis[]={"Measure Start"}; uchar code dis1[] = {"Distance:"}; uchar code dis2[] = {"0123456789.cm"}; uchar code dis3[]={"Out Measure!"}; uchar dis_buf[6]; void L_delay(void); void delay_ms(uint n); uint read_MCP(void); void init_1602(void); void busy(void); void dat_wrt(uchar dat); void cmd_wrt(uchar cmd); uint distance(void); void lcd_start(uchar start); void LCD_Clear(void); uchar dat_adj(uint dat1); void print(uchar *str); void disp(uint dat); uint average(void); /****************************主函数*******************************/ main() { //延时函数 //读 MCP3001 //1602 初始化函数 //LCD 忙标志判断函数 //显示代码 //显示 //显示缓冲区 //短延时 //写数据子函数 //写命令子函数 //距离计算函数 //设定显示位置函数 //LCD 清屏函数 //显示数据调整函数 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; for(i=0;i<13;i++) { MCP_CLK=0; L_delay(); MCP_CLK=1; temp<<=1; if(MCP_DO==1)temp|=0x01; } MCP_CS=1; temp&=0x03ff; return(temp); //CS 置低,开始采样数据 //读转换的 10 位数据 //获取有效转换值 } /************************LCD 忙标志判断函数*******************/ void busy(void) { flag=0x80; while (flag&0x80) { P0=0xff; RS=0; //赋初值 高位为 1 禁止 //读写操作使能位禁止时等待 继续检测 //指向地址计数器
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++) { ave+=read_MCP(); L_delay(); } av_dat=(uint)(ave/10); return(av_dat); //连续读取 10 个数据值 //读转换数据 //求平均值 } /*************************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); //确定显示起始位置
分享到:
收藏