GIỚI THIỆU ĐỀ TÀI
I.
- Em đưa ra mô hình thiết kế và lập trình điều khiển cân điện
tử sử dụng MSP430G2553 hiển thị LCD.
II. MỤC TIÊU YÊU CẦU
Mục tiêu:
Thiết kế được sơ đồ và giải thuật đề tài.
Giao tiếp được giữa cảm biến cân với MSP430 và giao tiếp
giữa MSP430 với LCD.
2. Yêu cầu:
Nắm vững kiến thức về
Sơ đồ chân, cách giao tiếp và các chức năng của linh kiện
được sử dụng.
Giải thuật lập trình và điều khiển.
1.
III. PHƯƠNG PHÁP THỰC HIỆN:
1.
Tìm hiểu và lựa chọn linh kiện:
Đề tài sử dụng cảm biến loadcell loại 10kg
•
•
•
•
•
•
•
Trở kháng đầu vào : 1066 ±20
Trở kháng ngõ ra : 1000 ±20
Điện áp hoạt động : 5V
Dây đỏ : ngõ vào (+)
Dây đen : ngõ vào (-)
Dây xanh : ngõ ra (+)
Dây trắng : ngõ ra (-)
1
Hình 1 : Cảm biến loadcell 10kg
2
1.1) Loadcell : là thiết bị cảm biến dùng để chuyển đổi lực
hoặc trọng lượng thành tín hiệu điện thường được sử
dụng để cảm ứng các lực lớn, tĩnh hay các lực biến thiên
chậm.
1.2) Cấu tạo: Loadcell được cấu tạo bởi hai thành phần,thành
phần thứ nhất là Strain gauge và thành phần còn lại là
Load
+Strain gauge Strain gauge là một điệ n trở đặc biệt chỉ nhỏ
bằng móng tay, có điện trở thay đổi khi bị nén hay kéo dãn
và được nuôi bằng một nguồn điệ n ổn định, đượ c dán lên
“ Load ” - một thanh kim loại chịu tải có tính đàn hồi
Hình 1: Cấu tạo cảm biến Loadcell
Cấu tạo chính của Loadcell gồm các điện trở strain gauge
R1,R2,R3,R4 kết nối thành một cầu trở Wheatstone (như
hình dưới) và được dán vào bề mặt thân loadcell.
3
Hình 2: Mạch căn bản của cầu Wheatstone
Một điện áp kích thích được cung cấp cho ngõ vào loadcell
(2 góc (1) và (4) của cầu điện trở Wheatstone) và điện áp
tín hiệu ra được đo giữa hai góc
Ban đầu cầu cân bằng,điện áp ra bằng 0V.Khi có lực tác
động lên điện trở strain gauge(được mắc dưới bàn cân) nó
sẽ thay đổi giá trị => Mạch cầu không còn cân bằng nữa =>
Xuất hiện điện áp ở 2 điểm (Như hình). Từ đó ta lấy được
khối lượng từ mức điện áp trả về.
4
Hình 3:Nguyên lý hoạt động của loadcell
Điện trở của strain gauge đươc tính theo công thức :
5
R= Điện trở strain gauge (Ohm)
L = Chiều dài của sợi kim loại strain gauge (m)
S = Tiết diện của sợi kim loại strain gauge (m2)
P= Điện trở suất vật liệu của sợi kim loại strain gauge
Khi dây kim loại bị lực tác động sẽ thay đổi điện trở
Khi dây bị lực nén, chiều dài strain gauge giảm, điện trở sẽ
giảm xuống.
Khi dây bi kéo dãn, chiều dài strain gauge tăng, điện trở sẽ
tăng lên
Điện trở thay đổi tỷ lệ với lực tác động.
6
Hình 4: Strain gauge (Mô tả thay đổi của lực tác dụng)
7
1.3) Phân loại:
Có thể phân loại Loadcells như sau:
Loại Loadcell theo lực tác động: chịu kéo (Shear Loadcell),
chịu nén (Compression Loadcell), dạng uốn (Bending),
chịu xoắn (Tension Loadcell)
Loại theo kích thước và khả năng chịu tải: Loại bé, vừa, lớn
Loại Loadcell theo hình dạng: Dạng đĩa, dạng thanh, dạng
trụ, dạng cầu, dạng chữ S ,.. như hình dưới
8
Hình 5 :Các dạng của Loadcell
Loại loadcell theo tín hiệu mã hóa:
o Tín hiệu từ Loadcell số (Digital Loadcell) truyền về bộ chỉ thị là dạng số (Đếm
o
xung =>Vi điều khiển =>hiển thị)
Tín hiệu từ Loadcell tương tự (Analog Loadcell) truyền về bộ chỉ thị là dạng điện
áp.( Tín hiệu ra dạng tương tự => Khuếch đại =>ADC => vi điều khiển =>hiển thị)
o
9
Hình 6:Digital Loadcell và Analog Loadcell
1.4) Ứng dụng của Loadcell:
Một ứng dụng khá phổ biến thường thấy của Loadcell là
được sử dụng trong các loại Cân điện tử và chiếc cân kĩ
thuật đòi hỏi độ chính xác cao cho tới những chiếc cân có
trọng tải lớn trong công nghiệp như cân xe tải.Có một số
loại Loadcell được gắn vào đầu của ngón tay robot để xác
định độ bền kéo và lực nén tác động vào các vật khi chúng
cầm nắm hoặc nhấc lên, và một vài ứng dụng phổ biến
khác
10
•
•
•
•
•
Hx711 là mạch đọc giá trị cảm biến loadcell với độ phân
giải 24bit và chuyển sang giao tiếp 2 dây (clock và data) để
gửi dữ liệu cho vi điều khiển.
Điện áp hoạt động: 2,7-5v
Dòng điện tiêu thụ: <1,5mA
Độ phân giải: 24 bit ADC
Ngõ vào:
Dây đỏ của Loadcell kết nối với E+
Dây đen Loadcell kết nối với EDây xanh Loadcell kết nối với A+
Dây trắng Loadcell kết nối với ANgõ ra:
Chân SCK kết nối với chân P1.0 của MSP430G2553
Chân DT kết nối với chân P1.5 của MSP430G2553
Hình 2: Mạch chuyển đổi ADC HX711
MSP430G2553
11
•
Ngõ vào:
Chân SCK kết nối với chân P1.0 của MSP430G2553
Chân DT kết nối với chân P1.5 của MSP430G2553
•
Ngõ ra: Dữ liệu
Chân P2.2 kết nối với D4 của LCD
Chân P2.3 kết nối với D5 của LCD
Chân P2.4 kết nối với D6 của LCD
Chân P2.5 kết nối với D7 của LCD
Hình 3: Sơ đồ chân của MSP430G2553
LCD loại 16x2
12
Hình 4: LCD 16x2
2.
Sơ đồ khối:
13
3.
Lưu đồ:
4.
Sơ đồ nguyên lí:
14
Hình 5: Sơ đồ nguyên lí
5.
Phần code chương trình:
#include "msp430g2553.h"
#include "chanmsp.h"
#include "LCD16x2.h"
#define ADDO P1OUT5
#define ADSK P1OUT0
#define ADDO_IN P1IN5
#define ADDO_DIR P1DIR5
#define ADSK_DIR P1DIR0
15
unsigned long ReadCount(void);
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
if (CALBC1_1MHZ == 0xff)
{ while(1);
}
DCOCTL = 0;
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
BCSCTL2 |= SELM_0;
P1DIR |= BIT0 + BIT5;
LCD_Initilize();
LCD_Clear();
LCD_GoToXY(0,0);
LCD_Write_String("DO AN VI XU LY");
LCD_GoToXY(1,0);
__delay_cycles(2000000);
LCD_Clear();
LCD_GoToXY(0,0);
LCD_Write_String("GIAO VIEN HUONG DAN:");
LCD_GoToXY(1,0);
LCD_Write_String("TRAN HUU DANH");
__delay_cycles(2000000);
LCD_Clear();
16
LCD_GoToXY(0,0);
LCD_Write_String("SV THUC HIEN:");
__delay_cycles(2000000);
LCD_Clear();
LCD_GoToXY(0,0);
LCD_Write_String("NGO VU ANH");
__delay_cycles(2000000);
while(1)
{
unsigned long data;
data = ReadCount();
LCD_GoToLineOne();
LCD_Write_String("GIA TRI CAN DUOC");
LCD_GoToLineTwo();
LCD_Write_Float((float)(8298648-data)/460,2);
LCD_Write_String(" gram");
__delay_cycles(1500000);
LCD_Clear();
}
}
unsigned long ReadCount(void){
unsigned long Count;
unsigned char i;
17
ADDO_DIR = 1;
ADSK_DIR = 1;
ADDO=1;
ADSK=0;
Count=0;
ADDO_DIR = 0;
while(ADDO_IN);
for (i=0;i<24;i++){
ADSK=1;
Count=Count<<1;
ADSK=0;
if(ADDO_IN) Count++;
}
ADSK=1;
Count=Count^0x800000;
ADSK=0;
return(Count);
}
////////////////////////////////////////////////////////////////////
// THU VIEN LCD 1602 (4BIT)
#ifndef _LCD16x2_H_
18
#define _LCD16x2_H_
#include "chanmsp.h"
#define LCDMaxLines
2
#define LCDMaxChars
16
#define LCD_CLEAR
0x01
#define LCD_RETURN_HOME
0x02
#define LCD_ENTRY_MODE
0x07
#define LCD_CURROR_OFF
0x0C
#define LCD_UNDERLINE_ON 0x0E
#define LCD_BLINK_CURROR_ON 0x0F
#define LCD_MOVE_LEFT
#define LCD_MOVE_RIGHT
0x10
0x14
#define LCD_TURN_ON
0x0C
#define LCD_TURN_OFF
0x08
#define LCD_SHIFT_LEFT
0x18
#define LCD_SHIFT_RIGHT
0x1E
#define LCD_LINE_ONE
0x80
#define LCD_LINE_TWO
0xc0
#define LCD_LINE_THREE
0x94
#define LCD_LINE_FOUR
0xD4
#define BlankSpace
''
19
#define LCD_RS _P2_OUT->_BIT.b0
Register select pin connected to P0.0
//
#define LCD_EN _P2_OUT->_BIT.b1
Enable pin connected to P2.2
//
#define LCD_D4 _P2_OUT->_BIT.b2
#define LCD_D5 _P2_OUT->_BIT.b3
#define LCD_D6 _P2_OUT->_BIT.b4
#define LCD_D7 _P2_OUT->_BIT.b5
#define LCD_RS_DIR _P2_DIR->_BIT.b0
#define LCD_EN_DIR
_P2_DIR->_BIT.b1
#define LCD_D4_DIR _P2_DIR->_BIT.b2
#define LCD_D5_DIR _P2_DIR->_BIT.b3
#define LCD_D6_DIR
_P2_DIR->_BIT.b4
#define LCD_D7_DIR _P2_DIR->_BIT.b5
void DataBus(char value);
void LCD_CmdWrite( char cmd);
void LCD_Initilize();
void LCD_Write_Char( char dat);
void LCD_Clear();
void LCD_GoToLineOne();
void LCD_GoToLineTwo();
20
void LCD_GoToXY(char row, char col);
void LCD_Write_String(char *string_ptr);
void LCD_Write_Number(unsigned int num);
void LCD_Write_Int(unsigned long n);
void LCD_Write_Float(float x, unsigned char coma);
void LCD_Write_Reg(char *name, int n);
void LCD_DisplayRtcTime(char hour,char min,char sec);
void LCD_DisplayRtcDate(char day,char month,char year);
void LCD_CharInit();
/*const char Smile01[8] ={0,10,10,0,17,14,2,0};*/
/*--------------------------------------------------------------------------------*/
void LCD_CmdWrite( char cmd)
/*--------------------------------------------------------------------------------*/
{
DataBus(cmd&0xf0);
of the command to LCD
// Send the Higher Nibble
LCD_RS=0;
// Select the Command Register by pulling RS LOW
LCD_EN=1;
// Send a High-to-Low Pusle at Enable Pin
__delay_cycles(10);
LCD_EN=0;
21
__delay_cycles(100);
// wait for some time
DataBus((cmd<<4) & 0xf0);
// Send the Lower Nibble of the command to LCD
LCD_RS=0;
// Select the Command Register by pulling RS LOW
LCD_EN=1;
// Send a High-to-Low Pusle at Enable Pin
__delay_cycles(10);
LCD_EN=0;
__delay_cycles(1000);
}
/*-------------------------------------------------------------------------------*/
void LCD_Initilize()
/*--------------------------------------------------------------------------------*/
{
LCD_RS_DIR=1;
LCD_EN_DIR=1;
LCD_D4_DIR=1;
LCD_D5_DIR=1;
LCD_D6_DIR=1;
LCD_D7_DIR=1;
P2SEL &= ~BIT6;
P2SEL &= ~BIT7;
22
LCD_CmdWrite(LCD_RETURN_HOME);
//Initilize the LCD in 4bit Mode
LCD_CmdWrite(0x28);
LCD_CmdWrite(LCD_CURROR_OFF);
LCD_CmdWrite(LCD_CLEAR);
// Display ON cursor ON
// Clear the LCD
LCD_CmdWrite(LCD_LINE_ONE);
Position
// Move the Cursor to First line First
}
/*--------------------------------------------------------------------------------*/
void LCD_Write_Char( char dat)
/*--------------------------------------------------------------------------------*/
{
DataBus(dat & 0xf0);
LCD
// Send the Higher Nibble of the Data to
LCD_RS=1;
// Select the Data Register by pulling RS HIGH
LCD_EN=1;
// Send a High-to-Low Pusle at Enable Pin
__delay_cycles(10);
LCD_EN=0;
__delay_cycles(100);
DataBus((dat <<4) & 0xf0);
LCD
LCD_RS=1;
// Send the Lower Nibble of the Data to
// Select the Data Register by pulling RS HIGH
23
LCD_EN=1;
// Send a High-to-Low Pusle at Enable Pin
__delay_cycles(10);
LCD_EN=0;
__delay_cycles(1000);
}
/*--------------------------------------------------------------------------------*/
void LCD_Clear()
/*--------------------------------------------------------------------------------*/
{
LCD_CmdWrite(LCD_CLEAR);
and go to First line First Position
// Clear the LCD
LCD_CmdWrite(LCD_LINE_ONE);
}
/*--------------------------------------------------------------------------------*/
void LCD_GoToLineOne()
/*--------------------------------------------------------------------------------*/
{
LCD_CmdWrite(LCD_LINE_ONE);
Position
// Move the Cursor to First line First
}
24
/*--------------------------------------------------------------------------------*/
void LCD_GoToLineTwo()
/*--------------------------------------------------------------------------------*/
{
LCD_CmdWrite(LCD_LINE_TWO);
First Position
// Move the Cursor to Second line
}
/*--------------------------------------------------------------------------------*/
void LCD_GoToXY(char row, char col)
/*--------------------------------------------------------------------------------*/
{
char pos;
if(row
{
pos= LCD_LINE_ONE | (row << 6);
// take the line
number
//row0->pos=0x80
row1->pos=0xc0
if(col
pos= pos+col;
//take the
char number
//now pos points to the
given XY pos
25