ĐỀ BÀI
Sử dụng chuẩn truyền RS232, thiết kế mạch giao tiếp giữa cổng COM máy tính và vi điều khiển.
Máy tính: Viết chương trình xuất/nhập dữ liệu để điều khiển các cơ cấu chấp hành được gắn với board vi điều khiển.
Vi điều khiển: Vi điều khiển được gắn với 01 màn hình
LCD và 01 bàn phím 16 nút.
Nguyên tắc hoạt động:
1. Khi user gõ vào 1 chữ hoặc 1 chuỗi kí tự trên máy tính và bấm nút Send thì chữ hoặc chuỗi kí
tự này sẽ hiện lên trên LCD.
2. Khi user nhấn 1 phím bất kì trên bàn phím 16 nút thì kết quả phím nào được nhấn sẽ được hiển thị trên LCD và trên giao diện của chương trình trên máy tính.
15 trang |
Chia sẻ: lethao | Lượt xem: 6641 | Lượt tải: 1
Bạn đang xem nội dung tài liệu Bài tập lớn Giao Tiếp Máy Tính Sử Dụng Chuẩn Truyền RS232, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
TRƯỜNG ĐẠI HỌC BÁCH KHOA TP. HCM
KHOA CƠ KHÍ
Bài tập lớn
KỸ THUẬT GIAO TIẾP MÁY TÍNH
TP. HCM, 12-2010
ĐỀ BÀI
Sử dụng chuẩn truyền RS232, thiết kế mạch giao tiếp giữa cổng COM máy tính và vi điều khiển.
Máy tính: Viết chương trình xuất/nhập dữ liệu để điều khiển các cơ cấu chấp hành được gắn với board vi điều khiển.
Vi điều khiển: Vi điều khiển được gắn với 01 màn hình
LCD và 01 bàn phím 16 nút.
Nguyên tắc hoạt động:
1. Khi user gõ vào 1 chữ hoặc 1 chuỗi kí tự trên máy tính và bấm nút Send thì chữ hoặc chuỗi kí
tự này sẽ hiện lên trên LCD.
2. Khi user nhấn 1 phím bất kì trên bàn phím 16 nút thì kết quả phím nào được nhấn sẽ được hiển thị trên LCD và trên giao diện của chương trình trên máy tính.
PHẦN THỰC HIỆN
1. Cấu trúc cổng nối tiếp
Cổng nối tiếp được sử dụng để truyền dữ liệu hai chiều giữa máy tính và ngoại vi, có các ưu điểm sau:
- Khoảng cách truyền xa hơn truyền song song.
- Số dây kết nối ít.
- Có thể truyền không dây dùng hồng ngoại.
- Có thể ghép nối với vi điều khiển hay PLC (Programmable Logic Device).
- Cho phép nối mạng.
- Có thể tháo lắp thiết bị trong lúc máy tính đang làm việc.
- Có thể cung cấp nguồn cho các mạch điện đơn giản
Các thiết bị ghép nối chia thành 2 loại: DTE (Data Terminal Equipment) và DCE (Data Communication Equipment). DCE là các thiết bị trung gian như MODEM còn DTE là các thiết bị tiếp nhận hay truyền dữ liệu như máy tính, PLC, vi điều khiển, … Việc trao đổi tín hiệu thông thường qua 2 chân RxD (nhận) và TxD (truyền). Các tín hiệu còn lại có chức năng hỗ trợ để thiết lập và điều khiển quá trình truyền, được gọi là các tín hiệu bắt tay (handshake). Ưu điểm của quá trình truyền dùng tín hiệu bắt tay là có thể kiểm soát đường truyền.
Tín hiệu truyền theo chuẩn RS-232 của EIA (Electronics Industry Associations).
Chuẩn RS-232 quy định mức logic 1 ứng với điện áp từ -3V đến -25V (mark), mức logic 0 ứng với điện áp từ 3V đến 25V (space) và có khả năng cung cấp dòng từ 10 mA đến 20 mA.
Ngoài ra, tất cả các ngõ ra đều có đặc tính chống chập mạch. Chuẩn RS-232 cho phép truyền tín hiệu với tốc độ đến 20.000 bps nhưng nếu cáp truyền đủ ngắn có thể lên đến 115.200 bps.
Các phương thức nối giữa DTE và DCE:
- Đơn công (simplex connection): dữ liệu chỉ được truyền theo 1 hướng.
- Bán song công ( half-duplex): dữ liệu truyền theo 2 hướng, nhưng mỗi thời điểm chỉ được truyền theo 1 hướng.
- Song công (full-duplex): số liệu được truyền đồng thời theo 2 hướng.
Định dạng của khung truyền dữ liệu theo chuẩn RS-232 như sau:
Khi không truyền dữ liệu, đường truyền sẽ ở trạng thái mark (điện áp -10V). Khi bắt đầu truyền, DTE sẽ đưa ra xung Start (space: 10V) và sau đó lần lượt truyền từ D0 đến D7 và Parity, cuối cùng là xung Stop (mark: -10V) để khôi phục trạng thái đường truyền. Dạng tín hiệu truyền mô tả như sau (truyền ký tự A):
Tín hiệu truyền của ký tự ‘A’
Các đặc tính kỹ thuật của chuẩn RS-232 như sau:
Các tốc độ truyền dữ liệu thông dụng trong cổng nối tiếp là: 1200 bps, 4800 bps, 9600 bps và 19200 bps.
Sơ đồ chân cổng nối tiếp
Cổng COM có hai dạng: đầu nối DB25 (25 chân) và đầu nối DB9 (9 chân) mô tả như hình trên. Ý nghĩa của các chân mô tả như sau:
2. Truyền thông giữa hai nút
Các sơ đồ khi kết nối dùng cổng nối tiếp:
Kết nối đơn giản trong truyền thông nối tiếp
Khi thực hiện kết nối như trên, quá trình truyền phải bảo đảm tốc độ ở đầu phát và thu giống nhau. Khi có dữ liệu đến DTE, dữ liệu này sẽ được đưa vào bộ đệm và tạo ngắt. Ngoài ra, khi thực hiện kết nối giữa hai DTE, ta còn dùng sơ đồ sau:
Kết nối trong truyền thông nối tiếp dùng tín hiệu bắt tay
Khi DTE1 cần truyền dữ liệu thì cho DTR tích cực ( tác động lên DSR của DTE2 cho biết sẵn sàng nhận dữ liệu và cho biết đã nhận được sóng mang của MODEM (ảo). Sau đó, DTE1 tích cực chân RTS để tác động đến chân CTS của DTE2 cho biết DTE1 có thể nhận dữ liệu. Khi thực hiện kết nối giữa DTE và DCE, do tốc độ truyền khác nhau nên phải thực hiện điều khiển lưu lượng. Quá trinh điều khiển này có thể thực hiện bằng phần mềm hay phần cứng. Quá trình điều khiển bằng phần mềm thực hiện bằng hai ký tự Xon và Xoff. Ký tự Xon được DCE gởi đi khi rảnh (có thể nhận dữ liệu). Nếu DCE bận thì sẽ gởi ký tự Xoff. Quá trình điều khiển bằng phần cứng dùng hai chân RTS và CTS. Nếu DTE muốn truyền dữ liệu thì sẽ gởi RTS để yêu cầu truyền, DCE nếu có khả năng nhận dữ liệu (đang rảnh) thì gởi lại CTS.
3. Truy xuất trực tiếp thông qua cổng:
Các cổng nối tiếp trong máy tính được đánh số là COM1, COM2, COM3, COM4 với các địa chỉ như sau:
Một số giá trị thông dụng xác định tốc độ truyền cho như sau:
SBCB (Set Break Control Bit) =1: cho phép truyền tín hiệu Break (=0) trong khoảng thời gian lớn hơn một khung
PS (Parity Select):
STB (Stop Bit) = 0: 1 bit stop, =1: 1.5 bit stop (khi dùng 5 bit dữ liệu) hay 2 bit stop (khi dùng 6, 7, 8 bit dữ liệu).
WLS (Word Length Select):
4. Giao tiếp với vi điều khiển
Khi thực hiện giao tiếp với vi điều khiển, ta phải dùng thêm mạch chuyển mức logic từ TTL Æ 232 và ngược lại. Các vi mạch thường sử dụng là MAX232 của Maxim hay DS275 của Dallas. Mạch chuyển mức logic mô tả như sau:
Mạch chuyển mức logic TTL ↔ RS232
Tuy nhiên, khi sử dụng mạch chuyển mức logic dùng các vi mạch thì đòi hỏi phải dùng chung GND giữa máy tính và vi mạch ( có khả năng làm hỏng cổng nối tiếp khi xảy ra hiện tượng chập mạch ở mạch ngoài. Do đó, ta có thể dùng thêm opto 4N35 để cách ly về điện. Sơ đồ mạch cách ly mô tả như sau:
Mạch chuyển mức logic TTL ↔ RS232 cách ly
Khi giao tiếp, vi điều khiển chính là một DTE nên sẽ nối RxD của máy tính với TxD của vi điều khiển và ngược lại.
Mạch kết nối giữa vi điều khiển và máy tính như sau:
Trong sơ đồ mạch trên ở 2 chân 25,26 được nối với max232 để giao tiếp với máy tính.
Code chương trình điều khiển:
#include
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=pin_c6,rcv=pin_c7)
#include
//#include
char const kitu[]=" 1234567890*#";
int key=0,vitri=0;
int k=10;
int ram[16];
void memory(int value,vitri)
{
ram[vitri]=value;
}
#INT_TIMER1
void SendData()
{
char c;
fprintf("Online\n\r");
putc(c);
delay_ms(100);
}
#INT_RDA
VOID RECEVICE()
{
char y;
y=getc();
fprintf(y);
}
void quet()
{ int b=10;
while(1)
{
output_d(0);
output_high(pin_D5);
if (input(PIN_D1)) {key=1;break;}
if (input(PIN_D2)) { key=4;break;}
if (input(PIN_D3)) { key=7;break;}
if (input(PIN_D4)) { key=11;break;}
output_d(0);
output_high(pin_D6);
if (input(PIN_D1)) { key=2;break;}
if (input(PIN_D2)) { key=5;break;}
if (input(PIN_D3)) { key=8;break;}
if (input(PIN_D4)) { key=10;break;}
output_d(0);
output_high(pin_D7);
if (input(PIN_D1)) { key=3;break;}
if (input(PIN_D2)) { key=6;break;}
if (input(PIN_D3)) { key=9;break;}
if (input(PIN_D4)) { key=12;break;}
b--;
}
}
void main()
{
enable_interrupts(global);
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER1);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(15536);
lcd_init();
while(true)
{
quet();
lcd_putc(kitu[key]);
delay_ms(15);
}
}
5. Thiết kế giao diện trên máy tính
Ta sử dụng ngôn ngữ lập trình C# để thiết kế giao diện.
Đầu tiên, ta tạo 1 giao diện (form) như sau:
Và đây là code của giao diện trên:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace RS232
{
public partial class Form1 : FORM
{
private int[] values = new int[200];
private int count = 0;
private int maxVal = 200;
public Form1()
{
InitializeComponent();
}
private void Form1_Load_1(object sender, EventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
serialPort1.Open();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
}
private void btnWrite_Click(object sender, EventArgs e)
{
byte data = (byte)Convert.ToInt16(txtWrite.Text, 10);
serialPort1.Write(new byte[] { data }, 0, 1);
drawLine();
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte nhan = (byte)serialPort1.ReadByte();
object[] para = { nhan };
txtRead.BeginInvoke(new deleFunc(Display), para);
}
//----------Hàm con hiển thị dữ liệu-----------------------
private delegate void deleFunc(byte nhan);
private void Display(byte nhan)
{
string receive = Convert.ToString(nhan, 10);
txtRead.AppendText(receive + " ");
values[count++] = (int)nhan;
redraw();
}
private void txtWrite_TextChanged(object sender, EventArgs e)
{
}
private void btnClear_Click(object sender, EventArgs e)
{
txtRead.Text = " ";
}
// hàm ve do thi
private void redraw()
{
Graphics g = panel1.CreateGraphics();
int width = panel1.Width;
int height = panel1.Height;
int space = 10;
g.FillRectangle(Brushes.White, 0, 0, width, height);
g.DrawRectangle(Pens.Black, space, space, width - space * 2, height - space * 2);
double yFactor = (height - space) / (maxVal + 1.0f);
g.SmoothingMode = SmoothingMode.HighQuality;
float x, y, lastX, lastY;
y = (float)((maxVal - (float)Int32.Parse(txtWrite.Text)) * yFactor);
g.DrawLine(Pens.DarkBlue, space, y, width - space, y);
//-------------Vẽ các vạch trục Y--------------------//
float yFactorDefault = (height - space * 2) / 20;
for (float j = 0; j <= 20; j++)
{
g.DrawLine(Pens.Black, space, space + j * yFactorDefault, space / 2, space + j * yFactorDefault);
}
//-------------Vẽ các vạch trục X--------------------//
float xFactorDefault = (float)(width - space * 2) / 100;
for (float jj = 0; jj <= 100; jj++)
{
g.DrawLine(Pens.Black, space + jj * xFactorDefault, height - space, space + jj * xFactorDefault, height - space / 2);
}
//--------------------------------------------------//
double step = (double)(width - space / 2) / values.Length;
lastX = (float)space;
lastY = (float)(yFactor * (maxVal - values[0]));
for (int i = 1; i < count; i++)
{
x = (float)(space + i * step);
y = (float)(yFactor * (maxVal - values[i]));
g.DrawLine(Pens.DarkBlue, lastX, lastY, x, y);
lastX = x;
lastY = y;
}
g.Dispose();
}
private void drawLine()
{
Graphics g = panel1.CreateGraphics();
int width = panel1.Width;
int height = panel1.Height;
float space = 5;
g.FillRectangle(Brushes.White, 0, 0, width, height);
g.DrawRectangle(Pens.Black, space, space, width - space * 2, height - space * 2);
double yFactor = (height - space) / (maxVal + 1.0f);
g.SmoothingMode = SmoothingMode.HighQuality;
float y = (float)((maxVal - (float)Int32.Parse(txtWrite.Text)) * yFactor);
g.DrawLine(Pens.DarkBlue, space, y, width - space, y);
g.Dispose();
}
private void panel1_LocationChanged(object sender, EventArgs e)
{
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void textBox13_TextChanged(object sender, EventArgs e)
{
}
private void textBox15_TextChanged(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
}
}