PIC Vietnam

Go Back   PIC Vietnam > Robotics > Cảm biến

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Cảm biến Camera, siêu âm, hồng ngoại, gyro, la bàn...

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 27-08-2011, 06:10 PM   #2
duongvt
Nhập môn đệ tử
 
Tham gia ngày: Apr 2011
Bài gửi: 9
:
Trích:
Nguyên văn bởi luulytim90 View Post
Chào mọi người,
Em đang có một bài tập sử dụng cảm biến SRF02 với Atmega128 qua giao tiếp I2C. Các pin SCL và SDA lần lượt được nối với PIN D0 và D1 trên vi xử lý (cổng SCL/SDA của TWI). Giữa dây +5V và 2 dây SCL, SDA có nối 2 điện trở 1800ohm.

Em gửi lệnh startRanging với giá trị 0x51 (đo bằng cm) sau đó đọc giá trị trả về từ register 0x02 và 0x03 rồi cộng lại. (Dưới đây là code C viết trong AVR Studio)

Mọi thứ có vẻ như rất ổn ngoại trừ kết quả đo thu được từ cảm biến hầu như vô nghĩa. Nó trả về giá trị random trong khoảng từ 25 đến 40 trong mỗi lần đọc. Các anh chị nếu có con SRF02 hoặc có kinh nghiệm làm việc với cảm biến này giúp em tìm ra lỗi sai với. Cám ơn mọi người!

Code:
#define F_CPU 14745600UL   

#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>
#include <string.h>
#include <stdio.h>  
#include <stdint.h>

#include "LCD.c"

#define SRF02		0xE0				// Address of SRF02
 
void i2c_transmit(char address, char reg, char data)
{
	TWCR = 0xA4;                                                  // send a start bit on i2c bus
	while(!(TWCR & 0x80));                                        // wait for confirmation of transmit 
	TWDR = address;                                               // load address of i2c device
	TWCR = 0x84;                                                  // transmit
	while(!(TWCR & 0x80));                                        // wait for confirmation of transmit
	TWDR = reg;
	TWCR = 0x84;                                                  // transmit
	while(!(TWCR & 0x80));                                        // wait for confirmation of transmit
	TWDR = data;
	TWCR = 0x84;                                                  // transmit
	while(!(TWCR & 0x80));                                        // wait for confirmation of transmit
	TWCR = 0x94;                                                  // stop bit
}

void startRanging(void)
{
	i2c_transmit(SRF02, 0, 0x51);					// Cause SRF02 to start a ranging returning results in CM
} 


unsigned char i2cRead(char address, char reg)
{
char read_data = 0;

   TWCR = 0xA4;                                                  // send a start bit on i2c bus
   while(!(TWCR & 0x80));                                        // wait for confirmation of transmit  
   TWDR = address;                                               // load address of i2c device
   TWCR = 0x84;                                                  // transmit 
   while(!(TWCR & 0x80));                                        // wait for confirmation of transmit
   TWDR = reg;                                                   // send register number to read from
   TWCR = 0x84;                                                  // transmit
   while(!(TWCR & 0x80));                                        // wait for confirmation of transmit

   TWCR = 0xA4;                                                  // send repeated start bit
   while(!(TWCR & 0x80));                                        // wait for confirmation of transmit 
   TWDR = address+1;                                             // transmit address of i2c device with readbit set
   TWCR = 0xC4;                                                  // clear transmit interupt flag
   while(!(TWCR & 0x80));                                        // wait for confirmation of transmit
   TWCR = 0x84;                                                  // transmit, nack (last byte request)
   while(!(TWCR & 0x80));                                        // wait for confirmation of transmit 
   read_data = TWDR;                                             // and grab the target data
   TWCR = 0x94;                                                  // send a stop bit on i2c bus
   return read_data;

}

unsigned int getRange(void) 
{
	unsigned int x;
	x = i2cRead(SRF02,2) << 8;					// Get high and then low bytes of the range
	x += i2cRead(SRF02,3);
	
	return(x);
}

void TWI_init_master(void) // Function to initialize master
{
	TWBR=0x0c;	// Bit rate
	TWDR=0xFF;
	TWCR=(1<<TWEN)|
		 (0<<TWIE)|(0<<TWINT)|
		 (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
		 (0<<TWWC);

	TWSR=(0<<TWPS1)|(0<<TWPS0);	// Setting prescalar bits
	// SCL freq= F_CPU/(16+2(TWBR).4^TWPS)
}

int main(void)
{
	char buffer[16];
	int range;
	TWI_init_master();
	LCD_Init();
	LCD_Clear();
	_delay_ms(500);
	startRanging();

	while(1)
	{		
                startRanging();
                _delay_ms(70);
		range = getRange();
		sprintf(buffer, "s= %3d", range);
		LCD_Position(0,0);
		LCD_WriteString(buffer);
		_delay_ms(200);
	}
}
Mình nghĩ F_CPU có ảnh hưởng đến tần số trên dây SCL, vậy nếu mình define F_CPU sai thì có thể gây ra việc đọc không chính xác không?

Cám ơn mọi người giúp đỡ,
Bây giờ Bạn đã làm xong chưa ?? Mình trao đổi chút nhé
theo mình thì thấy mấy con này thướng có hàm khởi tạo "init" nữa ở đây cũng thấy bạn init LCD và I2c nhưng chưa thấy init SRF ...vấn đề là ở đây chăng ??
duongvt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 12:43 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam