现在我打算做一个利用超声波测距离的东西,现在有一个ii c接口的模块,和开发板一块,希望做一个”盲人眼睛”的小制作,就是利用超声波模块和蜂鸣器两部分,物体离得越近,蜂鸣器可以响的越快,但是测试后总觉得蜂鸣器反应比较迟钝,有物体在前面出现不能立刻察觉到,可是用数码管动态显示就可以察觉到有快速的东西从超声波探头闪过,求大神可以告诉我怎么才能让蜂鸣器灵敏一些!以下是我的程序
第一张
第二张
第三张
第四章
- #include <reg51.h>
- #include <intrins.h>
- sbit SDA=P3^6; // 此引脚须上拉 4.7K 电阻至 VCC
- sbit SCL=P3^7; // 此引脚须上拉 4.7K 电阻至 VCC
- sbit beep=P1^5;
-
- unsigned int range=0;
- //unsigned int range1=0;
- //unsigned int range2=0;
- //unsigned int range3=0;
- //unsigned int min=0;
- void delay50us_chengxv(void) //误差 0us
- {
- unsigned char a,b;
- for(b=9;b>0;b--)
- for(a=1;a>0;a--);
- }
- void delay500ms(void) //误差 0us
- {
- unsigned char a,b,c;
- for(c=205;c>0;c--)
- for(b=116;b>0;b--)
- for(a=9;a>0;a--);
- }
- void delay300ms(void) //误差 0us
- {
- unsigned char a,b,c;
- for(c=5;c>0;c--)
- for(b=212;b>0;b--)
- for(a=140;a>0;a--);
- }
-
- void beepcv()
- {
- unsigned int a;
- if(range<=1500&&range>=0)
- {
- if(range<=1500&&range>=900)
- {
- for(a=600;a>0;a--)
- {
- beep=1;
- delay1(10);
- beep=0;
- delay1(10);
- delay1(175);
- }
- }
- else if(range>=300&&range<900)
- {
- for(a=600;a>0;a--)
- {
- beep=1;
- delay1(10);
- beep=0;
- delay1(10);
- delay1(100);
- }
- }
- else if(range>=0&&range<300)
- {
- for(a=600;a>0;a--)
- {
- beep=1;
- delay1(10);
- beep=0;
- delay1(10);
- delay1(50);
- }
- }
- }
- }
- void delay(void) //short delay 使用速度较快的单片机时,I2C 通讯可能不正常,在此函数中多加 4~8 个_nop_();即可
- {
- _nop_(); _nop_(); _nop_(); _nop_();
- _nop_(); _nop_(); _nop_(); _nop_();
- _nop_(); _nop_(); _nop_(); _nop_();
- _nop_(); _nop_(); _nop_(); _nop_();
- }
- void start(void) //I2C start
- {
- SDA = 1;
- delay();
- SCL = 1;
- delay();
- SDA = 0;
- delay();
- }
- void stop(void) //I2C stop
- {
- SDA = 0;
- delay();
- SCL = 1;
- delay();
- SDA = 1;
- delay();
- }
- void ack(void) //ack
- {
- unsigned char i;
- SCL = 1;
- delay();
- while(SDA == 1 && i < 200)
- {
- i++;
- }
- SCL = 0;
- delay();
- }
- void no_ack() //not ack
- {
- SDA = 1;
- delay();
- SCL = 1;
- delay();
- SCL = 0;
- delay();
- }
- void i2c_write_byte(unsigned char dat) //write a byte
- {
- unsigned char i;
- SCL = 0;
- for(i = 0; i < 8; i++)
- {
- if(dat & 0x80)
- {
- SDA = 1;
- }
- else
- {
- SDA = 0;
- }
- dat = dat << 1;
- delay();
- SCL = 1;
- delay();
- SCL = 0;
- delay();
- }
- SDA = 1;
- delay();
- }
- unsigned char i2c_read_byte(void) //read a byte
- {
- unsigned char i,dat;
- SCL = 0;
- delay();
- SDA = 1;
- delay();
- for(i = 0; i < 8; i++)
- {
- SCL = 1;
- delay();
- dat = dat << 1;
- if(SDA == 1)
- {
- dat++;
- }
- SCL = 0;
- delay();
- }
- return dat;
- }
- void init_i2c(void) //i2c init
- {
- SDA = 1;
- SCL = 1;
- }
- void write_byte(unsigned char address,unsigned char reg,unsigned char command) //address+register+command
- {
- init_i2c();
- start();
- i2c_write_byte(address);
- ack();
- i2c_write_byte(reg);
- ack();
- i2c_write_byte(command);
- ack();
- stop();
- }
- unsigned char read_byte(unsigned char address,unsigned char reg) //address(with bit 0 set) + register
- {
- unsigned char dat;
- init_i2c();
- start();
- i2c_write_byte(address);
- ack();
- i2c_write_byte(reg);
- ack();
- start();
- i2c_write_byte(address+1);
- ack();
- delay();delay();delay();delay();delay(); //此处延时对于 STC89C 系列单片机,可以删除,如果对于快速单
- //片机,需要加至少 50us 的延时,才可以可靠读到数据
- dat = i2c_read_byte();
- no_ack();
- stop();
- return dat;
- }
- void delayms(unsigned int ms) //delay ms
- {
- unsigned char i;
- unsigned int j;
- for(i=0;i<110;i++)
- for(j=0;j<ms;j++);
- }
- /*void change_i2c_address(unsigned char addr_old, unsigned char addr_new)
- // addr_old is the address now, addr_new will be the new address
- { //that you want change to
- delayms(2000); // Protect the eeprom ,you can delete this sentence
- write_byte(addr_old,2,0x9a);
- delayms(1);
- write_byte(addr_old,2,0x92);
- delayms(1);
- write_byte(addr_old,2,0x9e);
- delayms(1);
- write_byte(addr_old,2, addr_new);
-
- delayms(500); //Protect the eeprom, you can delete this sentence
- }
- void config_0x71_0x7d(unsigned char addr_old, unsigned char flag)
- //flag will be 0x71,0x72,0x73,0x74,0x7a,0x7b,0x7c,0x7d
- { //that you want change to
- delayms(2000); // Protect the eeprom ,you can delete this sentence
- write_byte(addr_old,2,0x9c);
- delayms(1);
- write_byte(addr_old,2,0x95);
- delayms(1);
- write_byte(addr_old,2,0x98);
- delayms(1);
- write_byte(addr_old,2, flag);
- delayms(500); //Protect the eeprom, you can delete this sentence
- }*/
- unsigned int detect(unsigned char address,unsigned char command) //0xe8(address) + 0x30(command)
- {
- unsigned int distance,count;
- write_byte(address,2,command); //use command "0x30" to detect the distance
- delayms(1); //安全延时,如果显示不清晰可以将延时调大一些
- //delayms(80); //如果是探测温度此处延时需根据表 1 所列时间相应延长
- count=800;
- while(--count || !SCL) //等待探测结束,count 值调小将减小探测等待时间
- {
- ; // 空语句
- // DigDisplay(range); //显示语句,可根据需要保留或删除
- }
- // while(!SCL)display(range); //you can delete "display(range)"
- //通过查询 SCL 线来智能识别探测是否结束,使用本语句可删除上条语句(count=800;while…)以节省探测时间
- distance=read_byte(address,2);
- distance <<= 8;
- distance += read_byte(address,3);
- return distance; //return 16 bit distance in millimeter
- }
- void main(void)
- {
- //change_i2c_address(0xe8,0xfe); //change default address 0xe8 to 0xfe
- while(1)
- {
- range = detect(0xe8,0x30);
- //0xe8 is the address; 0x30 is the command.you just need the only one sentence to get the range.
- beepcv();
- }
- }
复制代码
|