Professional Documents
Culture Documents
Mục lục
Lời nói đầu Trang
Chương I – Mục tiêu và nhiệm vụ của đề tài
1.1- Đặt vấn đề 6
1.2- Mục tiêu của đề tài 6
1.3- Nhiệm vụ của đề tài 6
Chương II– Tổng quan về mạng Ethernet
2.1-Kiến trúc giao thức 7
2.2-Cấu trúc mạng và kỹ thuật truyền dẫn 8
2.3-Cơ chế giao tiếp 9
2.4-Cấu trúc bức điện 10
2.5-Truy nhập bus 11
2.6-Chuẩn IEEE 802
14
Chương III– Các phương thức truyền tin dựa theo chuẩn Ethernet
3.1-Họ giao thức TCP/IP 17
3.2-Cấu trúc gói tin IP,TCP,UDP
3.2.1 Cấu trúc địa chỉ IP 21
3.2.2 Cấu trúc gói tin IP 22
3.2.3 Cấu trúc gói tin TCP và quá trình kết nối của giao
thức TCP 24
3.2.4 Cấu trúc gói tin UDP
28 3.3-Cấu trúc phần cứng, phần mềm
3.3.1 Vi điều khiển 29
3.3.2 Thiết bị ghép nối Ethernet với vi điều khiển 44
3.3.3 Một số thành phần khác 49
Chương IV– Mô hình ứng dụng sử dụng Ethernet
4.1- Phần cứng
mikroC 51
4.2.2 Các hàm API dùng cho PC 54
4.3- Một số kết quả thực hiện được 58
Chương V– Kết luận và hướng phát triển của đề tài
5.1-Đánh giá kết quả thực hiện đồ án 63
5.2- Hướng phát triển của đồ án 63
Tài liệu tham khảo 64
Phụ lục 65
Ethernet là kiểu mạng cục bộ (LAN) được sử dụng rộng rãi nhất hiện nay.
Thực chất, Ethernet chỉ là mạng cấp dưới (lớp vật lý và một phần lớp liên kết dữ
liệu), vì vậy có thể sử dụng các giao thức khác nhau ở phía trên, trong đó TCP/IP
là tập giao thức được sử dụng phổ biến nhất. Tuy vậy, mỗi nhà cung cấp sản phẩm
có thể thực hiện giao thức riêng hoặc theo một chuẩn quốc tế cho giải pháp của
mình trên cơ sở Ethernet. High Speed Ethernet (HSE) của Fieldbus Foundation
chính là một trong tám hệ bus trường được chuẩn hóa quốc tế theo IEC 61158.
Ethernet có xuất xứ là tên gọi một sản phẩm của công ty Xerox, được sử
dụng đầu tiên vào năm 1975 để nối mạng 100 trạm máy tính với cáp đồng trục dài
1km, tốc độ truyền 2,94 Mbit/s và áp dụng phương pháp truy nhập bus
CSMA/CD. Từ sự thành công của phương pháp này, Xerox đã cùng DEC và Intel
đã xây dựng một chuẩn 10 Mbit/s- Ethernet. Chuẩn này chính là cơ sở cho IEEE
802.3 sau này. Đặc biệt, với phiên bản 100 Mbit/s (Fast Ethernet, IEEE 802.3u),
Ethernet ngày càng đóng một vai trò quan trọng trong các hệ thống công nghiệp.
Bên cạnh việc sử dụng cáp đồng trục, đôi dây xoắn và cáp quang, gần đây
Ethernet không dây (Wireless LAN, IEEE 802.11) cũng đang thu hút được sự
quan tâm lớn.
2.1 Kiến trúc giao thức
Kiến trúc giao thức của Ethernet theo chuẩn IEEE 802.3 chỉ bao gồm lớp
vật lí và lớp MAC (Medium Access Control, lớp điều khiển truy nhập môi
trường).
phát. Một số bộ thu phát cho phép nối tới tám trạm qua các cổng khác nhau, nhờ
vậy tiết kiệm được số lượng bộ nối cũng như công lắp đặt.
Với 10BASE2, card giao diện mạng được nối với cáp đồng trục thông qua
bộ nối thụ động BNC hình chữ T. Bộ thu phát được tích hợp trong bảng mạch điện
tử của module giao diện mạng bên trong máy tính. Như vậy, mỗi trạm có một bộ
thu phát riêng biệt.
Về bản chất, cả hai kiểu dây với cáp đồng trục như nói trên đều thực hiện
cấu trúc bus ( vật lí cũng như logic), vì thế có ưu điểm là tiết kiệm dây. Tuy nhiên,
các lỗi phần cứng như đứt cáp, lỏng bộ phận nối rất khó phát hiện trực tuyến. Mặc
dù đã có một số biện pháp khắc phục, phương pháp tin cậy hơn là sử dụng cấu trúc
hình sao với một bộ chia ( hub) hoặc một bộ chuyển mạch ( switch ). Cấu trúc này
thông thường được áp dụng với cáp đôi dây xoắn, nhưng cũng áp dụng được với
cáp đồng trục ( ví dụ Industrial Ethernet).
Đa số cấu hình mạng Ethernet có kết nối với thiết bị điều khiển thường sử
dụng chuẩn chung 10BASE-T. Trong mạng này các trạm được nối với nhau qua
một bộ chia giống như cách nối các mạng điện thoại.
Ưu điểm của cấu trúc này là việc bổ xung hoặc tách một trạm ra khỏi mạng
cũng như việc phát hiện cáp truyền rất đơn giản.
Nhược điểm có thể thấy rõ nhất đó là tốn dây dẫn và công đi dây cũng như
chi phí cho bộ chia chất lượng cao cũng là một vấn đề. Bên cạnh đó, khoảng cách
tối đa cho phép từ một trạm tới bộ chia thường bị hạn chế trong vòng 100 – 150m.
Bên cạnh cáp đồng trục và cáp đôi dây xoắn thì cáp quang cũng được sử
dụng nhiều trong Ethernet, trong đó đặc biệt là 10BASE-F. Với cách ghép nối duy
nhất là điểm – điểm, cấu trúc mạng có thể là daisy-chain, hình sao hoặc hình cây.
Thông thường, chi phí cho các bộ nối và chặn đầu cuối rất lớn nhưng khả năng
kháng nhiễu tốt và tốc độ truyền cao lá các yếu tố quyết định trong nhiều phạm vi
ứng dụng.
Trong nhiều trường hợp, ta có thể sử dụng phối kết hợp nhiều loại trong
một mạng Ethernet. Ví dụ, cáp quang hoặc cáp đồng trục dầy có thể sử dụng là
đường trục chính hay xương sống ( backbone ) trong cấu trúc cây, với các đường
nhánh là cáp mỏng hoặc đôi dây xoắn. Đối với mạng quy mô lớn, có thể sử dụng
các bộ lặp, nhưng đường dẫn giữa hai bộ thu phát không được phép dài quá 2,5km
cũng như không đi qua quá bốn bộ lặp.
Mở đầu (Preamble ) của khung MAC là trường 7 byte giống nhau có giá trị
55H, được bên nhận sử dụng để đồng bộ nhịp với bên gửi. Việc đồng bộ hóa chỉ
được thực hiện một lần cho cả bức điện.
Một byte SFD (Start of Frame Delimiter ) chứa dãy bit 10101011, đánh dấu
khởi đầu khung MAC.
Theo 802.3,địa chỉ đích và địa chỉ nguồn có thể là 2 hoặc 6 byte, nhưng
chuẩn qui định cho truyền dải cơ sở 10 Mb/s chỉ sử dụng địa chỉ 6 byte. Bit cao
nhất trong địa chỉ đích có giá trị 0 cho các địa chỉ thông thường và giá trị 1 cho các
địa chỉ nhóm. Đối với các thông báo gửi tới các trạm (broadcast), tất cả các bit
trong địa chỉ đích sẽ là 1.
Có hai loại địa chỉ Ethernet là các địa chỉ cục bộ và các địa chỉ toàn cầu,
được phân biệt bởi bit 46 (bit gần cao nhất). Các địa chỉ cục bộ có thể đổ cứng
hoặc đặt bằng phần mềm và không có ý nghĩa ngoài mạng cục bộ. Ngược lại, một
địa chỉ toàn cầu được IEEE cấp phát, luôn được đổ cứng trong vi mạch để đảm
bảo sự thống nhất trên toàn thế giới. Với 46 bit có thể có tổng cộng 7* 1013 địa chỉ
cục bộ. Tuy nhiên số lượng các trạm cho phép trong một hệ thống mạng công
nghiệp còn phụ thuộc vào kiểu cáp truyền, giao thức phía trên cũng như đặc tính
của các thiết bị tham gia mạng.
Một sự khác nhau giữa Ethernet và IEEE 802.3 là ý nghĩa ô tiếp sau phần
địa chỉ. Theo đặc tả Ethernet, hai byte này chứa mã giao thức chuyển gói phía trên.
Cụ thể, mã 0800 chỉ giao thức IP (Internet Protocol ) và mã 0806 chỉ giao thức
ARP (Address Resolution Protocol ). Theo chuẩn IEEE 802.3, ô này dùng để chỉ
số byte dữ liệu ( từ 0 đến 1500). Với điều kiện ràng buộc giữa tốc độ truyền v (tính
bằng bit/s), chiều dài bức điện n và khoảng cách truyền l (tính bằng mét) của
phương pháp CSMA/CD
lv < 100.000.000 n.
để đảm bảo tốc độ truyền 10Mbit/s và khoảng cách truyền 2500m thì một
bức điện phải dài hơn 250 bit hay 32 byte. Xét tới cả thời gian trễ qua bốn bộ lặp,
chuẩn 802.3 qui định chiều dài khung tối thiểu là 64 byte (51,2us), không kể phần
mở đầu và byte SFD. Như vậy ô dữ liệu phải có chiều dài tối thiểu là 46 byte.
Trong trường hợp dữ liệu thực ngắn hơn 46 byte, ô PAD (Padding ) được sử dụng
để lấp đầy.
Ô cuối cùng trong khung MAC là FCS ( Frame Check Sequence) gồm 4
byte chứa mã CRC (Cyclic Redundancy Check) với đa thức phát
G(x) = x 32 + x 26 + x 23 + x 22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
Phần thông tin kiểm soát lỗi bao gồm các ô địa chỉ, ô chiều dài, ô dữ liệu.
định tới hiệu suất của hệ thống là thuật toán tính thời gian truy nhập lại cho các
trạm trong trường hợp xảy ra xung đột.
Một tình huống xảy ra xung đột tiêu biểu và cách khắc phục được minh họa
trên hình ….. Trạm A và C cùng nghe đường dẫn. Đường dẫn rỗi nên A có thể gửi
trước. Trong khi tín hiệu từ trạm A gửi đi chưa kịp tới nên trạm C không hay biết
và cũng gửi, gây ra xung đột tại một điểm gần C. A và C sẽ lần lượt nhận được tín
hiệu phản hồi, so sánh với tín hiệu gửi đi và phát hiện xung đột. Cả hai trạm sẽ
cùng phải hủy bỏ bức điện đã gửi đi bằng cách không phát tiếp, các trạm muốn
nhận sẽ không nhận được cờ hiệu kết thúc bức điện và sẽ coi như bức điện không
hợp lệ. A và C cũng có thể gửi đi một tín hiệu “ jam” đặc biệt để báo cho các trạm
cần nhận biết. Sau đó mỗi trạm sẽ chờ một thời gian chờ ngẫu nhiên, trước khi thử
phát lại. Thời gian chờ ngẫu nhiên ở đây tuy nhiên phải được tính theo một thuật
toán nào đó để sao cho thời gian chờ ngắn một cách hợp lí và không giống nhau
giữa các trạm cùng chờ. Thông thường thời gian chờ này là bội số của hai lần thời
gian lan truyền tín hiệu Ts.
Ưu điểm của CSMA/CD là tính chất đơn giản, linh hoạt. Khác với các
phương pháp tiền định, việc ghép thêm hay bỏ đi một trạm trong mạng không ảnh
hưởng gì tới hoạt động của hệ thống. Chính vì vậy, phương pháp này được áp
dụng rộng rãi trong mạng Ethernet.
Nhược điểm của CSMA/CD là tính chất bất định của thời gian phản ứng.
Các trạm đều bình đẳng như nhau nên quá trình chờ ở một trạm có thể lặp đi lặp
lại, không xác định được tương đối chính xác thời gian. Hiệu suất sử dụng đường
truyền vì thế cũng thấp. Rõ ràng, nếu như không kết hợp thêm với các kỹ thuật
khác thì phương pháp này không thích hợp với các cấp thấp, đòi hỏi trao đổi dữ
liệu định kỳ, thời gian thực.
Điều kiện ràng buộc
Khả năng thực hiện phương pháp CSMA/CD bị hạn chế bởi một điều kiện
ràng buộc giữa chiều dài dây dẫn, tốc độ truyền thông và chiều dài bức điện. Chỉ
khi một trạm phát hiện được xung đột xảy ra trong khi bức điện chưa gửi xong
mới có khả năng hủy bỏ bức điện ( có thể chỉ đơn giản bằng cách không gửi tiếp
cờ hiệu kết thúc). Còn nếu bức điện đã được gửi đi xong rồi mới phát hiện xảy ra
xung đột thì đã quá muộn, một trạm khác có thể đã nhận được và xử lí bức điện
với nội dung sai lệch.
Trong trường hợp xấu nhất hai trạm cùng gửi thông tin có thể ở hai đầu của
dây dẫn, trạm thứ hai chỉ gửi bức điện trước khi tín hiệu từ trạm thứ nhất tới một
chút. Tín hiệu bị xung đột xảy ra ở đây phải mất thêm một khoảng thời gian nữa
đúng bằng thời gian lan truyền tín hiệu Ts mới quay trở lại tới trạm thứ nhất. Như
vậy điều kiện thực hiện phương pháp CSMA/CD là thời gian gửi một bức điện
phải lớn hơn hai lần thời gian lan truyền tín hiệu, tức :
( Chiều dài bức điện n/ Tốc độ truyền v) > 2Ts
n/v > 2l/(0,66*300.000.000),
Với l là chiều dài dây dẫn và hệ số k= 0,67
lv < 100.000.000n
Đây chính là điều kiện ràng buộc trong việc nâng cao tốc độ và tăng chiều
dài dây dẫn. Ví dụ đối với một mạng Fast Ethernet (100Mbit/s) có chiều dài 100m
thì một bức điện không thể ngắn hơn 100 bit. Hệ quả của điều kiện rằng buộc này
là hiệu suất truyền thông sẽ rất thấp nếu như dữ liệu cần trao đổi không lớn. Một
lần nữa, ta thấy rằng phương pháp này không thích hợp lắm cho các hệ thống
mạng cấp thấp.
Thời gian lan truyền tín hiệu một lần qua lại đường truyền được gọi là khe
thời gian. Giá trị này được tính cho tối đa 2,5 km đường truyền và bốn bộ lặp là
512 thời gian bit hay 51,2 us. Sau lần xảy ra xung đột đầu tiên, mỗi trạm sẽ chọn
ngẫu nhiên 0 hoặc 1 lần khe thời gian chờ trước khi thử gửi lại. Nếu hai trạm ngẫu
nhiên cùng chọn một khoảng thời gian, hoặc có sự xung đột với một trạm thứ ba,
thì số khe thời gian lựa chọn chờ sẽ là 0, 1, 2 hoặc 3.Sau lần xung đột thứ i , số
khe thời gian chọn ngẫu nhiên nằm trong khoảng từ 0 tới 2i -1. Tuy nhiên, sau
mười lần xung đột, số khe thời gian chờ tối đa sẽ được giữ lại ở con số 1023. Sau
16 lần xung đột liên tiếp, các trạm sẽ coi là lỗi hệ thống và báo trở lại lớp giao
thức phía trên. Thuật toán nổi tiếng này được gọi là Binary Exponential Backoff
(BEB).
cũng nằm ngoài phạm vi của chuẩn này). Con số 802 chỉ đơn giản là con số còn
trống tiếp theo mà IEEE có thể dùng, đôi khi "802" còn được liên hệ với ngày mà
cuộc họp đầu tiên được tổ chức –tháng 2 năm 1980.
Các dịch vụ và giao thức được đặc tả trong IEEE 802 ánh xạ tới hai tầng
thấp (tầng liên kết dữ liệu và tầng vật lý của mô hình 7 tầng OSI. Thực tế, IEEE
802 chia tầng liên kết dữ liệu OSI thành hai tầng con LLC (điều khiển liên kết
lôgic) và MAC (điều khiển truy nhập môi trường truyền), do đó các tầng này có
thể được liệt kê như sau:
• Tầng liên kết dữ liệu
• Tầng con LLC
• Tầng con MAC
• Tầng vật lý
Họ chuẩn IEEE 802 được bảo trì bởi Ban Tiêu chuẩn LAN/MAN IEEE 802
(IEEE 802 LAN/MAN Standards Committee (LMSC)). Các chuẩn được dùng rộng
rãi nhất là dành cho họ Ethernet, Token Ring, mạng LAN không dây, các mạng
LAN dùng bridge và bridge ảo (Bridging and Virtual Bridged LANs). Mỗi lĩnh
vực có một Working Group tập trung nghiên cứu.
Các Working Group:
IEEE 802.1 Các giao thức LAN tầng cao
IEEE 802.2 điều khiển liên kết lôgic
IEEE 802.3 Ethernet
802.3u là chuẩn của FastEthernet
802.3z là chuẩn Gigabit Ethernet
IEEE 802.4 Token bus (đã giải tán)
IEEE 802.5 Token Ring
IEEE 802.6 Metropolitan Area Network (đã giải tán)
IEEE 802.7 Broadband LAN using Coaxial Cable (đã giải tán)
IEEE 802.8 Fiber Optic TAG (đã giải tán)
IEEE 802.9 Integrated Services LAN (đã giải tán)
IEEE 802.10 Interoperable LAN Security (đã giải tán)
IEEE 802.11 Wireless LAN (Wi-Fi certification)
IEEE 802.12 công nghệ 100 Mbit/s plus
IEEE 802.13 (không sử dụng)
Lớp vật lí
Server) là dịch vụ tên miền cho phép nhận ra máy tính từ một tên miền thay cho
chuỗi địa chỉ Internet.
Lớp ứng dụng trao đổi dữ liệu với lớp dưới ( lớp vận chuyển ) qua cổng.
Việc dùng cổng bằng số cho phép giao thức của lớp vận chuyển biết loại nội dung
nào chứa bên trong gói dữ liệu. Những cổng được đánh bằng số và những ứng
dụng chuẩn thường dùng cùng cổng. Ví dụ: giao thức FTP dùng cổng 20 cho dữ
liệu và cổng 21 cho điều khiển, giao thức SMTP dùng cổng 25…
Lớp Internet:
Lớp Internet có chức năng chuyển giao dữ liệu giữa nhiều mạng được liên
kết với nhau. Có một vài giao thức mà làm việc ở lớp Internet như : IP (Internet
Protocol ) có chức năng gán địa chỉ cho dữ liệu trước khi truyền và định tuyến
chúng tới đích, ICMP ( Internet Control Message Protocol ) có chức năng thông
báo lỗi trong trường hợp truyền dữ liệu bị hỏng, ARP ( Address Resolution
Protocol ) có chức năng lấy địa chỉ MAC từ địa chỉ IP.
Với giao thức IP, lớp Internet được sử dụng có nhiệm vụ thêm header tới
gói dữ liệu được nhận từ lớp vận chuyển, là một loại dữ liệu điều khiển khác, nó sẽ
thêm địa chỉ IP nguồn và địa chỉ IP đích – có nghĩa là địa chỉ IP của bên gửi dữ
liệu và bên nhận dữ liệu.
Mỗi datagram của IP có kích thước lớn nhất là 65.535 byte, bao gồm cả
header mà có thể dùng 20 hoặc 24 byte, phụ thuộc vào sự lựa chọn trong chương
trình sử dụng. Như vậy datagram của IP có thể mang 65.515 byte hoặc 65.511
byte, giao thức IP sẽ cắt gói xuống thành nhiều datagram nếu thấy cần thiết.
Đối với mạng Ethernet, dữ liệu có thể lên tới 1500 byte, nghĩa là kích thước
lớn nhất trường dữ liệu của frame được gửi lên mạng MTU ( Maximum Transfer
Unit ) có giá trị 1500 byte. Như vậy hệ điều hành tự động cấu hình giao thức IP để
tạo ra datagram của IP có chiều dài 1500 byte mà không phải là 65.535 byte.
Hình dưới minh họa datagram được tạo ra từ lớp Internet bằng giao thức IP.
Như chúng ta đã đề cập header được giao thức IP thêm vào bao gồm địa chỉ IP
nguồn, địa chỉ IP đích và một vài thông tin điều khiển.
trường truyền dẫn, kiểm soát lỗi và lưu thông dữ liệu. Datagram được tạo từ lớp
Internet sẽ được gửi xuống tới lớp truy nhập mạng nếu truyền dữ liệu, hoặc lớp
truy nhập mạng sẽ lấy dữ liệu từ mạng và gửi nó tới lớp Internet nếu chúng ta nhận
dữ liệu. Như đã đề cập ở phần trên, Ethernet là giao thức cấp dưới có ba lớp LLC (
Logic Link Control ), MAC ( Media Access Control ) và lớp vật lí Physical.
Lớp MAC (điều khiển truy nhập phương tiện truyền thông ) có nhiệm vụ
lắp ráp frame mà sẽ được gửi lên mạng, thêm địa chỉ MAC nguồn và địa chỉ MAC
đích. Địa chỉ MAC là địa chỉ vật lí của cạc mạng. Những frame mà là đích tới
mạng khác sẽ dùng địa chỉ MAC của router như là địa chỉ đích.
Những lớp LLC và MAC sẽ thêm những header của chúng tới datagram mà
nhận được từ lớp Internet. Do đó, cấu trúc đầy đủ của frame được tạo ra từ hai lớp
đó được thể hiện trong hình vẽ dưới
Lớp vận
TCP/IP chuyển
Data
Header
TCP/IP
MAC MAC
LLC header IP header Header Data
header CRC
độ truyền và cấu trúc cơ học của các phích cắm, rắc cắm. Lớp này có nhiệm vụ
chuyển đổi frame do lớp MAC tạo ra thành tín hiệu điện ( đối với hệ thống dây
dẫn mạng bằng cable ) hoặc thành song từ trường ( đối với hệ thống mạng không
dây ).
0 1 2 3 4 8 16 24
Class A 0 Netid Hostid
Class B 1 0 Netid Hostid
Class C 1 1 0 Netid Hostid
Class D 1 1 1 0 Multicast address
Class E 1 1 1 1 0 Reverved for future use
Hình 6: Tổ chức địa chỉ IP.
Địa chỉ lớp A: Lớp A sử dụng byte đầu tiên của 4 byte để đánh địa chỉ
mạng. Như hình trên, nó được nhận ra bởi bit đầu tiên trong byte đầu tiên
của địa chỉ có giá trị 0. 3 bytes còn lại được sử dụng để đánh địa chỉ máy
trong mạng. Có 126 địa chỉ lớp A (được đánh địa chỉ trong byte thứ nhất)
với số máy tính trong mạng là 2563 - 2 = 16.777.214 máy cho mỗi một địa
chỉ lớp A (sử dụng 3 bytes để đánh địa chỉ máy).
Địa chỉ lớp B: Một địa chỉ lớp B được nhận ra bởi 2 bit đầu tiên của byte
thứ nhất mang giá trị 10. Lớp B sử dụng 2 byte đầu tiên của 4 byte để đánh
địa chỉ mạng và 2 byte cuối đánh địa chỉ máy trong mạng. Có 64*256 - 2 =
16.128 địa chỉ mạng lớp B với 65.534 máy cho mỗi một địa chỉ lớp B.
Địa chỉ lớp C: Một địa chỉ lớp C được nhận ra với 3 bit đầu mang giá trị
110. Mạng lớp C sử dụng 3 byte đầu để đánh địa chỉ mạng và 1 byte cuối
đánh địa chỉ máy tính có trong mạng. Có 2.097.152 -2 địa chỉ lớp C, mỗi
địa chỉ lớp C có 254 máy.
Địa chỉ lớp D: Dùng để gửi các IP datagram tới một nhóm các host trên một
mạng.
Địa chỉ lớp E: Dùng để dự phòng và dùng trong tương lai.
Mạng con và mặt nạ:
Mạng Internet sử dụng địa chỉ IP 32 bit và phân chia ra các lớp rất mềm
dẻo, tuy nhiên, với một hệ thống địa chỉ như vậy việc quản lý vẫn rất khó khăn.
Nếu như một mạng được cấp một địa chỉ lớp A thì có nghĩa nó chứa tới
6*1.048.576 máy tính, do vậy người ta dùng mặt nạ bit để phân chia mạng ra
thành những mạng con gọi là Subnet. Subnet mask là một con số 32 bit bao gồm n
bit 1 (thường là các bit cao nhất) dùng để đánh địa chỉ mạng con và m bit 0 dùng
để đánh địa chỉ máy trong mạng con (với n+m=32).
0 16
Network Number Host Number
Network Number Subnet Number Host Number
1111111 11111111 11111111 00000000
Hình 7: Mạng con và mặt nạ.
IHL(IP Header Length)-4bít: chỉ độ dài phần header của gói tin, tính theo
từ 32 bít.
TOS(Type of Service)-1byte: cho biết dịch vụ nào mà gói tin muốn sử dụng
chẳng hạn như độ ưu tiên, thời hạn chậm trễ, năng suất truyền và độ tin
cậy. Cụ thể như sau:
3 bít đầu (Precedence) chỉ quyền ưu tiên gửi gói tin, từ gói tin bình
thường là 0 đến gói tin kiểm soát mạng là 7.
1 bít tiếp theo (Delay) chỉ độ trễ yêu cầu, 0 ứng với gói tin có độ trễ
bình thường, 1 ứng với gói tin có độ trễ thấp.
1 bít tiếp theo (Throughput) chỉ thông lượng yêu cầu sử dụng để
truyền gói tin với lựa chọn truyền trên đường thông suất thấp hay trên
đường thông suất cao, 0 ứng với thông lượng bình thường, 1 ứng với thông
lượng cao.
1 bít tiếp theo (Reliability) chỉ độ tin cậy yêu cầu, 0 ứng với độ tin
cậy bình thường, 1 ứng với độ tin cậy cao.
Total Length-2byte:chỉ độ dài toàn bộ gói tin tính cả phần header, tính theo
đơn vị byte.
Indentification-16 bít: cùng với các tham số khác như Source Address,
Destination Address dùng để định danh duy nhất một gói tin trong thời gian
nó tồn tại trên mạng.
Flags: Các gói tin khi truyền trên đường đi có thể bị phân thành nhiều gói
tin nhỏ. Trường Flags dùng để điều khiển phân đoạn và lắp ghép gói tin. Cụ
thể như sau:
Bít 0: chưa sử dụng, luôn lấy giá trị 0
Bít 1: 0 ứng với gói tin bị phân mảnh, 1 ứng với gói tin không bị
phân mảnh.
Bít 2: 0 ứng với gói tin thuộc phân đoạn cuối cùng của gói tin gốc, 1
ứng với gói tin không phải là phân đoạn cuối cùng của gói tin gốc.
Fragment Offset-13bít: chỉ vị trí của phân đoạn trong gói tin gốc, tính theo
đơn vị 8 byte.
Time To Live-1byte: quy định thời gian tồn tại tính bằng giây của gói tin
trong mạng. Thời gian này được đặt bởi trạm gửi và giảm đi (thường quy
ước là 1) khi gói tin đi qua mỗi router của liên mạng. Một giá trị tối thiểu
phải đủ lớn để mạng hoạt động tốt.
Protocol: Chỉ tầng giao thức kế tiếp sẽ nhận vùng dữ liệu ở trạm đích. TCP
có ứng với giá trị 6, UDP ứng với giá trị 17, 1 ứng với ICMP.
Header Checksum-2byte: Dùng để phát hiện lỗi header của gói tin xảy ra
trong quá trình truyền của nó.
Source IP Address-4byte: Địa chỉ IP của nơi truyền gói tin.
Destination IP Address-4byte: Địa chỉ IP của nơi nhận gói tin.
IP Option-độ dài thay đổi: Khai báo các lựa chọn do người sử dụng yêu
cầu, ví dụ như: mức độ bảo mật, đường mà gói tin được gửi đi, timestamp ở
mỗi router.
Padding-độ dài thay đổi: Dùng để đảm bảo phần header luôn kết thúc ở một
mốc 32 bít.
Data: chứa thông tin lớp trên ,chiều dài thay đổi đến 64Kb.
3.2.3 Cấu trúc gói tin TCP và quá trình kết nối của giao thức TCP
Đơn vị dữ liệu trong TCP được gọi là Segment với cấu trúc như sau:
Source Port-2 byte: số hiệu cổng TCP của trạm nguồn.
Destination Port-2byte: số hiệu cổng TCP của trạm đích.
Sequence number: số hiệu của byte đầu tiên của segment, nếu cờ SYN bật
thì nó là số thứ tự gói ban đầu và byte đầu tiên được gửi có số thứ tự này
cộng thêm 1. Nếu không có cờ SYN thì đây là số thứ tự của byte đầu tiên.
Acknowledgment Number-2byte: nếu cờ ACK bật thì giá trị của trường
chính là số thứ tự gói tin tiếp theo mà bên nhận cần. Báo là nhận tốt các
segment mà trạm đích đã gửi cho trạm nguồn.
Data offset-4bit: độ dài của phần header tính theo đơn vị từ 32 bit. Tham số
này chỉ ra vị trí bắt đầu của nguồn dữ liệu.
Reserved-6 bít.
Flags: các bít điều khiển
URG: Vùng con trỏ khẩn (Urgent pointer) có hiệu lực
ACK: Vùng báo nhận ACK number có hiệu lực
PSH: Chức năng PUSH
RST: khởi động lại liên kết
Quá trình thiếp lập kết nối của giao thức TCP:
Không giống như giao thức UDP-giao thức có thể lập tức gửi mà không cần
thiết lập kết nối, TCP đòi hỏi phải thiết lập kết nối trước khi bắt đầu gửi dữ liệu và
kết thúc kết nối khi việc gửi dữ liệu hoàn tất. Cụ thể các kết nối của TCP có 3 pha
là :thiết lập kết nối, truyền dữ liệu và kết thúc kết nối.
Các trạng thái của kết nối:
LISTEN: đang đợi yêu cầu kết nối từ một TCP và cổng bất kỳ ở xa (trạng thái này
thường do các TCP server đặt).
SYN-SENT: đang đợi TCP ở xa gửi một gói tin TCP với các cờ SYN và ACK
được bật (trạng thái này thường do các TCP client cài đặt).
SYN-RECEIVED: đang đợi TCP ở xa gửi lại một tin báo nhận sau khi đã gửi cho
TCP ở xa đó một tin báo nhận kết nối(connnection acknowledgment)(thường do
TCP server đặt).
ESTABLISHED: cổng đã sẵn sàng nhận/gửi dữ liệu với TCP ở xa (đặt bởi TCP
client và server).
TIME-WAIT: đang đợi qua đủ thời gian để chắc chắn là TCP ở xa nhận được đã
nhận được tin báo nhận về yêu cầu kết thúc kết nối của nó. Một kết nối có thể ở
trạng thái TIME-WAIT trong vòng tối đa 4 phút.
Hình 8: Quá trình thiết lập kết nối của giao thức TCP.
Truyền dữ liệu:
Một số đặc điểm cơ bản của TCP để phân biệt với UDP:
thứ 2 trong mô hình OSI. Tuy nhiên điều này không có nghĩa là trường kiểm tra
tổng của TCP là không cần thiết: thống kê cho thấy các sai sót do cả phần cứng và
phần mềm gây ra giữa các điểm áp dụng kỹ thuật kiểm tra CRT là khá phổ biến và
kỹ thuật kiểm tra tổng có khả năng phát hiện phần lớn các lỗi đơn giản này.
Điểm cuối cùng là khả năng hạn chế tắc nghẽn. Tin báo nhận (hoặc không
có tin báo nhận) là tín hiệu về trạng thái đường truyền giữa 2 máy tính. Từ đó, hai
bên có thể thay đổi tốc độ truyền nhận dữ liệu cho phù hợp với điều kiện. Vấn đề
này thường được đề cập là điều kiển lưu lượng, kiểm soát tắc nghẽn. TCP sử dụng
một số cơ chế nhằm đạt được hiệu suất cao và ngăn ngừa khả năng nghẽn mạng.
Các cơ chế này bao gồm: cửa sổ trượt (sliding window), thuật toán slow-start,
thuật toán tránh nghẽn mạng (congestion avoidance), thuật toán truyền lại và phục
hồi nhanh,… Hiện nay, vấn đề cải tiến TCP trong môi trường truyền dẫn tốc độ
cao đang là hướng nghiên cứu được quan tâm.
Kích thước cửa sổ TCP là chiều dài (byte) của khối dữ liệu có thể lưu trong
bộ đệm bên nhận. Bên gửi chỉ có thể gửi tối đa lượng thông tin chứa trong cửa sổ
này trước khi nhận được tin báo nhận.
Dãn kích thước cửa sổ: Để tận dụng khả năng truyền dẫn của mạng thì cửa
sổ dùng trong TCP cần được tăng lên. Trường điều khiển kích thước cửa sổ của
gói tin TCP có độ dài 2 byte do đó kích thước tối đa của cửa sổ là 65535 byte. Do
trường điều khiển không thể thay đổi nên người ta sử dụng một hệ số dãn nào đó.
Hệ số này được định nghĩa trong RFC1323 có thể tăng kích thước tối đa của cửa
sổ lên tới 1GB. Việc tăng kích thước cửa sổ chỉ được dùng trong giao thức bắt tay
3 pha. Giá trị của trường co dãn cửa sổ thể hiện số bít cần được dịch trái đối với
trường kích thước cửa sổ. Hệ số dãn có thể thay đổi từ 0 (không dãn) đến 14 (dãn
tối đa).
Kết thúc kết nối
Để kết thúc kết nối hai bên sử dụng quá trình bắt tay 4 bước và chiều của
kết nối kết thúc độc lập với nhau. Khi một bên muốn kết thúc, nó gửi đi một gói
tin FIN và bên kia gửi lại tin báo nhận ACK. Vì vậy, một quá trình kết thúc tiêu
biểu sẽ có 2 cặp gói tin trao đổi. Một kết nối có thể tồn tại ở dạng nửa mở: một
bên đã kết thúc gửi dữ liệu nên chỉ nhận thông tin, bên kia tiếp tục gửi.
Bên cạnh đó là một vài đặc tính khác của vi điều khiển như:
• Bộ nhớ flash với khả năng ghi xóa được 100.000 lần.
• Bộ nhớ EEPROM với khả năng ghi xóa được 1.000.000 lần.
• Dữ liệu bộ nhớ EEPROM có thể lưu trữ trên 40 năm.
• Khả năng tự nạp chương trình với sự điều khiển của phần mềm.
• Nạp được chương trình ngay trên mạch điện ICSP (In Circuit Serial
Programming) thông qua 2 chân.
• Watchdog Timer với bộ dao động trong.
• Chức năng bảo mật mã chương trình.
• Chế độ Sleep.
• Có thể hoạt động với nhiều dạng Oscillator khác nhau.
Hình 10: Sơ đồ khối cấu trúc của vi điều khiển PIC 16F877A.
Cấu trúc bộ nhớ của vi điều khiển PIC16F877A bao gồm bộ nhớ chương
trình (Program memory) và bộ nhớ dữ liệu (Data Memory).
Bộ nhớ chương trình :
Bộ nhớ chương trình của vi điều khiển PIC16F877A là bộ nhớ flash, dung
lượng bộ nhớ 8K word (1 word = 14 bit) và được phân thành nhiều trang (từ page
0 đến page 3) .Như vậy bộ nhớ chương trình có khả năng chứa được 8*1024 =
8192 lệnh (một lệnh sau khi mã hóa sẽ có dung lượng 1 word -14 bit).
Để mã hóa được địa chỉ của 8K word bộ nhớ chương trình, bộ đếm chương
trình có dung lượng 13 bit (PC<12:0>).
Khi vi điều khiển được reset, bộ đếm chương trình sẽ chỉ đến địa chỉ 0000h
(Reset vector). Khi có ngắt xảy ra, bộ đếm chương trình sẽ chỉ đến địa chỉ 0004h
(Interrupt vector).
Bộ nhớ chương trình không bao gồm bộ nhớ stack và không được địa chỉ
hóa bởi bộ đếm chương trình.
GPR (General Purpose Register) nằm ở vùng địa chỉ còn lại trong bank.
Các thanh ghi SFR thường xuyên được sử dụng (ví dụ như thanh ghi STATUS) sẽ
được đặt ở tất cả các bank của bộ nhớ dữ liệu giúp thuận tiện trong quá trình truy
xuất và làm giảm bớt lệnh của chương trình. Sơ đồ cụ thể của bộ nhớ dữ liệu
PIC16F877A ở trên.
Timer 0
Đây là một trong ba bộ đếm hoặc bộ định thời của vi điều khiển
PIC16F877A.
Timer 0 là bộ đếm 8 bit được kết nối với bộ chia tần số (prescaler) 8 bit.
Cấu trúc của Timer0 cho phép ta lựa chọn xung clock tác động và cạnh tích cực
của xung clock. Ngắt Timer 0 sẽ xuất hiện khi Timer 0 bị tràn. Bit TMR0IE
(INTCON<5>) là bit điều khiển của Timer0. TMR0IE=1 cho phép ngắt Timer0
tác động, TMR0IF= 0 không cho phép ngắt Timer 0 tác động. Sơ đồ khối của
Timer 0 như trên.
Muốn Timer 0 hoạt động ở chế độ Timer ta xoá bit TOSC
(OPTION_REG<5>), khi đó giá trị thanh ghi TMR0 sẽ tăng theo từng chu kì xung
đồng hồ (tần số vào Timer 0 bằng ¼ tần số oscillator). Khi giá trị thanh ghi TMR0
từ FFh trở về 00h, ngắt Timer0 sẽ xuất hiện. Thanh ghi TMR0 cho phép ghi và
xóa được giúp ta ấn định thời điểm ngắt Timer0 xuất hiện một cách linh động.
Muốn Timer0 hoạt động ở chế độ counter ta set bit TOSC
(OPTION_REG<5>). Khi đó xung tác động lên bộ đếm được lấy từ chân
RA4/TOCK1. Bit TOSE (OPTION_REG<4>) cho phép lựa chọn cạnh tác động
vào bột đếm. Cạnh tác động sẽ là cạnh lên nếu TOSE=0 và cạnh tác động sẽ là
cạnh xuống nếu TOSE=1.
Khi thanh ghi TMR0 bị tràn, bit TMR0IF (INTCON<2>) sẽ được set. Đây
chính là cờ ngắt của Timer 0. Cờ ngắt này phải được xóa bằng chương trình trước
khi bộ đếm bắt đầu thực hiện lại quá trình đếm. Ngắt Timer 0 không thể “đánh
thức” vi điều khiển từ chế độ sleep.
Bộ chia tần số (prescaler) được chia sẻ giữa Timer 0 và WDT (Watchdog
Timer). Điều đó có nghĩa là nếu prescaler được sử dụng cho Timer 0 thì WDT sẽ
không có được hỗ trợ của prescaler và ngược lại. Prescaler được điều khiển bởi
thanh ghi OPTION_REG. Bit PSA (OPTION_REG<3>) xác định đối tượng tác
động của prescaler. Các bit PS2:PS0 (OPTION_REG<2:0>) xác định tỉ số chia tần
số của prescaler.
Các lệnh tác động lên giá trị thanh ghi TMR0 sẽ xóa chế độ hoạt động của
prescaler. Khi đối tượng tác động là Timer 0, tác động lên giá trị thanh ghi TMR0
sẽ xóa prescaler nhưng không làm thay đổi đối tượng tác động của prescaler. Khi
đối tượng tác động là WDT, lệnh CLRWDT sẽ xóa prescaler, đồng thời prescaler
sẽ ngưng tác vụ hỗ trợ cho WDT.
Timer 1
Timer 1 là bộ định thời 16 bit, giá trị của Timer 1 sẽ được lưu trong hai
thanh ghi (TMR1H:TMR1L). Cờ ngắt của Timer1 là bit TMR1IF (PIR1<0>). Bit
điều khiển của Timer1 sẽ là TMR1IE (PIE<0>). Tương tự như Timer0, Timer1
cũng có hai chế độ hoạt động: chế độ định thời (timer) với xung kích là xung clock
của oscillator (tần số của timer bằng ¼ tần số của oscillator) và chế độ đếm
(counter) với xung kích là xung phản ánh các sự kiện cần đếm lấy từ bên ngoài
thông qua chân RC0/T1OSO/T1CKI (cạnh tác động là cạnh lên). Việc lựa chọn
chế độ hoạt động nào sẽ được điều khiển bởi TMR1CS ( T1CON<1>).
Ngoài ra Timer 1 còn có chức năng reset input bên trong được điều khiển
bởi một trong hai khối CCP ( Capture/ Compare/ PMW ). Timer 1 có hai chế độ
đếm là đồng bộ ( Synchronous) và dị bộ ( Asynchronous). Chế độ đếm được quyết
định bởi bit điều khiển T1SYNC (T1CON <2>).
Timer 2
00h. Khi reset thanh ghi PR2 được nhận giá trị mặc định FFh.
Ngõ ra của Timer 2 được đưa qua bộ chia tần số postscaler với các mức
chia từ 1:1 đến 1:16. Postscaler được điều khiển bởi 4 bit T2OUTPS3:T2OUTPS0.
Ngõ ra của postscaler đóng vai trò quyết định trong việc điều khiển cờ ngắt.
Ngoài ra ngõ ra của Timer2 còn được kết nối với khối SSP, do đó Timer2
còn đóng vai trò tạo ra xung clock đồng bộ cho khối giao tiếp SSP.
MSSP
MSSP ( Master Synchronous Serial Port) là giao diện đồng bộ nối tiếp dùng
để giao tiếp với các thiết bị ngoại vi (EEPROM, ghi dịch, chuyển đổi ADC,…)
hay các vi điều khiển khác. MSSP có thể hoạt động dưới hai dạng giao tiếp:
SPI ( Serial Pheripheral Interface ).
I2C ( Inter-Intergrated Circuit ).
Các thanh ghi điều khiển chuẩn giao tiếp này bao gồm thanh ghi trạng thái
SSPSTAT và hai thanh ghi điều khiển SSPCON và SSPCON2. Tùy theo chuẩn
giao tiếp được sử dụng (SPI hay I2C) mà chức năng các thanh ghi này được thể
hiện khác nhau.
Chuẩn giao tiếp SPI cho phép truyền nhận đồng bộ. Ta cần sử dụng 4 pin
cho chuẩn giao tiếp này:
RC5/SDO: ngõ ra dữ liệu dạng nối tiếp (Serial Data output).
RC4/SDI/SDA: ngõ vào dữ liệu dạng nối tiếp (Serial Data Input).
RC3/SCK/SCL: xung đồng bộ nối tiếp (Serial Clock).
RA5/AN4/SS/C2OUT: chọn đối tượng giao tiếp (Serial Select) khi giao
tiếp ở chế độ Slave mode.
Các thanh ghi liên quan đến MSSP khi hoạt động ở chuẩn giao tiếp SPI bao
gồm:
Thanh ghi điều khiển SSPCON, thanh ghi này cho phép đọc và ghi.
Thanh ghi trạng thái SSPSTAT, thanh ghi này chỉ cho phép đọc và ghi ở 2
bit trên, 6 bit còn lại chỉ cho phép đọc.
Thanh ghi đóng vai trò là buffer truyền nhận SSPBUF, dữ liệu truyền đi
hoặc nhận được sẽ được đưa vào tranh ghi này. SSPBUF không có cấu trúc
đệm hai lớp (doubled-buffer), do đó dữ liệu ghi vào thanh ghi SSPBUF sẽ
lập tức được ghi vào thanh ghi SSPSR.
Thanh ghi dịch dữ liệu SSPSR dùng để dịch dữ liệu vào hoặc ra. Khi 1 byte
dữ liệu được nhận hoàn chỉnh, dữ liệu sẽ từ thanh ghi SSPSR chuyển qua
thanh ghi SSPBUF và cờ hiệu được set, đồng thời ngắt sẽ xảy ra.
Khi sử dụng chuẩn giao tiếp SPI trước tiên ta cần thiết lập các chế độ cho
giao diện bằng cách đưa các giá trị thích hợp vào hai thanh ghi SSPCON và
SSPSTAT. Các thông số cần thiết lập bao gồm:
+ Master mode hay Slave mode. Đối với Master mode, xung clock
đồng bộ sẽ đi ra từ chân RC3/SCK/SCL. Đối với Slave mode, xung
clock đồng bộ sẽ được nhận từ bên ngoài qua chân
RC3/SCK/SCL.
+ Các chế độ của Slave mode.
+ Mức logic của xung clock khi ở trang thái tạm ngưng quá trình
truyền nhận (Idle).
+ Cạnh tác động của xung clock đồng bộ (cạnh lên hay cạnh xuống).
+ Tốc độ xung clock (khi hoạt động ở Master mode).
+ Thời điểm xác định mức logic của dữ liệu (ở giữa hay ở cuối thời
gian 1 bit dữ liệu được đưa vào).
+ Master mode, Slave mode và các chế độ của Slave mode được
điều khiển bởi các bit SSPM3:SSPM0 (SSPCON<3:0>).
MSSP bao gồm một thanh ghi dịch dữ liệu SSPSR và thanh ghi đệm dữ liệu
SSPBUF.Hai thanh ghi này tạo thành bộ đệm dữ liệu kép (doubled-buffer). Dữ
liệu sẽ được dịch vào hoặc ra qua thanh ghi SSPSR, bit MSB được dịch trước. Đây
là một trong những điểm khác biệt giữ hai giao diện MSSP và USART (USART
dịch bit LSB trước).
Trong quá trình nhận dữ liệu, khi dữ liệu đưa vào từ chân RC4/SDI/SDA
trong thanh ghi SSPSR đã sẵn sàng (đã nhận đủ 8 bit), dữ liệu sẽ được đưa vào
thanh ghi SSPBUF, bit chỉ thị trạng thái bộ đệm BF (SSPSTAT<0>) sẽ được set
để báo hiệu bộ đệm đã đầy, đồng thời cờ ngắt SSPIF (PIR1<3>) cũng được set. Bit
BF sẽ tự động reset về 0 khi dữ liệu trong thanh ghi SSPBUF được đọc vào. Bộ
đệm kép cho phép đọc tiếp byte tiếp theo trước khi byte dữ liệu trước đó được đọc
vào. Tuy nhiên ta nên đọc trước dữ liệu từ thanh ghi SSPBUF trước khi nhận byte
dữ liệu tiếp theo.
Quá trình truyền dữ liệu cũng hoàn toàn tương tự nhưng ngược lại. Dữ liệu
cần truyền sẽ được đưa vào thanh ghi SSPBUF đồng thời đưa vào thanh ghi
SSPSR, khi đó cờ hiệu BF được set. Dữ liệu được dịch từ thanh ghi SSPSR và đưa
ra ngoài qua chân RC5/SDO. Ngắt sẽ xảy ra khi quá trình dịch dữ liệu hoàn tất.
Tuy nhiên dữ liệu trước khi được đưa ra ngoài phải được cho phép bởi tín hiệu từ
chân RA5/AN4/SS/C2OUT. Chân này đóng vai trò chọn đối tượng giao tiếp khi
SPI ở chế độ slave mode.
Khi quá trình truyền nhận dữ liệu đang diễn ra, ta không được phép ghi dữ
liệu vào thanh ghi SSPBUF. Thao tác ghi dữ liệu này sẽ set bit WCON
(SSPCON<7>). Một điều cần chú ý nữa là thanh ghi SSPSR không cho phép truy
xuất trực tiếp mà phải thông qua thanh ghi SSPBUF.
qua thanh ghi TRISC sao cho phù hợp với chiều của giao diện SPI. Cụ thể :
RC4/SDI/SDA sẽ tự động được điều khiển bởi khối giao tiếp SPI.
RS5/SDO là ngõ ra dữ liệu, do đó cần clear bit TRISC<5>.
Khi SPI ở dạng Master mode, cần clear bit TRISC<3> để cho phép
đưa xung clock đồng bộ ra chân RC3/SCK/SCL.
Khi SPI ở dạng Slave mode, cần set bit TRISC<3> để cho phép nhận xung
clock đồng bộ từ bên ngoài qua chân RC3/SCK/SCL.
Set bit TRISC <4> để cho phép chân RA5/AN4/SS/C2OUT nhận tín hiệu
điều khiển truy xuất dữ liệu khi SPI ở chế độ slave mode.
Theo sơ đồ kết nối của chuẩn giao tiếp SPI, khối Master sẽ bắt đầu quá
trình truyền nhận dữ liệu bằng cách gửi tín hiệu xung đồng bộ SCK. Dữ liệu sẽ
dịch từ cả hai thanh ghi SSPSR đưa ra ngoài nếu có một cạnh của xung đồng bộ
tác động và ngưng dịch khi có tác động của cạnh còn lại.
Cả hai khối Master và Slave nên được ấn định chung các qui tắc tác động
của xung clock đồng bộ để dữ liệu có thể dịch chuyển đồng thời.
SPI Master Mode
Ở chế độ Master mode, vi điều khiển có quyền ấn định thời điểm trao đổi
dữ liệu (và đối tượng trao đổi dữ liệu nếu cần) vì nó điều khiển xung clock đồng
bộ. Dữ liệu sẽ được truyền nhận ngay thời điểm dữ liệu được đưa vào thanh ghi
SSPBUF. Nếu chỉ cần nhận dữ liệu, ta có thể ấn định chân SDO là ngõ vào (set bit
TRISC<5>). Dữ liệu sẽ được dịch vào thanh ghi SSPSR theo một tốc độ được
định sẵn cho xung clock đồng bộ. Sau khi nhận được một byte dữ liệu hoàn chỉnh,
byte dữ liệu sẽ được đưa vào thanh ghi SSPBUF, bit BF được set và ngắt xảy ra.
Khi lệnh SLEEP được thực thi trong quá trình truyền nhận, trạng thái của
quá trình sẽ được giữ nguyên và tiếp tục sau khi vi điều khiển được đánh
thức.Giản đồ xung của Master mode và các tác động của các bit điều khiển được
trình bày trong hình vẽ trên.
thấp, dữ liệu ra ở chân RC5/SDO được cho phép xuất dữ liệu và khi ở mức cao, dữ
liệu ra ở chân RC5/SDO bị khóa, đồng thời SPI được reset ( bộ đếm dữ liệu được
gán giá trị 0 ).
Hình 19: Giản đồ xung chuẩn giao tiếp SPI ở chế độ Slave Mode.
Các thanh ghi liên quan đến chuẩn giao tiếp SPI bao gồm:
Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): chứa bit cho phép
toàn bộ các ngắt (GIE và PEIE).
Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ ngắt SSPIF.
Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt SSPIE.
Thanh ghi TRISC (địa chỉ 87h): điều khiển xuất nhập PORTC.
Thanh ghi SSPBUF (địa chỉ 13h): thanh ghi đệm dữ liệu.
Thanh ghi SSPCON (địa chỉ 14h): điều khiển chuẩn giao tiếp SPI.
Thanh ghi SSPSTAT (địa chỉ 94h): chứa các bit chỉ thị trạng chuẩn giao
tiếp SPI.
Thanh ghi TRISA ( địa chỉ 85h) : điều khiển xuất nhập chân RA5/ AN4/S-
S/C2-OUT.
Ngắt (Interrupt)
PIC16F877A có đến 15 nguồn tạo ra hoạt động ngắt được điều khiển bởi
thanh ghi INTCON (bit GIE). Bên cạnh đó mỗi ngắt còn có một bit điều khiển và
cờ ngắt riêng. Các cờ ngắt vẫn được set bình thường khi thỏa mãn điều kiện ngắt
xảy ra bất chấp trạng thái của bit GIE, tuy nhiên hoạt động ngắt vẫn phụ thuôc vào
bit GIE và các bit điều khiển khác. Bit điều khiển ngắt RB0/INT và TMR0 nằm
trong thanh ghi INTCON, thanh ghi này còn chứa bit cho phép các ngắt ngoại vi
PEIE. Bit điều khiển các ngắt nằm trong thanh ghi PIE1 và PIE2. Cờ ngắt của các
ngắt nằm trong thanh ghi PIR1 và PIR2.
Hình 20: Sơ đồ logic của tất cả các ngắt trong vi điều khiển PIC 16F877A.
Trong một thời điểm chỉ có một chương trình ngắt được thực thi, chương
trình ngắt được kết thúc bằng lệnh RETFIE. Khi chương trình ngắt được thực thi,
bit GIE tự động được xóa, địa chỉ lệnh tiếp theo của chương trình chính được cất
vào trong bộ nhớ Stack và bộ đếm chương trình sẽ chỉ đến địa chỉ 0004h. Lệnh
RETFIE được dùng để thoát khỏi chương trình ngắt và quay trở về chương trình
chính, đồng thời bit GIE cũng sẽ được set để cho phép các ngắt hoạt động trở lại.
Các cờ hiệu được dùng để kiểm tra ngắt nào đang xảy ra và phải được xóa bằng
chương trình trước khi cho phép ngắt tiếp tục hoạt động trở lại để ta có thể phát
hiện được thời điểm tiếp theo mà ngắt xảy ra.
Đối với các ngắt ngoại vi như ngắt từ chân INT hay ngắt từ sự thay đổi
trạng thái các pin của PORTB (PORTB Interrupt on change), việc xác định ngắt
nào xảy ra cần 3 hoặc 4 chu kì lệnh tùy thuộc vào thời điểm xảy ra ngắt.
Ngắt INT dựa trên sự thay đổi trạng thái của pin RB0/INT. Cạnh tác động
gây ra ngắt có thể là cạnh lên hay cạnh xuống và được điều khiển bởi bit INTEDG
(thanh ghi OPTION_REG <6>). Khi có cạnh tác động thích hợp xuất hiện tại pin
RB0/INT, cờ ngắt INTF được set bất chấp trạng thái các bit điều khiển GIE và
PEIE. Ngắt này có khả năng đánh thức vi điều khiển từ chế độ sleep nếu bit cho
phép ngắt được set trước khi lệnh SLEEP được thực thi.
Ngắt do sự thay đổi trạng thái của các chân trong PORTB. Các pin
PORTB<7:4> được dùng cho ngắt này và được điều khiển bởi bit RBIE (thanh ghi
INTCON<4>). Cờ ngắt của ngắt này là bit RBIF (INTCON<0>).
Tất cả bộ nhớ bên trong ENC28J60 là kiểu RAM tĩnh (SRAM ). Có 3 loại
bộ nhớ :
Bộ nhớ chứa các thanh ghi điều khiển được sử dụng để cấu hình, điều khiển
và lấy lại trạng thái của ENC28J60. Chúng được đọc và ghi trực tiếp bởi giao tiếp
SPI.
Bộ nhớ chứa các thanh ghi điều khiển được chia thành 4 ngăn (bank ), có
thể được chọn bởi các bit chọn ngăn BSEL1:BSEL0 trong thanh ghi ECON1. Mỗi
bank dài 32 bytes và được đánh 5 bit địa chỉ. Vị trí của 5 bytes cuối cùng (từ 1Bh
đến 1Fh) của tất cả các bank đều có chung năm thanh ghi EIE, EIR, ESTAT,
ECON1, ECON2.
Bộ đệm Ethernet là bộ nhớ đệm có được sử dụng để truyền và nhận dữ liệu.
Kích thước của bộ đệm là 8Kbyte và được chia thành bộ đệm nhận và bộ đệm
truyền. Trong đó, kích thước và vị trí của các bộ đệm trên được lập trình bởi vi
điều khiển qua giao tiếp SPI. Nội dung của bộ đệm Ethernet được truy cập thông
qua các con trỏ đọc và ghi kết hợp với các lệnh đọc và ghi bộ nhớ đệm SPI.
Bộ đệm nhận là vùng nhớ tạm thời dùng để lưu dữ liệu nhận được từ mạng
Ethernet. Các cặp thanh ghi ERXSTH: ERXSTL và ERXNDH : ERXNDL đóng
vai trò như là các con trỏ để xác định kích thước và vị trí của bộ đệm trong bộ nhớ.
Khi các byte của dữ liệu nhận được từ giao diện Ethernet thì chúng sẽ được ghi
vào trong bộ đệm nhận một cách tuần tự.
Bộ đệm truyền sẽ chiếm phần bộ nhớ còn lại trong bộ đệm Ethernet. Bộ
đệm này cũng được xác định kích thước và vị trí thông qua các cặp thanh ghi
ETXST và ETXSN như các con trỏ. Dữ liệu trước khi truyền lên mạng Ethernet sẽ
được lưu tạm thời trong vùng nhớ này.
Các thanh ghi PHY được sử dụng để cấu hình, điều khiển và lấy lại trạng
thái của module PHY. Các thanh ghi này không được truy nhập trực tiếp qua giao
diện SPI, chúng chỉ có thể được truy nhập qua MII thực hiện trong MAC.
Mọi hoạt động của ENC28J60 phụ thuộc vào toàn bộ các lệnh được đưa từ
vi điều khiển thông qua giao diện SPI. Các lệnh này được sử dụng để truy nhập tới
bộ nhớ chứa các thanh ghi điều khiển và bộ đệm Ethernet.
Lệnh đọc thanh ghi điều khiển (RCR) cho phép vi điều khiển đọc bất kì các thanh
ghi nào của ETH, MAC, MII. Lệnh đọc bộ nhớ đệm(RBM)cho phép vi điều khiển
có thể đọc các bytes bên trong bộ nhớ đệm truyền và nhận.Lệnh viết thanh ghi
điều khiển viết WCR cho phép vi điều khiển viết tới bất kì các thanh ghi nào của
ETH, MAC, MII. Lệnh viết tới bộ nhớ đệm WBM cho phép vi điều khiển viết các
bytes trong 8-Kbyte bộ nhớ đệm truyền và nhận. Lệnh BSF dùng để thiết lập 8 bits
điều khiển trong thanh ghi ETH. Lệnh này không được sử dụng với thanh ghi
MAC, PHY, MII hay bộ nhớ đệm. Lệnh BFC dùng để xóa 8 bits trong thanh ghi
điều khiển ETH. Lệnh reset hệ thống SRC cho phép vi điều khiển phát ra lệnh
SSR. Không giống như các lệnh SPI khác. Lệnh SRC chỉ là lệnh 1 byte, không tác
động lên các thanh ghi khác.
4.Xóa bit TXIF và đặt bit TXIE trong thanh ghi EIR, đặt bit INTIE trong thanh ghi
EIE để có thể thực hiện một ngắt khi cần thiết.
5.Quá trình truyền được bắt đầu khi đặt bit TXRTS của thanh ghi ECON1.
Khi quá trình truyền bức điện được thực hiện thành công hoặc ngưng lại
khi có một nguyên nhân nào đó thì bit TXRTS của thanh ghi ECON1 sẽ được xóa,
7 byte vector trạng thái truyền sẽ được ghi vào vị trí bởi ETXND +1, bit TXIF của
thanh ghi EIR sẽ được đặt và ngắt được tạo ra. Để kiểm tra nếu bức điện được gửi
thành công, bit TXABRT của thanh ghi ESTAT sẽ được đọc.
Để có thể nối vào card mạng của PC thì cáp đôi dây xoắn cần được gắn vào
đầu nối RJ45.
Về cơ bản đã thiết kế được phần cứng để giao tiếp với máy tính thông qua
giao diện Ethernet.
Có thể mở rộng để giao tiếp giữa máy tính với nhiều vi điều khiển, sử dụng
Hub.
Đã có thể sử dụng được cả giao thức TCP và UDP để truyền nhận dữ liệu.
Hiển thị nhiệt độ tương đối chính xác.
4.1 Phần cứng
4.1.1 Các thành phần của mạch
Mạch giao tiếp Ethernet sử dụng các thành phần:
PIC16F877A.
ENC28J60.
RJ45 tích hợp biến áp.
74LS08 nhằm mục đích chuyển mức điện áp từ 3.3V sang 5V để ghép nối
ENC28J60 với vi điều khiển.
LCD hiển thị nhiệt độ và dữ liệu gửi xuống từ máy tính.
Cảm biến nhiệt độ môi trường LM35.
4.1.2 Sơ đồ mạch nguyên lý, mạch in
Sơ đồ mạch nguyên lý
Trình bày trong bản A3 đính kèm
Sơ đồ mạch in
Với vi điều khiển để thực hiện giao tiếp Ethernet, thư viện của MikroC đã tích hợp
sẵn các hàm, thủ tục, làm đơn giản việc lập trình. Một số hàm cơ bản:
1.Spi_Ethernet_Init: Khởi tạo cho ENC28J60. ENC28J60 được khởi tạo như sau:
Vùng đệm nhận bắt đầu từ địa chỉ 0x0000 và kết thúc tại 0x19AD
Vùng đệm gửi là vùng còn lại, từ 0x19AE đến 0x1FFF
Con trỏ đọc viết RAM đặt ở chế độ tự động tăng giảm khi
độ dài lớn nhất của gói tin là 1518
CLKOUT bị vô hiệu hoá
LedA hiển thị trạng thái, ledB hiển thị hoạt động
void Spi_Ethernet_Init(unsigned char *resetPort, unsigned char resetBit,
unsigned char *CSportPtr, unsigned char CSbit, unsigned char *mac, unsigned
char *ip, unsigned char fullDuplex);
resetPort: Địa chỉ cổng có chân reset.
resetBit: chân reset.
CSport: Điạ chỉ cổng có chân chip select.
CSbit: chân chip select.
mac: địa chỉ MAC, phải đặt trong RAM
ip: điạ chỉ IP, phải đặt trong RAM.
fullDuplex: 0 hoặc là 1 ứng với chế độ bán song công hay là song công.
2.Spi_Ethernet_doPacket: Hàm nhận bức điện và xử lý, các yêu cầu ARP và
ICMP sẽ được tự động đáp lại, các gói tin UDP, TCP sẽ được xử lý trong
Spi_Ethernet_UserUDP, Spi_Ethernet_UserTCP.
unsinged char Spi_Ethernet_doPacket();
Giá trị trả về: 0-không có gói tin hoặc xử lý gói tin thành công.
1-quá trình nhận bức điện có lỗi hoặc vùng đệm nhận lỗi
2-nhận bức điện sai địa chỉ ip
3-nhận bức điện không phải phiên bản Ipv4
4-kiểu của bức điện không được định nghĩa trong thư viện
3.Spi_Ethernet_putByte: Hàm lưu một byte vào địa chỉ hiện tại xác định bởi
EWRPT.
void Spi_Ethernet_putByte(unsigned char v);
4.Spi_Ethernet_getByte: hàm đọc 1 byte trong RAM có địa chỉ xác định bởi
ERDPT
unsigned char Spi_Ethernet_getByte();
5.Spi_Ethernet_UserTCP: Hàm xử lý gói tin TCP. Hàm này được gọi bởi hàm
Spi_Ethernet_doPacket để xử lý gói tin TCP.
unsigned int Spi_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int
remotePort, unsigned int destPort, unsigned int reqLength);
Giá trị trả về của hàm: là số byte gửi trở lại
remotePort , remoteHost: cổng và số ip của nơi gửi
destPort: số cổng đích
reqLength: độ dài của dữ liệu gửi
6.Spi_Ethernet_UserUDP: Hàm xử lý gói tin UDP. Hàm này được gọi bởi hàm
Spi_Ethernet_doPacket để xử lý gói tin UDP.
unsigned int Spi_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int
remotePort, unsigned int destPort, unsigned int reqLength);
Giá trị trả về của hàm: là số byte gửi trở lại
remotePort , remoteHost: cổng và số ip của nơi gửi
destPort: số cổng đích
reqLength: độ dài của dữ liệu gửi
8. Spi_Ethernet_getBytes đọc một số byte từ ENC28J60 bắt đầu từ địa chỉ addr
10. Spi_Ethernet_putString
unsigned int Spi_Ethernet_putString(unsigned char *ptr);
11. Spi_Ethernet_putConstString
unsigned int Spi_Ethernet_putConstString(const unsigned char *ptr);
Một TCP/IP socket gồm một địa chỉ IP kết hợp với một port xác định duy
nhất một quá trình liên mạng. Đối với giao thức IP, mỗi bên giao tiếp được gán
một địa chỉ IP đại diện bởi một chuỗi 32 bit, gọi là địa chỉ Ipv4. Ngoài địa chỉ IP
để truy cập máy tính ở xa, một ứng dụng phải biết được số cổng hay port của dịch
vụ để truyền thông với dịch vụ đang chạy trên máy cục bộ hoặc ở xa.
Khi một client muốn truyền thông giao tiếp với server qua giao thức TCP
hay UDP, nó phải dò địa chỉ IP của server song song với số cổng dịch vụ. Khi
server muốn lắng nghe kết nối và thu thập nhu cầu của client chúng phải chỉ rõ
một địa chỉ IP và port.
Có hai loại socket:
Stream socket: dựa trên giao thức TCP, việc truyền dữ liệu chỉ thực hiện giữa hai
quá trình đã thiết lập kết nối. Dữ liệu được truyền tin cậy, đúng trình tự và không
lặp lại.
Datagram socket: Dựa trên giao thức UDP, việc truyền dữ liệu không yêu cầu có
sự thiết lập kết nối giữa hai quá trình. Dữ liệu truyền không tin cậy, có thể không
đúng trình tự hoặc lặp lại.
5.Hàm accept hàm chấp nhận yêu cầu kết nối từ client
SOCKET accept(SOCKET s, struct sockaddr FAR * addr, int FAR *addrlen);
Hàm trả về INVALID_SOCKET nếu không thành công
s: Socket đang ở trạng thái listen. Kết nối được tạo ra với socket trả về.
addr: chứa địa chỉ của nơi kết nối
addrlen: độ dài của dữ liệu trong addr
Hình 30 : Gửi dữ liệu xuống vi điều khiển, sử dụng giao thức TCP
Hình 35 : Hiển thị dữ liệu nhận được theo giao thức UDP
Phụ lục
1. Chương trình trên vi điều khiển PIC16F877A
#define PORT_SD 20000
unsigned iNhietdo;
unsigned char cDem = 0;
char strNhietdo[6];
char cChedo;
void interrupt(){
if(INTCON.TMR0IF){
cDem++;
INTCON.TMR0IF = 0;
}
}
void VietBandau(){
Lcd8_Out(1,1,"Do an tot nghiep");
Lcd8_Out(2,1,"Nhiet do:");
void main () {
unsigned temp;
char i;
cChedo= 1;
TRISA.F0= 1;
TMR0 = 0;
OPTION_REG = 0x07;
INTCON = 0xA0;
TRISD = 0;
TRISE = 0;
ADCON1 = 0xAE;
Lcd8_Config(&PORTE,&PORTD,0,2,1,7,6,5,4,3,2,1,0);
VietBandau();
Spi_Init();
SPi_Ethernet_Init(&PORTC,0, &PORTC, 1, dcMac, dcIP, 1 );
iNhietdo = 0;
memset(pDemNhietdo, 0, sizeof(pDemNhietdo));
cVtNhietdo = 0;
while (1) {
Spi_Ethernet_doPacket();
if (cDem == 10){
pDemNhietdo[cVtNhietdo] = (unsigned char) (ADC_Read(0) * 500L/1023);
cVtNhietdo++;
if (cVtNhietdo==8) cVtNhietdo = 0;
temp = 0;
for(i=0; i<8; i++) temp = temp+ pDemNhietdo[i];
iNhietdo = temp >> 3;
if(cChedo== 2){
Lcd8_cmd(LCD_CLEAR);
VietBandau();
cChedo =1;
}
if(cChedo==1){
wordToStr (iNhietdo, strNhietdo);
XoaSpace (strNhietdo);
Lcd8_Out (2,11,strNhietdo);
Lcd8_Out (2,13,"(C)");
} else if(cChedo==3){
SPi_Ethernet_Init(&PORTC,0, &PORTC, 1, dcMac, dcIP, 1 );
cChedo = 0;
//Lcd8_Out (1,1,"IP:");
Lcd8_Cmd(LCD_CLEAR);
for(i=0; i<4; i++){
intToStr(dcIP[i],strNhietdo);
XoaSpace (strNhietdo);
strNhietdo[3] = 0;
if(i==0) Lcd8_Out(1,1,strNhietdo); else Lcd8_Out_Cp(strNhietdo);
if(i!= 3) Lcd8_Out_Cp(".");
}
wordToStr(port,strNhietdo);
XoaSpace(strNhietdo);
Lcd8_Out(2,1,strNhietdo);
}
cDem = 0;
}
}
}
}else if(cCommand==255){
cChedo = 2;
cDem = 10;
}else if(cCommand==254){
cChedo = 3;
for(i=0; i<4; i++)
dcIP[i]= Spi_Ethernet_getByte();
port = Spi_Ethernet_getByte()*256+Spi_Ethernet_getByte();
}else {
cChedo = 0;
Lcd8_Cmd(LCD_CLEAR);
Lcd8_Chr(1,1, cCommand);
for(i= 1; i<reqlength-1; i++){
cCommand = Spi_Ethernet_getByte();
if(cCommand!= 0) Lcd8_Chr_Cp(cCommand);
else{
cCommand = Spi_Ethernet_getByte();
i++;
Lcd8_Chr(2,1,cCommand);
}
}
}
return 0;
}
Lcd8_Chr(1,1,c);
if(isUpper(c)) Spi_Ethernet_putByte(tolower(c));
else Spi_Ethernet_putByte(toupper(c));
for(i= 1; i< reqLength; i++){
c= Spi_Ethernet_getByte();
if(i==16) Lcd8_Chr(2,1,c); else Lcd8_Chr_Cp(c);
if(isUpper(c)) Spi_Ethernet_putByte(tolower(c));
else Spi_Ethernet_putByte(toupper(c));
}
return reqLength;
}
}
}
return 0;
}
2. Chương trình trên PC
#include "DA_Std.h"
#define WM_READ WM_USER
#define ID_TIMER 1
#define PORT_DATA 20000
HINSTANCE hInst;
HWND hDlgDAEthernet;
int iTempe = 0;
void SetSockAddr(){
sockaddrLocal.sin_family = AF_INET;
sockaddrLocal.sin_addr.s_addr = INADDR_ANY;
sockaddrLocal.sin_port= htons (uPort);
sockaddrHost.sin_family = AF_INET;
sockaddrHost.sin_addr = szHostIP; //inet_addr (szHostIP);
sockaddrHost.sin_port = htons (uPort);
}
int ConnectTCP(){
int tempval;
SetSockAddr();
sockConnect = socket (AF_INET, SOCK_STREAM, 0);
if (sockConnect == INVALID_SOCKET) {
return WSAGetLastError();
}
bind (sockConnect, (LPSOCKADDR)&sockaddrLocal, sizeof(sockaddrLocal));
if (connect (sockConnect, (LPSOCKADDR) &sockaddrHost, sizeof(sockaddrHost))==
SOCKET_ERROR){
tempval = WSAGetLastError();
closesocket (sockConnect);
return tempval;
}
if (WSAAsyncSelect (sockConnect, hDlgDAEthernet, WM_READ, FD_READ) ==
SOCKET_ERROR){
tempval = WSAGetLastError();
WSAAsyncSelect (sockConnect, hDlgDAEthernet, 0, 0);
return tempval;
}
tempval = TRUE;
if(setsockopt(sockConnect, IPPROTO_TCP,TCP_NODELAY, (LPCSTR)&tempval,
sizeof(tempval)));
tempval = TRUE;
setsockopt(sockConnect, SOL_SOCKET, SO_DONTLINGER,(LPCSTR)&tempval,
sizeof(tempval));
return 0;
}
int ConnectUDP(){
SetSockAddr();
sockConnectUDP = socket (AF_INET, SOCK_DGRAM, 0);
if (sockConnect == INVALID_SOCKET) {
return WSAGetLastError();
}
bind (sockConnectUDP, (LPSOCKADDR)&sockaddrLocal, sizeof(sockaddrLocal));
return 0;
}
void GetTemperature(){
char pCommand[6] = {0,0,0,0,0,0};
ConnectTCP();
send(sockConnect, (LPCSTR)&pCommand, 6, 0);
}
}
return 0;
}
switch (uMsg) {
case WM_INITDIALOG:
InitCommonControlsEx(&icce);
SendMessage(GetDlgItem(hDlg,IDC_LCDROW1),EM_LIMITTEXT,16,0);
SendMessage(GetDlgItem(hDlg,IDC_LCDROW2),EM_LIMITTEXT,16,0);
SetDlgItemText(hDlg,IDC_TEMPERATURE,"- - - (C)");
wsprintf(szMessage,"%s is running",WSADat.szDescription);
SetDlgItemText(hDlg,IDC_STATUS,szMessage);
break;
case WM_READ:
if(WSAGETSELECTERROR(lParam)!= 0) break;
if(WSAGETSELECTEVENT(lParam)==FD_READ){
temp = recv(sockConnect, szMessage, sizeof(szMessage),0);
if(temp==0){
SetDlgItemText(hDlg,IDC_STATUS,"Connect broken");
} else {
iTempe= (szMessage[0]*256+szMessage[1]);
wsprintf(szMessage,"%d (C)",iTempe);
SetDlgItemText(hDlg, IDC_TEMPERATURE, szMessage);
}
}
break;
case WM_TIMER:
if(bConnect)
GetTemperature();
break;
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDC_DISPLAY:
if(HIWORD(wParam)== LBN_SELCHANGE){
cExe=
(char)SendDlgItemMessage(hDlg,IDC_DISPLAY,CB_GETCURSEL,0,0);
switch(cExe){
case 0:
EnableSendData(FALSE);
EnableSetIP(FALSE);
break;
case 1:
EnableSendData(TRUE);
EnableSetIP(FALSE);
break;
case 2:
EnableSendData(FALSE);
EnableSetIP(TRUE);
}
}
break;
case IDC_ABOUT:
DialogBox(hInst,"ABOUT",hDlg,(DLGPROC)DlgAboutProc);
break;
case IDOK:
case IDCANCEL:
KillTimer(hDlg, ID_TIMER);
DestroyWindow(hDlg);
PostQuitMessage(0);
break;
case IDC_CONFIG:
if(DialogBox(hInst,"CONFIGETHERNET",hDlg,(DLGPROC)
DlgConfigProc)== IDOK){
EnableWindow(GetDlgItem(hDlg,IDC_CONNECT),bUsedTCP);
EnableWindow(GetDlgItem(hDlg,IDC_SEND),!bUsedTCP);
}
break;
case IDC_SEND:
if(cExe==0){
szMessage[0]= (char)255;
szMessage[1]= 0;
temp = 2;
} else if(cExe==1){
if(bUsedTCP){
memset(szLcdRow1,0,sizeof(szLcdRow1));
memset(szLcdRow2,0,sizeof(szLcdRow2));
GetDlgItemText(hDlg,IDC_LCDROW1,szLcdRow1,sizeof(szLcdRow1));
GetDlgItemText(hDlg,IDC_LCDROW2,szLcdRow2,sizeof(szLcdRow2));
memset(szMessage,0,sizeof(szMessage));
strcpy(szMessage,szLcdRow1);
memcpy(szMessage+strlen(szLcdRow1)+1,szLcdRow2,strlen(szLcdRow2)+1);
temp = strlen(szLcdRow1)+strlen(szLcdRow2)+2;
}else{
GetDlgItemText(hDlg,IDC_LCDROW1,szMessage,sizeof(szMessage));
GetDlgItemText(hDlg,IDC_LCDROW2,szMessage+strlen(szMessage),sizeof(szMessage));
temp = strlen(szMessage);
}
}else{
//int i;
//PIP_ADAPTER_INFO pai;
//ULONG outbuflen= sizeof(pai);
unsigned short port;
szMessage[0]= 254;
SendDlgItemMessage(hDlg, IDC_IPSET,IPM_GETADDRESS,
0, (long)(szMessage+1));
port = GetDlgItemInt(hDlg, IDC_PORTSET,NULL,FALSE);
SetDlgItemInt(hDlg,IDC_PORTSET, port,0);
Swap(szMessage+1,szMessage+4);
Swap(szMessage+2,szMessage+3);
szMessage[5] = port/256;
szMessage[6] = port%256;
temp= 7;
//GetAdaptersInfo(&pai,&outbuflen);
//pai.IpAddressList.IpMask.String
}
if(bUsedTCP){
temp = send(sockConnect,szMessage,temp,0);
if(cExe==2){
closesocket(sockConnect);
bConnect = FALSE;
SetDlgItemText(hDlg,IDC_CONNECT,"Connect");
EnableWindow(GetDlgItem(hDlg,IDC_CONFIG),TRUE);
}
}else{
ConnectUDP();
temp = sendto(sockConnectUDP,szMessage,temp,0,
(LPSOCKADDR)&sockaddrHost,sizeof(sockaddrHost));
if(cExe==1){
temp = sizeof(sockaddrHost);
recvfrom(sockConnectUDP, szMessage,
sizeof(szMessage),0,(LPSOCKADDR)&sockaddrHost,&temp);
wsprintf(szMessage+strlen(szMessage),"\nReceive %d
bytes",temp);
SetDlgItemText(hDlg, IDC_STATUS, szMessage);
} else if(cExe==2){
closesocket(sockConnectUDP);
}
break;
}
wsprintf(szMessage, "Send %d bytes to %d.%d.%d.
%d",temp,szHostIP.s_net,szHostIP.s_host,szHostIP.s_lh,szHostIP.s_impno);
SetDlgItemText(hDlg,IDC_STATUS,szMessage);
break;
case IDC_CONNECT:
bConnect = !bConnect;
if(bConnect){
if((temp=ConnectTCP())== 0){
wsprintf (szMessage, "Connection to %d.%d.%d.
%d",szHostIP.s_net,szHostIP.s_host,szHostIP.s_lh,szHostIP.s_impno);
SetDlgItemText(hDlg, IDC_STATUS, szMessage);
} else{
wsprintf(szMessage,"Socket error %d",temp);
SetDlgItemText(hDlg,IDC_STATUS,szMessage);
closesocket(sockConnect);
bConnect = 0;
}
} else {
closesocket(sockConnect);
SetDlgItemText(hDlg, IDC_STATUS,"Disconnection...");
}
SetDlgItemText(hDlg,IDC_CONNECT,bConnect?"Disconnect":"Connect");
EnableWindow(GetDlgItem(hDlg,IDC_CONFIG),!bConnect);
EnableWindow(GetDlgItem(hDlg,IDC_SEND),bConnect);
}
return TRUE;
}
return FALSE;
}