- #include "STC89.h"
- #include "intrins.h"
- #include "process.h"
- #define CycleTime_Ultrasonic 10
- #define TR_Ultrasonic TR0
- #define TH_Ultrasonic TH0
- #define TL_Ultrasonic TL0
- #define ET_Ultrasonic ET0
- #define TMOD_Ultrasonic TMOD
- sbit FrontTrig=P2^2;
- sbit FrontEcho=P3^2;//accord to the selected timer, timer 0-->P32 timer 1--->P33
- void InitDistance(void);
- float GetDistance(void);
- void StartCheckDistance(void);
- #define AddWr 0x90 //写数据地址 PCF8591 bit321为地址A0 A1 A2
- #define AddRd 0x91 //读数据地址 PCF8591
- sbit SDA_PCF8591=P2^6;
- sbit SCL_PCF8591=P2^7;
- unsigned char ReadADC(unsigned char Chl);
- unsigned char SysTime;
- unsigned char SoundAdc;
- unsigned int LedShowData;
- unsigned char NumToShow=6;
- unsigned int DistanceData;
- sbit Key0=P0^4;
- unsigned char OldKey0,DisMode=0;
- void InitTimer2(void)
- {
- T2MOD = 0;
- T2CON = 0;
- RCAP2H = 0xFC;
- RCAP2L = 0x17;
- EA=1; //总中断打开
- ET2=1; //定时器T2允许中断
- TR2=1; //定时器T2开始工作
- }
- void et2(void) interrupt 5 using 0
- {
- TF2=0;
- SysTime++;
- }
- bit ack; //应答标志位
- /*------------------------------------------------
- 启动总线
- ------------------------------------------------*/
- void Start_I2c()
- {
- SDA_PCF8591=1; //发送起始条件的数据信号
- _nop_();
- SCL_PCF8591=1;
- _nop_(); //起始条件建立时间大于4.7us,延时
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA_PCF8591=0; //发送起始信号
- _nop_(); //起始条件锁定时间大于4μ
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL_PCF8591=0; //钳住I2C总线,准备发送或接收数据
- _nop_();
- _nop_();
- }
- /*------------------------------------------------
- 结束总线
- ------------------------------------------------*/
- void Stop_I2c()
- {
- SDA_PCF8591=0; //发送结束条件的数据信号
- _nop_(); //发送结束条件的时钟信号
- SCL_PCF8591=1; //结束条件建立时间大于4μ
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA_PCF8591=1; //发送I2C总线结束信号
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*----------------------------------------------------------------
- 字节数据传送函数
- 函数原型: void SendByte(unsigned char c);
- 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
- 此状态位进行操作.(不应答或非应答都使ack=0 假)
- 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
- ------------------------------------------------------------------*/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
- for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
- {
- if((c<<BitCnt)&0x80)SDA_PCF8591=1; //判断发送位
- else SDA_PCF8591=0;
- _nop_();
- SCL_PCF8591=1; //置时钟线为高,通知被控器开始接收数据位
- _nop_();
- _nop_(); //保证时钟高电平周期大于4μ
- _nop_();
- _nop_();
- _nop_();
- SCL_PCF8591=0;
- }
-
- _nop_();
- _nop_();
- SDA_PCF8591=1; //8位发送完后释放数据线,准备接收应答位
- _nop_();
- _nop_();
- SCL_PCF8591=1;
- _nop_();
- _nop_();
- _nop_();
- if(SDA_PCF8591==1)ack=0;
- else ack=1; //判断是否接收到应答信号
- SCL_PCF8591=0;
- _nop_();
- _nop_();
- }
- /*----------------------------------------------------------------
- 字节数据传送函数
- 函数原型: unsigned char RcvByte();
- 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
- 发完后请用应答函数。
- ------------------------------------------------------------------*/
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
-
- retc=0;
- SDA_PCF8591=1; //置数据线为输入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _nop_();
- SCL_PCF8591=0; //置时钟线为低,准备接收数据位
- _nop_();
- _nop_(); //时钟低电平周期大于4.7us
- _nop_();
- _nop_();
- _nop_();
- SCL_PCF8591=1; //置时钟线为高使数据线上数据有效
- _nop_();
- _nop_();
- retc=retc<<1;
- if(SDA_PCF8591==1)retc=retc+1; //读数据位,接收的数据位放入retc中
- _nop_();
- _nop_();
- }
- SCL_PCF8591=0;
- _nop_();
- _nop_();
- return(retc);
- }
- /*----------------------------------------------------------------
- 非应答子函数
- 原型: void NoAck_I2c(void);
- ----------------------------------------------------------------*/
- void NoAck_I2c(void)
- {
-
- SDA_PCF8591=1;
- _nop_();
- _nop_();
- _nop_();
- SCL_PCF8591=1;
- _nop_();
- _nop_(); //时钟低电平周期大于4μ
- _nop_();
- _nop_();
- _nop_();
- SCL_PCF8591=0; //清时钟线,钳住I2C总线以便继续接收
- _nop_();
- _nop_();
- }
- /*------------------------------------------------
- 读AD转值程序
- 输入参数 Chl 表示需要转换的通道,范围从0-3
- 返回值范围0-255
- ------------------------------------------------*/
- unsigned char ReadADC(unsigned char Chl)
- {
- unsigned char Val;
- Start_I2c(); //启动总线
- SendByte(AddWr); //发送器件地址
- if(ack==0)return(0);
- SendByte(0x00|Chl); //发送器件子地址
- if(ack==0)return(0);
- Start_I2c();
- SendByte(AddRd);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //发送非应位
- Stop_I2c(); //结束总线
- Start_I2c();
- SendByte(AddRd);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //发送非应位
- Stop_I2c(); //结束总线
- return(Val);
- }
- void InitDistance(void) //使用EX0口
- {
- TMOD_Ultrasonic |= 0x09;//打开GATE0 内部时钟计数模式
- ET_Ultrasonic=0;
- FrontTrig = 0;
- }
- void Delay(void)
- {
- unsigned i=10;
- while(i--)
- _nop_( );
- }
- void StartCheckDistance(void)
- {
- FrontTrig = 1;
- TH_Ultrasonic = 0;
- TL_Ultrasonic = 0;
- Delay();
- TR_Ultrasonic=1;
- FrontTrig = 0;
- }
- float GetDistance(void)//always return value ,unit:mm
- {
- static unsigned char DisTestStep,DisDelayTime;
- unsigned int FrontTime;
- static float DistanceData=0;
- switch(DisTestStep)
- {
- case 0:
- {
- StartCheckDistance();
- DisTestStep = 1;
- break;
- }
- case 1:
- {
- DisDelayTime++;
- if(DisDelayTime >= 30/CycleTime_Ultrasonic)
- {
- DisDelayTime = 0;
- DisTestStep = 2;
- }
- break;
- }
- case 2:
- {
- TR0 = 0;
- FrontTime = TH_Ultrasonic;
- FrontTime = FrontTime<<8;
- FrontTime = FrontTime+TL_Ultrasonic;
- DistanceData = FrontTime;
- DistanceData = DistanceData*0.17;
- DisTestStep = 3;
- break;
- }
- case 3:
- {
- DisDelayTime++;
- if(DisDelayTime >= 300/CycleTime_Ultrasonic)
- {
- DisDelayTime = 0;
- DisTestStep = 0;
- }
- break;
- }
- }
- return DistanceData;
- }
- main()
- {
- InitTimer2();
- //InitSci();
- InitDistance();
- for(;;)
- {
- StartPro(0);
- SoundAdc = ReadADC(3);
- DistanceData = GetDistance();
- if((OldKey0==0)&&(Key0==1))
- {
- DisMode = ~DisMode;
- }
- OldKey0 = Key0;
- if(DisMode == 0)
- {
- P25 = 0;
- if(DistanceData < 200)
- {
- NumToShow = 0;
- }
- else if(DistanceData > 800)
- {
- NumToShow = 12;
- }
- else
- {
- NumToShow = (DistanceData-200)/50;
- }
- }
- else
- {
- P25 = 1;
- if(SoundAdc < 62)
- {
- NumToShow = 0;
- }
- else if(SoundAdc > 110)
- {
- NumToShow = 12;
- }
- else
- {
- NumToShow = (SoundAdc-62)>>2;
- }
- }
- LedShowData = (0x0FFF>>NumToShow);
- P36 = LedShowData>>11;
- P35 = LedShowData>>10;
- P34 = LedShowData>>9;
- P33 = LedShowData>>8;
- P10 = LedShowData>>7;
- P11 = LedShowData>>6;
- P12 = LedShowData>>5;
- P13 = LedShowData>>4;
- P14 = LedShowData>>3;
- P15 = LedShowData>>2;
- P16 = LedShowData>>1;
- P17 = LedShowData;
-
- EndPro(10);
- }
- }
复制代码
|