gp2y10的驱动程序
晶振:12.000MHz
传感器接口:
1、6引脚接+5V电源
2、4引脚接GND
3引脚接PWM信号——T0CLKO=P3.4或PWM00=P2.0
5引脚接AD引脚——单片机的P1.0引脚
显示接口:
J3接LCD1602
参考文献:
《集体智慧编程》
《机器学习实战》
单片机源程序:
- /********************************************************************************
- * 描述: LCD1602 滚动显示 *
- * 显示方式: *
- * 1、从左到右逐字显示,闪动二次,清屏。 *
- * 2、再从右到左逐字显示,闪动二次,清屏。 *
- * 3、周期性地重复上述显示方式。 *
- ********************************************************************************/
- #include <reg51.h> //51寄存器文件
- #include <intrins.h>
- /**********Define Variable**********/
- #define ulong unsigned long
- #define uint unsigned int
- #define uchar unsigned char
- #define bool bit
- /***Define ADC operation const for ADC_CONTR***/
- #define ADC_POWER 0x80
- #define ADC_FLAG 0x10
- #define ADC_START 0x08
- #define ADC_SPEEDLL 0x00
- #define ADC_SPEEDL 0x20
- #define ADC_SPEEDH 0x40
- #define ADC_SPEEDHH 0x60
- //ADRJ位复位时为0,此时AD值格式:
- //取10位时,(ADC_RES[7:0],ADC_RES[1:0])=1024*Vin/Vcc
- //取8位时,(ADC_RES[7:0])=256*Vin/Vcc
- //ADRJ为1,此时AD值格式:
- //取10位时,(ADC_RES[1:0],ADC_RES[7:0])=1024*Vin/Vcc
- /*******Declare SFR associated with the ADC****/
- sfr ADC_CONTR=0xBC;
- sfr ADC_RES=0xBD;
- sfr ADC_LOW2=0xBE;
- sfr P1ASF=0x9D;
- /*****Declare SFR associated with the P1******/
- sfr P1M1=0x91;
- sfr P1M0=0x92;
- /***Declare SFR associated with the Timer****/
- sfr AUXR=0x8E;
- sfr INT_CLKO=0x8F;
- sbit T0CLKO=P3^4;
- sbit PWM00=P2^0;
- /*****Declare SFR associated with the PCA*****/
- sfr CCON=0xD8;
- sbit CCF0=CCON^0;
- sbit CCF1=CCON^1;
- sbit CR=CCON^6;
- sbit CF=CCON^7;
- sfr CMOD=0xD9;
- sfr CL=0xE9;
- sfr CH=0xF9;
- sfr CCAPM0=0xDA;
- sfr CCAP0L=0xEA;
- sfr CCAP0H=0xFA;
- sfr CCAPM1=0xDB;
- sfr CCAP1L=0xEB;
- sfr CCAP1H=0xFB;
- sfr PCAPWM0=0xF2;
- sfr PCAPWM1=0xF3;
- /****1602 LCD****************/
- sbit LCD_RS = P2^6; //复位端
- sbit LCD_RW = P2^5; //写数据端
- sbit LCD_EP = P2^7; //使能端
- uchar display1[6];
- bit flag;
- uint addata;
- /****************延时函数************************/
- delay(uint ms)
- { //延时子程序
- uint i;
- while(ms--)
- {
- for(i = 0; i< 250; i++)
- {
- _nop_(); //空执行
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- /************************************************/
- void Delay880us() //@12.000MHz
- {
- unsigned char i, j;
- i = 11;
- j = 66;
- do
- {
- while (--j);
- } while (--i);
- }
- /****************侧忙函数************************/
- bool lcd_bz()
- {
- bool result;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EP = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- result = (bool)(P0 & 0x80); //检测P0最高位是否为1
- LCD_EP = 0;
- return result;//返回侧忙结果
- }
- /****************写命令函数************************/
- lcd_wcmd(uchar cmd)
- { // 写入指令数据到LCD
- while(lcd_bz());
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_EP = 0;
- _nop_();
- _nop_();
- P0 = cmd; //将8位指令通过P0口传给1602
- _nop_();
- _nop_(); //用于产生一个脉冲宽度
- _nop_();
- _nop_();
- LCD_EP = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EP = 0;
- }
-
- lcd_pos(uchar pos)
- { //设定显示位置
- lcd_wcmd(pos | 0x80);
- }
- /****************写数据函数************************/
- lcd_wdat(uchar dat)
- { //写入字符显示数据到LCD
- while(lcd_bz());
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EP = 0;
- P0 = dat; //将8位数据通过P0口传给1602
- _nop_();
- _nop_(); //用于产生一个脉冲宽度
- _nop_();
- _nop_();
- LCD_EP = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EP = 0;
- }
- /****************LCD 初始化************************/
- lcd_init()
- { //LCD初始化设定
- lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
- delay(1);
- lcd_wcmd(0x0c); //显示开,关光标
- delay(1);
- lcd_wcmd(0x06); //移动光标
- delay(1);
- lcd_wcmd(0x01); //清除LCD的显示内容
- delay(1);
- }
- /*****************Initial ADC sfr***************/
- void InitADC()
- {
- //P1ASF=0xff;//Open 8 channels ADC function
- P1ASF=0x01;//Open P1.0 channels ADC function
- ADC_RES=0;//Clear previous result
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
- delay(2);//ADC power-on and delay
- }
- /****************Get ADC result*****************/
- uchar GetADCResult(uchar ch)
- {
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
- _nop_();//Must wait before inqurity
- _nop_();
- _nop_();
- _nop_();
- while(!(ADC_CONTR&ADC_FLAG));//Wait complete flag
- ADC_CONTR&=~ADC_FLAG;//Close ADC
- return ADC_RES;
- }
- void tm0() interrupt 1 using 1
- {
- flag=!flag;
- if(flag)
- {
- TL0=0xC0;
- TH0=0xFE;
- PWM00=1;
- }
- else
- {
- TL0=0x30;
- TH0=0xDA;
- PWM00=0;
- Delay880us();
- addata=GetADCResult(0);
- }
- }
- /****************主函数****************************/
- main()
- {
- uchar i;
- //uint addata;
- P1M1=P1M1|0x01;
- P1M0=P1M0|0x00;//P1.0为输入口
- lcd_init();// 初始化LCD
- InitADC();//初始化ADC
- //AUXR=0x80;//定时器0设置为1T模式
- INT_CLKO=0x01;//使能定时器0时钟输出使能
- TMOD=0x01;//设置定时器0为模式1(16位自动重装载模式)
- TL0=0x30;
- TH0=0xDA;
- T0CLKO=0;
- flag=0;
- TR0=1;
- ET0=1;
- EA=1;
- delay(10);
- addata=998;
- display1[0]=addata/1000+0x30;
- addata=addata%1000;
- display1[1]=addata/100+0x30;
- addata=addata%100;
- display1[2]=addata/10+0x30;
- display1[3]=addata%10+0x30;
- lcd_wcmd(0x06);//向右移动光标
- lcd_pos(0);//设置显示位置为第一行的第1个字符
- for(i=0;i<4;i++)
- {
- lcd_wdat(display1[i]);
- delay(30);//控制两字之间显示速度
- }
- delay(1500);//控制停留时间
- lcd_wcmd(0x01);//清除LCD的显示内容
- while(1)
- {
- //addata=GetADCResult(0);//8为AD转换
- //addata=(addata<<2)+ADC_LOW2;//10位AD转换
- display1[0]=addata/1000+0x30;
- addata=addata%1000;
- display1[1]=addata/100+0x30;
- addata=addata%100;
- display1[2]=addata/10+0x30;
- display1[3]=addata%10+0x30;
- lcd_wcmd(0x06);//向右移动光标
- lcd_pos(0);//设置显示位置为第一行的第1个字符
- for(i=0;i<4;i++)
- {
- lcd_wdat(display1[i]);
- delay(30);//控制两字之间显示速度
- }
- delay(500);//控制停留时间
- lcd_wcmd(0x01);//清除LCD的显示内容
- }
- }
- /**************************************************/
- /*********test T0 PWM*******
- main()
- {
- //AUXR=0x80;//定时器0设置为1T模式
- INT_CLKO=0x01;//使能定时器0时钟输出使能
- TMOD=0x01;//设置定时器0为模式1(16位自动重装载模式)
- TL0=0x30;
- TH0=0xDA;
- T0CLKO=0;
- flag=0;
- TR0=1;
- ET0=1;
- EA=1;
- while(1)
- {
- ;
- }
- }
- ***************************/
- /***********test PWM*************
- main()
- {
- CCON=0;
- CL=0;
- CH=0;
- CMOD=0x02;
-
- CCAP0H=0x80;
- CCAP0L=0x80;
- CCAPM0=0x42;
- ***************************
- //实测结果与程序相符
- //Focs=12MHz,Fpca=(1/2)*Focs=6MHz,
- //Fpwm=
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
下载:
testGP2Y10.rar
(169.42 KB, 下载次数: 52)
|