現在我打算做一個利用超聲波測距離的東西,現在有一個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();
- }
- }
復制代碼
|