Thông báo

Collapse
No announcement yet.

Serial Port - lập trình giao tiếp nối tiếp

Collapse
This topic is closed.
X
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Serial Port - lập trình giao tiếp nối tiếp

    Do mình viết bài trong "Viết chương trình = VB giao tiếp máy tính có lẽ là không tổng quát cho lắm. Tôi xin copy tất cả các bài của tôi vào box này để cho tổng quát hơn giới thiệu về giao tiếp nối tiếp qua Serial Port như RS-232, RS-485. Hi vọng là cho các bạn có kiến thức đầy đủ về lập trình nối tiếp nói chung và qua RS232, RS-485 nói riêng.
    Technical sale at WT Microelectronics S'pore
    Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
    Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

  • #2
    Giới thiệu giao tiếp cổng com - chapter1

    Như đã hứa. Nay tôi xin giới thiệu cho các bạn chi tiết các thông tin, cách lập trình truyền thông nối tiếp dùng chuẩn RS-232 và RS-485.

    Có thể có nhiều bạn đã biết rồi hoặc là chưa biết nhưng tôi mong rằng sẽ bổ sung cho các bạn một số điều cơ bản.

    Tất cả mọi vấn đề tôi dịch từ cuốn Serial_complete của Jan Axelson và thực tế lập trình truyền thông giao tiếp với vdk AT89C51( một loại vi điều khiển đơn giản). Hi vọng các vấn đề tôi đưa ra sẽ làm các bạn môt phần nào hiểu biết thêm về cổng thông dụng này cổng Comm( communicactions).

    Do thời gian không có nhiều vừa làm vừa ôn thi nên mỗi ngày tôi sẽ up lên từng vấn đề một. Mong các bạn góp ý thêm. Tôi làm cái này không có ý qua mặt các cao thủ, mong các cao thủ bỏ quá cho.
    Các bạn có thể có thêm nhiều ví dụ khi vào trang web http://www.lvr.com

    1. Thứ nhất tôi xin giới thiệu một cách khái quát về các cổng và đặc biệt là cổng RS-232 và RS-485.

    Trước hết tôi xin định nghĩa liên kết: là dùng dây dẫn hoặc trung gian khác như công nghệ không dây,.. để kết nối các máy tính hoặc là kết nối các thiết bị kết nối qua PC. Khoảng cách có thể rất ngắn vài cm đến hàng ngàn km, thời gian có thể 1 giây có khi đến hàng 1 tuần. Các điểm kết nối vào mạng có thể là 2 hoặc nhiều điểm.

    Đặc điểm so sánh giữa các cổng nay quên không mang bảng so sánh, mai mang sau)
    • Chuẩn RS-232 chỉ có thể kết nối nhiều nhất 2 thiết bị, với khoảng cách dài nhất là 50-100 feet( 12,7->25,4 m), tốc độ 20k bit/s
    • Chuẩn RS-485 có thể kết nối tối đa là 32 thiết bị, khoảng cách dài hơn tối đa là 4000feet( 1016 m-> hơn 1km) gấp 40 lần RS-232. Tốc độ cao 10 mega bit/s. Cả hai chuẩn này có thẻ có sắn trong mainboard khi mua hoặc là có thể lắp thêm rất dễ dàng, giá mua rất rẻ so với các giao diện khác.Chuẩn RS-232 dùng rộng rãi, mua dễ dàng, đơn giản khi lắp thêm với nhiều cách thiết lập. Còn RS-485 dùng với khoảng cách lớn hơn, tốc độ cao hơn, nhiều đầu nối hơn.
    • Chuẩn IrDA( Inared Data Asociation) dùng các UART giống nhau và định dạng dữ liệu giống như RS-232 nhưng có thêm bộ giải mã. Dữ liệu truyền từ nguồn phát hồng ngoại đến các thiết bị không giây. Giao diện này rất là có ích cho các liên kết ngắt, giữa các thiết bị mà không thể có cáp nối ở giữa( có thể là cho đẹp).
    • Chuẩn MIDI( Musical instrument digital interface): giao diện số hóa các dụng cụ âm nhạc. Chuẩn này dùng dòng 5mA, tốc độ 31,5k bit/s
    • Microwire, I2C,SPI là các chuẩn nối tiếp đồng bộ, dùng trong các liên kết ngắn. Nhiều vdk có 1 hoặc nhiều chuẩn này.
    • USB( Universial Sẻial Bus) và Fireware( chuẩn IEEE-1384) là chuẩn mới, tốc độ cao, thông minh kết nối với PC và các PC khác, thiết bị ngoại vi. USB ra đời đã dần thay thế chuẩn RS-232 và chuẩn máy in Centronic như là một lựa chọn mới hiện đại cho các TB ngoại vi. Fireware tốc độc truyền dữ liệu nhanh hơn nhiều và được dùng để truyền nhạc tiếng, nhạc hình, hoặc các block dung lượng lớn.
    • Ethernet là các chuẩn mạng gần gũi thường dùng trong nhiều mạng. Tốc độ cao nhưng yêu cầu phần cứng và phần mềm khá phức tạp, đắt hơn nhiều so với các chuẩn khác.
    • Đồng hành với chuẩn nối tiếp là chuẩn song song, có nhiều đường dữ liệu. Ví song song nên chuyển nhiều bit cùng một lúc, rất nhanh. Thường có một loạt các đường dữ liệu -> dữ liệu truyền đi theo một chiều ở một thời điểm. Nếu dùng để nối khoảng cách xa thì tiền mua quả là đắt đỏ cho việc thực hành của sinh viên cũng như các ứng dụng trong công nghiệp, ..
    • Chuẩn máy in Cenntronics(IEEE-1284). Mọi pc đều có chuẩn này. Tốc độ truyền cao qua cáp. Được ứng dụng với các máy quét, các thiết bị lưu trữ mở rộng như đĩa cứng,.. và nhiều thiết bị ngoại vi đặc biệt khác. Chuẩn IEEE-488 là chuẩn song song dùng trong các ứng dụng điều khiển và trong âm nhạc.


    Nói thêm về cổng RS-232 và RS-485:

    Cổng nối tiếp là một phần của PC ngay khi nó mới ra đời. Với mỗi cổng Com hoặc Comm( communications) trong PC là một cổng nối tiếp không đồng bộ được điều khiển bởi cácUART. Mỗi cổng Com có thể có giao diện RS-232, RS – 485 hoặc cổng có thể để dành cho một modem trong hoặc thiết bị khác. Mỗi PC có thể có các dạng khác nhau của các cổng nối tiếp như USB, Firewire, và I2C nhưng chúng dùng các giao thức khác nhau và yêu cầu các thành phần khác nhau.

    Giao diện nối tiếp mới nhất là USB và Firewire với các tình năng: nhanh, và nhìều lợi ích khác nữa. Thực tế thì nên dùng USB trong việc thay thế cổng RS-232 ở bất kì nơi nào có thể được trong các thiết kế mới, ứng dụng mới. Và với nhều thiết bị ngoại vi, giao diện mới này lại rất là phù hợp.

    Nhưng RS – 232 và các giao diện giống nó vẫn sẽ tiếp tục phổ biến trong các ứng dụng như là hệ thống điều khiển, điều hành. Những giao diện này không đắt đỏ, dễ dàng lập trình, cho phép cáp dài,và dễ dùng kết hợp với các thiết bị vi điều khiển rẻ tiền, các máy tính cũ. Như cổng USB đã được sử dụng rộng rãi, các bộ chuyển đổi sẵn sàng để chuyển USB thành cổng RS-232 hoặc RS – 285. Bộ chuyển đổi sẽ kết nối với cổng USB của PC và chuyển đổi giữa USB và các giao diện khác. Thiết lập rất đơn giản để thêm một cổng RS-232 hoặc RS – 485 vào bất kỳ hệ thống nào.
    Last edited by ngohaibac; 04-05-2007, 01:00.
    Technical sale at WT Microelectronics S'pore
    Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
    Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

    Comment


    • #3
      Uart

      Tiếp theo tôi xin giới thiệu cho các bạn UART:

      Trong những máy tính IBM – PC đầu tiên, UART điều khiển cổng nối tiếp là 8250, tốc độ lớn nhất là 57.600 bit /giây. Các UART từ thời gian này đã được tiếp tục cải thiện thêm nhiều đặc điểm mới như thêm bộ đệm, tốc độ tăng lên. Ngày nay, UART trong PC là một phần không thể thiếu của chíp đa chức năng bao gồm một hay nhiều UART hỗ trọ cổng song song, thiết bị lưu trữ và các bộ phận hệ thống khác.

      UART chuyển đổi giữa dữ liệu nối tíêp và song song. Một chiều, UART chuyển đổi dữ liệu song song bus hệ thống ra dữ liệu nối tiếp để truyền đi. Một chiều khác, UART chuyển đổi dữ liệu nhận được dạng dữ liệu nối tiếp thành dạng dữ liệu song song cho CPU có thể đọc vào bus hệ thống.

      UART của PC hỗ trợ cả hai kiểu giao tiếp là giao tiếp đồng thời và không giao tiếp đồng thời. Giao tiếp đồng thời tức là UART có thể gửi và nhận dữ liệu vào cùng một thời điểm. Còn giao tiếp không đồng thời( không kép) là chỉ có một thiết bị có thể chuyển dữ liệu vào một thời điểm, với tín hiệu điều khiển hoặc mã sẽ quyết định bên nào có thể truyền dữ liệu. Giao tiếp không đồng thời được thực hiện khi mà cả 2 chiều chia sẻ một đường dẫn hoặc nếu có 2 đường nhưng cả 2 thiết bị chỉ giao tiếp qua một đường ở cùng một thời điểm.
      Thêm vào đường dữ liệu, UART hỗ trợ bắt tay chuẩn RS232 và tín hiêu điều khiển như RTS, CTS, DTR, DCR, RT và CD.

      Để thuận tiện, các chương trình gửi và nhận dữ liệu trong định dạng không đồng bộ đơn giản hơn những gì bạn tưởng. PC và nhiều vi xủ lí khác có một bộ phận gọi là UART( universal asynchronous receiver/transmitter: truyền /nhận không đồng bộ chung) vì thế có thể vận dụng phần lớn những chi tiết truyền và nhận dữ liệu.

      Trong PC, hệ điều hành và ngôn ngữ lập trình hỗ trợ cho lập trình liên kết nối tiếp mà không cần phải hiểu rõ chi tiết cấu trúc UART . Để mở liên kết, ứng dụng lựa chọn một tần số dữ liệu hoặc là thiết lập khác hoặc cho phép truyền thông tại các cổng. Để gửi 1 byte, ứng dụng ghi byte này vào bộ đệm truyền của cổng được lựa chọn, và UART gửi dữ liệu này, từng bít một, trong định dạng yêu cầu, thêm bít Start, bít Stop, bít chẵn lẻ khi cần. Trong một cách đơn giản, byte nhận được tự động được lưu trữ trong bộ đệm. UART cso thể dùng nhanh một ngắt để báo cho CPU và các ứng dụng biết dữ liệu đang nhận được và các sự kiện khác.

      Một vài vi điều khiển không bao gồm UART, và thỉnh thoảng bạn cần nhiều hơn các UART mà vi xử lí có. Trong trường hợp này, có 2 lựa chọn: thêm UART ngoài, hoặc mô phỏng UART trong mã chương trình. Basic Stamp của Parallax là một ví dụ của chip với một UART bổ sung trong mã chuơng trình.
      UART là một thiết bị đơn giản hỗ trợ tốt cả hai kiểu truyền thông đồng bộ và không đồng bộ.
      Last edited by ngohaibac; 24-12-2005, 11:55.
      Technical sale at WT Microelectronics S'pore
      Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
      Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

      Comment


      • #4
        Định dạng và giao thức đồng bộ và không đồng bộ

        Định dạng và giao thức Format và Protocol):

        Máy tính trong một mắt xích nối tiếp có thể là nhiều dạng khác nhau, nhưng tất cả chúng phải cùng đồng ý một thoả thuận và qui tắc để cho dữ liệu có thể trao đổi giữa chúng. Sự thoả thuận này phải chắc chắn rằng mọi sự chuyển dữ liệu phải tìm thấy được nơi nó cần đến, và mỗi máy tính phải hiểu thông điệp gửi tới nó.

        Dưới đây giới thiệu về cách định dạng dữ liệu và giao thức dùng trong truyền thông nối tiếp. Chủ yếu là định dạng không đồng bộ dùng 2 chuẩn thông dụng là RS-232 và RS-485.

        Gửi dữ liệu nối tiếp

        Trong một liên kết nối tiếp, nơi gửi dữ liệu sẽ gửi từng bit một ở mỗi thời điểm nối tiếp nhau. Một liên kết nối tiếp chỉ có 2 thiết bị thì phải có đường dẫn dành cho mỗi chiều truyền hoặc là nó chỉ có 1 đường dẫn được chia sẻ bởi cả 2 thiết bị với thoả thuận của 2 thiết bị này. Khi mà có 3 hoặc nhiều thiết bị, tất cả các thiết bị này thường dùng chung một đường dẫn, và giao thức mạng quyết định xem thiết bị nào có quyền truyền nhận dữ liệu.

        Một tín hiệu đòi hỏi bởi tất cả mọi liên kết nối tiếp là tín hiệu xung đồng hồ, hoặc là có sự tham khảo về thời gian để điều khiển đường truyền dữ liệu. Nơi truyền và nơi nhận dùng xung đồng hồ để quyết định khi nào gửi và khi nào đọc mỗi bít. Có hai dạng định dạng dữ liệu là đồng bộ và không đồng bộ, và mỗi định dạng này dùng các dạng xung đồng hồ khác nhau.

        Định dạng đồng bộ:

        Trong truyền đồng bộ, mọi thiết bị dùng một xung đồng hồ được phát ra bởi một thiết bị hoặc từ một nguồn xung ngoài. Xung đồng hồ có thể có một tần số cố định hoặc cóc thể chốt tại những khoảng thời gian không đều. Mọi bít truyền đi được đồng bộ với đồng hồ. Nói cách khác, mỗi bít được truyền đi là dựa vào sự chuyển đổi của xung( như tăng hoặc giảm của sường xung). Nơi nhận dùng sự chuyển đổi xung để quyết định khi nào đọc mỗi bít truyền tới. Từ hình vẽ các bạn cũng có thể thấy là nơi truyền sẽ truyền các bit khi mà nhận thấy sự chuyển sườn xung từ cao xuống thấp, và nơi nhận thì ngược lại phát hiện khi nào có sự chuyển sườn xung từ thấp lên cao thì đọc các bit.Chi tiết chính xác của giao thức này có thể biến đổi khác đi. Ví dụ, nơi nhận có thể chốt dữ liệu nhận trong sườn xung tăng hoặc giảm, hoặc là phát hiện mức logic ở mức cao hoặc thấp. Định dạng đồng bộ dùng các cách khác nhau để bắt đầu và kết thúc việc truyền dữ liệu, bao gồm bít Start và bít Stop và tín hiệu lựa chọn chíp.

        Định dạng không đồng bộ:

        Trong truyền không đồng bộ, liên kết không bao gồm đường xung đồng hồ, bởi vì mỗi điểm đầu cuối của liên kết đã có xung đồng hồ cho riêng từng cái. Mỗi điểm sẽ cần phải đồng ý cùng một tần số của đồng hồ và mọi đồng hồ chỉ khác nhau một vài %. Mỗi byte truyền đi bao gồm bít Start để đồng bộ đồng hồ và một hoặc nhiều bít Stop cho tín hiệu kết thúc việc truyền trong mỗi một từ được truyền đi. Cổng RS-232 trong PC dùng định dạng khoong đồng bộ để giao tiếp với modems(thiết bị mã hoá, giải mã dữ liệu) và các thiết bị khác. Dù RS-232 có thể truyền dữ liệu đồng bộ nhưng liên kết không đồng bộ vần được dùng phổ biến hơn. Phần lớn liên kết RS-485 dùng giao tiếp không đồng bộ.

        Truyền không đồng bộ có thể dùng một trong vài cách định dạng phổ biến. Phổ biến nhất là kiểu 8-N-1, nơi truyền sẽ truyền mỗi byte dữ liệu một bít Start, tiếp theo là 8 bít dữ liệu bắt đầu với bít 0(bít có trọng số nhỏ nhất Least Sìgnificant Bit) và kết thúc với 1 bít Stop.

        Các bạn có thể xem hình vẽ để hiểu thêm về cách định dạng này.

        Chữ N trong định dạng 8-N-1 chỉ rằng truyền dữ liệu không dùng bít chẵn lẻ. Một dạng định dạng khác là bao gồm một bít chẵn lẻ giống như dạng đơn giản của kiểm soát lỗi.

        Khi số các bit 1 trong byte là chẵn thì bít Odd Parity Bit = 1 và bít lẻ = 0,..
        Một số dạng khác không phổ biến là dùng một số khác nhau của số bít dữ liệu. Rất nhiều cổng nối tiếp hỗ trợ mọi nơi từ 5 ->8 bít dữ liệu, cộng với bít chẵn lẻ.

        Tốc độ số bít là số bít một giây được truyền đi hoặc là nhận về trong một đơn vị thời gian. Tốc độ bus là số các sự kiện hình xảy ra hoặc truyền dữ liệu trên giây. Hai giá trị này thường đồng nhất với nhau trong nhiều liên kết. Trong đường dây điện thoại, môdem tốc độ cao mã hoá nhiều bít trong mỗi chu kì dữ liệu vì thế tốc độ bus thực tế nhỏ hơn tốc độ bit( bit rate).

        Mọi bít cần thiết cho truyền một giá trị từ bít Start đến bít Stop gọi là một Word. Mỗi bít trong dạng Word gọi là một Character. Trong vài liên kết, các bít là kí tự văn bản( dạng chữ hoặc số), trong khi các dạng kí tự khác lại là giá trị nhị phân. Thời gian truyền các các kí tự trong một giây bằng với tổng thời gian truyền từng bít trong word cộng lại. Thêm bít start và bít Stop làm tăng thời gian truyền mỗi byte lên 25% ( vì có 10 bít cần truyền trong khi chỉ dùng có 8 bít). Với định dạng 8-N-1, một byte truyền với thời gian bằng 1/10 tần số bus: do đó 9600 bít/s truyền 960 byte/s.

        Nếu nơi nhận đòi hỏi phải có một thời gian kiểm tra dữ liệu nhận đuợc, nơi truyền sẽ kéo dài độ rộng của bít Stop ra 1,5 hoặc 2 bít.

        Hôm sau tôi sẽ giới thiệu cho các bạn bài về các định dạng truyền dữ liệu kiểu nhị phân và văn bản, cách thức để chống mất dữ liệu.
        Last edited by ngohaibac; 04-05-2007, 01:02.
        Technical sale at WT Microelectronics S'pore
        Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
        Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

        Comment


        • #5
          Cơ chế chống mất dữ liệu

          Cảm ơn sự động viên của anh Công. Sợ đụng hàng thì chết. Thế thì em sẽ tiếp tục chủ đề này.

          Tôi xin giới thiệu cho các bạn cơ chế chống mất dữ liệu trong khi truyền nhận dữ liệu giữa các nút trong mạng lưới:

          Phần lớn các máy tính trong mạng nối tiếp có nhiều việc phải làm bên cạnh việc chờ nhận dữ liệu. Ví dụ, mỗi đơn vị dữ liệu có thể thu thập theo chu kì và lưu trữ dữ liệu tới khi một mắt xích khác trong mạng yêu cầu dữ liệu này. Hoặc một điều khiển có thể đáp ứng các điều kiện điều khiển và điều hành, thỉnh thoảng lại nhận thông tin hoặc nhận các yêu cầu từ trong mạng.

          Một máy tính muốn truyền dữ liệu trong khi một máy nhận khác đang bận với các công việc khác. Việc thiết kế mạng phải đòi hỏi rằng mỗi nơi nhận có thể biết được dữ liệu nào chuyển đến nó và tất cả mọi dữ liệu đến máy nhận phải không có lỗi.

          Có nhiều cách làm để thực hiện điều đó, bao gồm bắt tay( handshaking), bộ đệm( buffering), dùng dò( polling) và ngắt( interrupts) để phát hiện dữ liệu đã đến, kiểm soát lỗi( error checking), và thừa nhận dữ liệu đã tới( acknowledging). Mỗi liên kết có thể dùng một hoặc nhiều cách trong số những cách này.

          Bắt tay( handshaking):

          Với tín hiệu bắt tay, máy phát có thể xác định khi nào máy tính này phải truyền dữ liệu và máy nhận có thể biết khi nào nó sẵn sàng nhận dữ liệu. Tín hiệu có thể biến đổi qua RS-232 hoặc RS-485 theo giao thức chuẩn hoặc giao thức qui ước.

          Một trong những dạng bắt tay về phần cứng, nơi nhận đưa ra dòng mức cao khi sẵn sàng nhận dữ liệu, và nơi truyền chờ tín hiệu này trước khi truyền dữ liệu. Nơi nhận có thể đưa ra dòng mức thấp trong mọi thời điểm, thậm chí cả trong quá trình chờ dòng phản hồi cao trước khi kết thúc quá trình truyền nhận. Một số dạng liên kết khác hoạt động giống nguyên tắc ở trên nhưng với bắt tay bằng phần mềm, bằng cách nơi nhận gửi một mã để báo nó sẵn sàng nhận dữ liệu, và một mã khác để báo báo cho nơi truyền dừng quá trình gửi dữ liệu.

          Bộ đệm( Buffer):

          Bộ đệm là một dạng khác để nơi nhận có thể chắc chắn là không mất một dữ liệu nào gửi đến chúng. Bộ đệm có thể có ích cho phía truyền, nơi cho phép ứng dụng làm việc có hiệu quả bằng cách lưu trữ dữ liệu để gửi khi liên kết sẵn sàng để truyền nhận dữ liệu.

          Bộ đệm có thể là bộ đệm phần cứng, phần mềm hoặc cả hai. Cổng nối tiếp dùng tất cả các dạng này nhưng máy tính cổ nhất có 16 byte bộ đệm phần cứng được tích hợp trong những UART. Trong chiều nhận, điều đó có nghĩa rằng UART có thể lưu trữ 16 byte trước khi phần mềm cần đọc chúng. Trong chiều nhận, UART có thể lưu trữ 16 byte và UART sẽ cẩn thận truyền mỗi byte theo từng bít tứng bít theo giao thức lựa chọn.

          Khi bộ đệm phần cứng không đủ rộng, một máy tính cá nhân có thể dùng bộ đệm phần mềm, bộ đệm này có thể lập trình được kích thước và kích thước tối đa cho phép bởi bộ nhớ hệ thống. Các thiết bị phần mềm của cổng truyền nhận dữ liệu giữa bộ đệm phần cứng và phần mềm.

          Trong các vi điều khiển, bộ đệm có xu hướng trở nên nhỏ hơn, và một số chip không có bộ đệm phần cứng. Việc làm hẹp bộ nhớ đệm điều quan trọng hơn ở đây là các chíp này dùng các công nghệ khác để chắc chắn là không dữ liệu nào bị mất.

          Thăm dò và ngắt:

          Sự kiện gây ra ở cổng nối tiếp bao gồm khi truyền và nhận dữ liệu, thay đổi tín hiệu bắt tay, và gửi , nhận thông điệp lỗi. Có hai cách cho ứng dụng phát hiện và gây ra những sự kiện này.

          Các thứ nhất là có chương trình tự động nhảy tới các chuỗi sự kiện được sắp xếp trước( như bảng vector ngắt) khi một sự kiện xảy ra. Ứng dụng phản ứng nhanh và tự động hoạt động ở cổng mà không lãng phí thời gian kiểm tra, chỉ cần biết như không có hoạt động nào xảy ra.

          Dạng lập trình này gọi là chạy đua sự kiện( event-driven) bởi vì một sự kiện bên ngoài có thể xảy ra trong bất kì thời điểm nào và chương trình chạy tới một bảng đặc biệt.

          Trong VB, sự kiện OnComm của MSComm( Microsoft Communication Control 6.0 - Điều khiển ActiveX) làm công việc này. OnComm chạy đáp ứng lại ngắt phần cứng hoặc bộ đếm của bộ đệm phần mềm đạt tới giá trị xảy ra sự kiện. Nhiều bộ vi điều khiển có ngắt phần cứng dùng với mục đích này.

          Cách thứ hai là thăm dò bằng cách đọc theo từng chu kì hoặc phát ra tín hiệu tìm kiếm khi nào một sự kiện xảy ra. Dạng lập trình này gọi là lập trình thủ tục, và không dùng ngắt phần cứng. Ứng dụng phải chắc chắn thăm dò cổng một cách đầy đủ để không mất bất kì một dữ liệu nào hoặc sự kiện nào. Tần số thăm dò phụ thuộc vào kích thước bộ đệm và tổng dữ liệu cần lấy( cần cho phản ứng nhanh). Ví dụ, nếu một thiết bị có 16 byte bộ đệm và dò cổng 1 lần/1 giây, thiết bị này chỉ có thể nhận không thể lớn hơn 16 byte/ 1 giây hoặc là bộ đệm sẽ bị tràn hoặc là dữ liệu sẽ bị mất.

          Phương pháp thăm dò thường áp dụng cho truyền dữ liệu ngắn, đột ngột hoặc khi máy tính gửi dữ liệu và chớ đợi tín hiệu phản hồi nhanh. Một giao diện thăm dò không yêu cầu ngắt phần cứng, và bạn có thể chạy dạng lập trình này ở trên cổng mà không có đường ngắt. Nhiều giao diện thăm dò dùng ngắt timer của hệ thống để có kế hoạch đọc cổng sau một khoảng thời gian cố định.
          Last edited by ngohaibac; 04-05-2007, 01:04.
          Technical sale at WT Microelectronics S'pore
          Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
          Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

          Comment


          • #6
            Cơ chế chống mất dữ liệu(tiếp)

            Thừa nhận( Actknowledgments):

            Một vài liên kết có các nút chấp nhận mệnh lệnh mà không có một phản ứng nào, nhưng bình thường nó có ích cho nút nhận để cho bên truyền biết rằng một thông điệp
            đã truyền qua, thậm chí nếu bên nhận không có một thông tin nào phản hồi. Sự thừa nhận này đặc biệt có ích trong mạng lưới, khi có nhiều nút chia sẻ cùng đường truyền thông và nơi truyền đang chuyển đổi tại thời gian không đúng có thể cản trở một thông điệp của nơi truyển khác.

            Actknowledgments có thể là một byte đã được định nghĩa sẵn, như là một giá trị mà đã đồng hoá với bên nhận, hoặc là nút truyền có thể cho rằng có một nút nhận đuợc thông điệp của nó khi nó nhận được yêu cầu dữ liệu đáp lại. Nếu nút truyền không nhận được phản ứng phản ứng mà nó yêu cầu, nút này sẽ cho rằng có một lỗi và truyền lại hoặc là làm các công việc khác.

            Khi truyền tới một nút mà không có bộ đệm nhận hoặc có bộ đệm kích thước nhỏ, bên truyền có thể dùng Actknowlegments để chắc chắn rằng sẽ có sự tham gia của nút nào đó vào quá trình truyền nhận trước khi gửi một gói dữ liệu. Nút truyền bắt đầu bằng cách gửi một byte tới tín hiệu mà nó muốn gửi dữ liệu. Khi nút nhìn thấy byte, nút này gửi một Actknowlegment và sau đó tập trung vào việc xem xét ở đầu vào nối tiếp của nó. Khi nơi nhận nhận được Actknowgment , nó biết rằng đã an toàn và yên tâm cho việc gửi dữ liệu.

            Kiểm tra lỗi(Error Checking):

            Bên nhận có thể dùng Error- Checking để kiểm tra rằng mọi dữ liệu đến đúng đích. Cách để kiểm tra thông điệp lỗi bao gồm gửi dữ liệu bản sao và byte kiểm tra lỗi.

            Một dạng đơn giản kiểm tra lỗi đơn giản là dùng dữ liệu bản sao. Bên truyền gửi mỗi thông điệp 2 lần và bên nhận kiểm tra để xác định rằng 2 thông điệp này đều giống nhau trong cả 2 lần. Tất nhiên, điều đó có nghĩa rằng mỗi thông điệp sẽ mất gấp đôi thời gian truyền. Nó quả thật là hữu ích khi gửi một dữ liệu ngắn quan trong thỉnh thoảng, bất chợt. Nhiều điều khiển hồng ngoại dùng dạng thức này.

            Mộtcách thức khác của eror-checking là gửi một byte kiểm tra lỗi cùng với dữ liệu. Checksum tính toán bằng cách thực hiện một vài phép tính toán số học hoặc logic trên byte đó trong thông điệp. Vì thế sẽ thêm một byte kiểm tra vào trong mỗi byte của thông điệp và dùng byte sau cùng để làm kết quả của sự kiểm tra.

            Nơi nhận lặp đi lặp lại quá trình tính toán này, và nếu nó nhận được các kết quả khác nhau thì có nghĩa rằng nó không nhận được đúng dữ liệu đã gửi.
            Một dạng khác của byte kiểm tra là CRC( cyclic redundancy code ) dùng nhiều tính toán phức tạp và thực tế hơn nhiều so với checksum. Một vài giao thức phổ biến dùng trong file truyền đi là Kermit, Xmodem, Ymodem, và Zmodem.

            Khi một nút phát hiện lỗi hoặc nhận được thông điệp mà nó không hiểu, nó sẽ có gắng thông báo cho nút gửi dữ liệu để báo rằng nút này có thể truyền thử lại hoặc truyền dữ liệu khác để trả lời trong hoàn cảnh này. Sau một số lần cố gằng gửi, nếu nút truyền đủ biết để giữ nút để hiển thị một thông điệp lỗi, một âm thanh báo hiệu, hoặc làm điều gì đó để cho con người biết hoạt động của lỗi và sau đó tiếp tục với trách nhiệm tốt nhất mà nó có thể làm được.

            Nút nhận nên biết phải làm gì với thông điệp ngắn hơn so với mong đợi. Dù đợi mãi cho thông điệp kế thúc, nó phải có sự kiện time out và để cho nơi điều hành biết là có một lỗi. Nơi điều hành có thể gửi lại sau đó hoặc là tiếp tục. Nếu không thì mạng có thể bị treo trong sự chờ đợi kết thúc.
            Last edited by ngohaibac; 04-05-2007, 01:05.
            Technical sale at WT Microelectronics S'pore
            Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
            Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

            Comment


            • #7
              Giới thiệu điều khiển ActiveX MSComm

              MSComm trong VB dùng điều khiển truyền thông nối tiếp. Điều khiển này có trong bản VB Proessional và Enterprise editions, nhưng không có trong phiên bản Learning editions( giá rẻ nhất). Điều khiển này dễ dàng trong lập trình và hoạt động tốt hơn các dạng truy suất cổng khác. Nếu là bản đầy đủ các bạn dễ dàng tìm được điều khiển này trong Project-> Component( Ctr-T) Chọn Microsoft Comm Control 6.0

              Các đặc tính của MSComm:

              Những tính chất của MSComm liên quan đến thiết lập cổng, truyền nhận dữ liệu, dùng tín hiệu bắt tay, hoặc đồng nhất các điều khiển. Các tính chất của MSComm được sắp xếp theo chức năng:

              Thiết lập:
              • CommID: trả lại handles đồng nhất tới thiết bị truyền thông có kiểu Long. Tính chất này không có lúc thiết kế mà chỉ có khi thi hành, thuộc tính này là ReadOnly.
              • CommPort: dạng object.CommPort = value. Value là chỉ số của cổng Com có giá trị từ 1 -> 16 và mặc định có giá trị =1. Các bạn cần phải thiết lập thông số này trước khi mở cổng. Sẽ có lỗi error 68 (Device unavailable) nếu như không mở được cổng này.
              • InBuferSize: thiết lập hoặc trả lại kích thước của bộ đệm nhận, tính =byte. Mặc định là 1024 byte. Các bạn không được nhầm lẫn với đặc tính InBufferCount là số byte đang chờ trong bộ đệm.
              • InputLen : object.InputLen [ = value ] thiết lập hoặc trả lại số byte mỗi lần thuộc tính Input đọc được. Mặc định giá trị Value=0 tức là thuộc tính Input sẽ đọc hết nội dung của bộ đệm khi nó được dùng. Nếu số kí tự trong bộ đệm nhận không = InputLen thì thuộc tính Input sẽ trả lại kí tự rỗng “”. Ví thế bạn cần phải chọn cách kiểm tra InBufferCount để chắc chắn số kí tự yêu cầu đã có đủ trước khi dùng lệnh .Input. Tính chất này rất là có ích khi đọc dữ liệu một máy mà dữ liệu ra được định dạng bằng các khối có chiều dài cố định.
              • InputMode: object.InputMode [ = value ] . Value = 0 hay = comInputModeText dữ liệu nhận được dạng văn bản kiểu kí tự theo chuẩn ANSI. Dữ liệu nhận được sẽ là một sâu.
              • Value=1 hay = comInputModeBinary dùng nhận mọi kiểu dữ liệu như kí tự điều khiển nhúng, kí tự NULL,.. Giá trị nhận được từ Input sẽ là một mảng kiểu Byte.
              • NullDiscard: object.NullDiscard [ = value ] tính chất này quyết định kí tự trống có được truyền từ cổng đến bộ đệm nhận hay không. Nếu value= True kí tự này không được truyền. value = false kí tự trống sẽ được truyền. Kí tự trống được định nghía theo chuẩn ASCII là kí tự 0 – chr$(0).
              • OutBuferSize: giống như InBuferSize, mặc định là 512.
              • ParityReplace: thiết lập và trả lại kí tự thay thế kí tự không đúng trong lỗi giống nhau.
              • PortOpen: thiết lập và trả lại tính trạng của cổng(đóng hoặc mở). object.PortOpen [ = value ] value = true cổng mở. =false cổng đóng và xóa toàn bộ dữ liệu trong bộ đệm nhận và truyền. Cần phải thiết lập thuộc tính CommPort đúng với tên của cổng trước khi mở cổng giao tiếp. Thêm vào đó cổng giao tiếp của thiết bị của bạn phải hỗ trợ giá trị trong thuộc tính Setting thì thiết bị của bạn mới hoạt động đúng, còn không thì nó sẽ hoạt động rất dở hơi nếu không nói là nó chạy không tốt. Đường DTR và RTS luôn giữ lại trạng thái của cổng.
              • RthresHold: object.Rthreshold [ = value ] value kiểu số nguyên. Thiết lập số kí tự nhận được trước khi gây lên sự kiện comEvReceive. Mặc định =0 tức là không có sự kiện OnComm khi nhận được dữ liệu. Thiết lập = 1 tức là sự kiện OnComm xảy ra khi bất kì kí tự nào bị thay thế trong bộ đệm nhận.
              • Settings: object.Settings [ = value ] thiết lập hoặc trả lại các thông số tần số baud, bít dữ liệu, bít chẵn lẻ, bít stop. Nếu Value không có giá trị khi mở sẽ gây ra lỗi 380 (Invalid property value).

                Value có dạng "BBBB,P,D,S". Trong đó, BBBB là tần số bus, P : thiết lập bít đồng bộ, D: số bít dữ liệu, S: số bít stop.
                Mặc định của nó là : "9600,N,8,1"

                Sau đây là một số tần số bus 110,300,600,1200,2400,4800,9600( mặc định), 1400,19200,28800,38400,56000,115200,128000,256000.
                Các giá trị của P: E( even), M: mark, N: none( mặc định), O: old, S: Space.
                D : có giá trị từ 4-> 8( mặc định).
                S: số bít stop có giá trị 1, 1.5, 2;
              • SThreshold: thiết lập và và trả lại số kí tự nhỏ nhất được cho phép trong bộ đệm gửi để xảy ra sự kiện OnComm = comEvSend . Theo mặc định giá trị này = 0 tức là khi truyền sẽ không gây ra sự kiện OnComm. Nếu thiết lập thông số này =1 thì sự kiện OnComm xảy ra khi bộ đệm truyền rỗng. Sự kiện OnComm = comEvSend chỉ xảy ra khi mà số kí tự trong bộ đệm truyền nhỏ hơn hoặc = Sthreshold. Nếu số kí tự trong bộ đệm này luôn lớn hơn Sthreshold thì sự kiện này không thể xảy ra.
              Last edited by ngohaibac; 04-05-2007, 01:08.
              Technical sale at WT Microelectronics S'pore
              Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
              Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

              Comment


              • #8
                Giới thiệu điều khiển ActiveX MSComm( tiếp)

                Truyền nhận dữ liệu:
                + CommEvent: trả lại phần lớn sự kiện giao tiếp hoặc có lỗi. CommEvent xảy ra khi có lỗi hoặc khi xảy ra sự kiện nào đó. Sau đây là một số hằng số lỗi:


                comEventBreak 1001 A Break signal was received.
                comEventFrame 1004 Framing Error. The hardware detected a framing error.
                comEventOverrun 1006 Port Overrun. A character was not read from the hardware before the next character arrived and was lost.
                comEventRxOver 1008 Receive Buffer Overflow. There is no room in the receive buffer.
                comEventRxParity 1009 Parity Error. The hardware detected a parity error.
                comEventTxFull 1010 Transmit Buffer Full. The transmit buffer was full while trying to queue a character.
                comEventDCB 1011 Unexpected error retrieving Device Control Block (DCB) for the port.

                Một số sự kiện :

                Constant Value Description
                comEvSend 1 There are fewer than Sthreshold number of characters in the transmit buffer.
                comEvReceive 2 Received Rthreshold number of characters. This event is generated continuously until you use the Input property to remove the data from the receive buffer.
                comEvCTS 3 Change in Clear To Send line.
                comEvDSR 4 Change in Data Set Ready line. This event is only fired when DSR changes from 1 to 0.
                comEvCD 5 Change in Carrier Detect line.
                comEvRing 6 Ring detected. Some UARTs (universal asynchronous receiver-transmitters) may not support this event.
                comEvEOF 7 End Of File (ASCII character 26) character received.



                + EOFEnable: object.EOFEnable [ = value ] quyết định các hành động nếu MSComm tìm thấy kí tự kết thúc file. Nếu value=true khi tìm thấy kí tự kết thúc file thì sẽ gây lên sự kiện comEvEOF trong OnCommEvent. Nếu value= false thì sẽ không gây lên sự kiện này.

                + InBufferCout: trả lại số kí tự đang có trong bộ đệm nhận Bạn có thể xoá bộ đệm nhận bằng cách đặt thuộc tính này =0 . Không nhầm với thuộc tính InBufferSize là tổng kích thước của bộ đệm nhận.

                + Input: nhận và xoá dữ liệu trong bộ đệm nhận.Nếu InputMode là comInputModeText thì giá trị trả về sẽ là một xâu tức có kiểu String , dữ liệu dạng text trong một biến kiểu Variant. Nếu InputMode = comInputModeBinary thì thuộc tính này sẽ trả lại dữ liệu dạng nhị phân dưới dạng một mảng kiểu byte trong một biến Variant.

                + OutBufferCount: trả lại số kí tự trong bộ đệm truyền.

                + Output: ghi dữ liệu vào bộ đệm truyền. có thể truyền kiểu text hoặc kiểu nhị phân. Nếu truyền bằng kiểu text thì cho một biến Variant = kiểu String, nếu truyền kiểu nhị phân thì cho cho Output= variant = một mảng kiểu Byte.
                Bắt tay( handshaking):

                + Break : thiết lập hoặc xoá tín hiệu. object.Break [ = value] value = true hoặc false. Khi set value= true thì thông số Break này sẽ gửi một tín hiệu break. Tín hiệu break trì hoàn việc truyền dữ liệu và đưa đường truyền vào trạng thái break tới khi mà value = false.

                + CDHolding: quết định xem sự truyền này đến đâu bằng cách truy vấn đường CD( Carrier Detect). Carrier Detect là tín hiệu gửi từ modem tới máy tính kết nối với nó thống báo rằng nó đang online. Nếu giá trị = true thì nó đường CD đang ở mức cao, nếu = false thì đường dây này đang ở mức thấp. Tính chất này không có trong lúc thiết kế chỉ có trong khi chạy chương trình.
                Carrier Detect được biết như là Receive Line Signal Detect (RLSD).

                + CTSHolding: quết định khi nào bạn gửi dữ liệu bằng cách truy vấn trạng thái đường Clear To Send (CTS). Thông thường tín hiệu CTS được gửi từ modem tới máy tính kết nối với nó để báo rằng đang quá trình truyền dữ liệu. Thuộc tính Readonly chỉ xuất hiện khi chạy chương trình. Đường Clear To Send dùng trong RTS/CTS (Request To Send/Clear To Send) bắt tay phần cứng. CTSHolding cho bạn một cách để tự tay dò đường Clear To Send nếu bạn cần biết trạng thái của nó.

                + DSRHolding: biết trạng thái của đường Data Set Ready (DSR). Tín hiệu Data Set Ready truyền từ modem tới máy tính nối với nó để thông báo rằng modem đã sẵn sàng hoạt động. Tính chất này dùng khi viết Data Set Ready/Data Terminal Ready handshaking routine cho máy Data Terminal Equipment (DTE)- máy trang bị đầu cuối dữ liệu.

                + DTREnable: tính chất này quyết định khi nào cho phép đường Data Terminal Ready (DTR) trong truyền thông. Tín hiệu DTR gửi từ máy tính tới modem đẻ báo rằng máy tính sẵn sàng là nơi nhận dữ liệu. Khi DTREnable = true thì đường Data Terminal Ready set lên cao khi cổng mở, và thấp khi cổng đóng. Nếu DTREnable = false thì đường đó luôn mức thấp. Trong phần lớn trường hợp set đường Data Terminal Ready thành thấp để hang up telephone.

                + Handshaking: thiết lập và trả lại giao thức bắt tay phần cứng. object.Handshaking [ = value ].
                Các giá trị của value:

                Setting Value Description
                comNone 0 (Default) No handshaking.
                comXOnXOff 1 XON/XOFF handshaking.
                comRTS 2 RTS/CTS (Request To Send/Clear To Send) handshaking.
                comRTSXOnXOff 3 Both Request To Send and XON/XOFF handshaking.

                Handshaking chỉ là giao thức truyền thông nội tại quyết định bởi dữ liệu nào được truyền từ cổng phần cứng tới bộ đệm nhận. Khi kí tự của dữ liệu tới cổng nối tiếp, thiết bị truyền thông sẽ chuyển nó vào trong bộ đệm nhận và chương trình của bạn có thể đọc chúng. Nếu không có bộ đệm dữ liệu hoặc chương trình của bạn cần đọc kí tự trực tiếp từ phần cứng , bạn có thể mất dữ liệu bởi vì kí tự từ phần cứng đến rất nhanh. Giao thức Handshaking đảm bảo dữ liệu không bị mất, khi dữ liệu đến cổng quá nhanh thì thiết bị truyền thông sẽ chuyển dữ liệu vào trong bộ đệm nhận.

                + RTSEnable: quết định khi nào cho phép đường Request To Send (RTS), Tín hiệu RTS từ máy tính tới modem để yêu cầu được tryền dữ liệu. Khi RTSEnable = true thì đường RTS mức cao khi cổng mở, tích mức thấp khi cổng đóng. Và hiển nhiên khi RTSEnable thì đường RTS luôn mức thấp.RTS dùng trong RTS/CTS hardware handshaking. RTSEnable cho phép bạn dò đường RTS khi cần biết tình trạng của đường này.

                Các tính chất trên không có lúc thiết kế giao diện mà chỉ có lúc chạy chương trình ( dùng trong viết code).

                Ngoài ra còn có các thuộc tính khác như với các loại điều khiển khác:
                Index: thiết lập và trả về một số xác định thứ tự nếu form bạn có nhiều điều khiển như thế này.
                , Name: tên điều khiển, Object, Parent: trả về form hoặc đối tượng mà điều khiển này nằm trên đó,
                Tag: thiết lập và trả về một biểu thức. Người dùng định nghĩa

                Chắc các bạn đã có phần nào hiểu biết về điều khiển ActiveX này.
                Last edited by ngohaibac; 28-12-2005, 17:47.
                Technical sale at WT Microelectronics S'pore
                Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                Comment


                • #9
                  Truyền dữ liệu kiểu text và nhị phân trong VB

                  Chào các bạn hôm nay tôi lại tiếp tục giới thiệu cho các bạn hiểu về cách truyền, nhận dữ liệu dạng text và binary trong VB.

                  Trước hết, các bạn cần biết biến kiểu Variant( tra trong từ điển có nghĩa là tương tự, gần giống nhau). Do vậy mà một biến Variant có thể gán = bất kì kiểu gì cũng được.Sau đây là chi tiết về 2 vấn đề chính:

                  VB cho phép bạn truyền dữ liệu dạng Text hay là dạng Binary. Thuộc tính InputMode quyết định điều khiển MSComm dùng dạng nào.


                  1.Kiểu văn bản( Text):


                  Với thuộc tính InputMode = comInputModeText thì MSComm sẽ gửi và nhận dữ liệu dạng xâu theo chuẩn ANSI ( không phải chuẩn ASCII). Để gửi một xâu ra port, bạn cần phải cho thuộc tính Output của MSComm = 1 xâu. Ví dụ:

                  Code:
                  	Dim SampleText as String
                  	‘ví dụ bạn muốn truyền một xâu “ABC”
                  	SampleText = “ABC”
                    	‘ gửi kí tự này ra cổng
                   	MSComm1.Output = SampleText
                  MSComm gửi một mã ANSI 8 bít cho mỗi kí tự trong xâu mà bạn gửi. Để đọc một xâu từ cổng, cần đặt một xâu = thuộc tính Input của MSComm. Ví dụ bạn muốn đọc dữ liệu từ cổng và ghi vào một biến SampleText có kiểu String:

                  Code:
                  Dim SampleText as String
                  SampleText = MSComm1.Input ‘ khi đó SampleText sẽ là dữ liệu đọc được
                  MSComm lưu trữ mỗi mã ANSI 8 bít như một kí tự văn bản.
                  Thực tế như các bạn đã biết thì giá trị truyền cho MSComm1.Output phải là kiểu Variant. Ở đây thuộc tính Output chấp nhận kiểu một biến Variant chứa một xâu kí tự và MSComm sẽ đọc xâu kí tự và gán tự động vào một biến Variant vì Variant chính là kiểu của Output. Nói cách khác ở đây có sự chuyển kiểu ngầm định giữa kiểu String sang kiểu Variant.

                  Ngay ở bên trong bản thân chương trình VB lại lưu trữ xâu dưới dạng mã Unicode 16 bít nhưng sự chuyển đổi giữa kiểu Unicode và kiểu xâu kí tự ANSI 8 bít của MSComm diễn ra một cách tự động.


                  Sự chuyển kiểu của số ASCII Hex:


                  Số ASCII Hex là số hexa bình thường mà ta vẫn dùng như 0xA5( trong C,C++) hoặc 0A5h( trong ASM,..) đại diện cho số 165 trong hệ Decimal( 165 = 16*10+ 5).

                  Với các ứng dụng dùng định dạng ASCII Hex, VB có một hàm chuyển đổi giữa kiểu xâu ASCII Hex và giá trị mà nó đại diện. Toán tử Hex$ chuyển đổi một số sang dạng kí tự ASCII Hex:

                  Ví dụ, để kiểm tra bạn có thể dùng hàm rất đơn giản xem nó in ra thế nào :
                  Code:
                  debug.print Hex$(165)
                  thì kết quả sẽ hiện trên một Dialog là : A5
                  Toán tử Val chuyển đổi từ kiểu ASCII Hex sang kiểu giá trị của xâu đó:
                  Ví dụ: ta thấy 0xA5 = 165 để thử xem có đúng không dùng lệnh;
                  Code:
                     debug.print Val(“&h” & “A5”)
                  Kết quả là 165.

                  Xâu đầu tiên “&h” được thêm vào để báo cho VB biết để đối xử với giá trị đưa ra sau đó như là một số hexadecimal.’

                  2. Kiểu nhị phân( Binary Mode):

                  Để truyền dữ liệu dưới dạng nhị phân, cần thiết lập thuộc tính InputMode của MSComm thành comInputModeBinary.

                  VB cung cấp một kiểu dữ liệu kiểu Byte để lưu trữ dữ liệu nhị phân. Các byte được ghi và đọc từ cổng nối tiếp được lưu trữ trong một biến Variant( nội dung của nó chứa một mảng mà các phần tử của mảng có kiểu Byte). Thậm chí nếu chí đọc, ghi duy nhất có 1 byte thì dữ liệu này cũng phải đặt trong một mảng byte, chứ không đuợc lưu trữ trong một biến kiểu byte thông thường. Để ghi một mảng kiểu byte ra cổng nối tiếp gồm 2 bước.

                  + Bước đầu: lưu trữ mảng kiểu byte vào một biến variant

                  + Bước 2: gửi dữ liệu đi bằng cách thiết lập thông số Output của MSComm bằng biến Variant đó.

                  Code:
                  	Dim BytesToSend(0 to 1) as Byte ‘ khai báo một mảng 2 phần tủ
                  	Dim Buffer as Variant
                  	‘ lưu trữ dữ liệu vào mảng kiểu byte ở trên
                  	BytesToSend(0) = &H4A
                  	BytesToSend(1) = &H23
                  	‘ cho vào một biến Variant
                  	Buffer = BytesToSend()
                  	‘ghi vào cổng nối tiếp
                  	MSComm1.Output = Buffer
                  Để đọc các byte tại cổng nối tiếp, bạn cũng làm tương tự như trên, đọc vào một biến Variant sau đó cho một mảng = biến đó.
                  Code:
                  	Dim BytesReceived()  as Byte ‘ khai báo một mảng động
                  	Dim Buffer as Variant ‘ khai báo biến variant
                  	‘đọc dữ liệu từ cổng nối tiếp
                  	Buffer = MSComm1.Input
                  	‘ ghi dữ liệu đọc được vào mảng động
                  	BytesReceived() = Buffer
                  Các ban lưu ý là phải khai báo một mảng byte động. Có 2 cách để chuyển đổi giữ mảng bytes và kiểu Variant. Bạn có thể cho một biến = một biến có số chiều đã được biết và VB làm công việc chuyển đổi này tự động:

                  Code:
                  Dim DimensionedArray(15) as Byte ‘ mảng đã khai báo số chiều =15
                  Dim DynamicBytesArray()  as Byte
                  Dim Buffer As Variant
                  Dim Count As Integer
                  ‘ lưu trữ một mảng mảng vào một biến variant. Mảng này đã được biết số phần tử
                  Buffer = DimensionedArray() 
                  
                  ‘để sao chép nội dung của một biến variant vào một mảng thì mảng này phải khai báo là một mảng động( chưa biết số phần tử)
                  DynamicBytesArray() = Buffer
                  Đối với VB 6.0 bạn hoàn toàn có thể gán 2 mảng với nhau vì nó sẽ tự sao chép nội dung từ mảng nguồn sang mảng đích mà không cần phải làm bằng cách sao chép từng phần tử của 2 mảng cho nhau( như trong C thì bạn phải làm điều này rồi vì gán 2 tên mảng thực chất là bạn chỉ là cho con trỏ mảng đích trỏ vào địa chỉ của phần tử của mảng nguồn thôi, đây là sự sao chép bề mặt). Tuy nhiên bạn vẫn có thể làm điều này trong VB:

                  Code:
                  ‘lưu trữ một mảng kiểu byte trong một biến variant
                  Buffer = CVar(DynamicByteArray()) 
                  ‘ CVar   -> Convert to Variant  Chuyển thành kiểu variant
                  
                  
                  ‘lưu nội dung của biến variant này trong một mảng kiểu byte
                  For Count = 0 to (LenB(Buffer)-1)
                  	DimmensionedArray(Count) = CByte(Buffer(count))
                  Next Count
                  ‘ CByte -> Convert to Byte chuyển kiểu thành kiểu Byte
                  Last edited by ngohaibac; 04-05-2007, 01:15.
                  Technical sale at WT Microelectronics S'pore
                  Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                  Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                  Comment


                  • #10
                    Gửi nhận dữ liệu bằng phương pháp dò

                    Tiếp theo tôi xin giới thiệu cho các bạn phương pháp lấy dữ liệu bằng phương pháp thăm dò( polling).
                    Giao tiếp tại cổng bằng phương pháp dò tức là bạn chỉ đọc hoặc ghi ra cổng khi nào cần bằng cách dùng thuộc tính Input hoặc Output của MSComm.

                    1. Gửi dữ liệu:


                    Thuộc tính Output dùng để ghi dữ liệu ra cổng. Biến dùng ở bên phải cú pháp là một biến kiểu Variant.
                    Đây là cú pháp để ghi dữ liệu:
                    Code:
                    	Dim DataToWrite As Variant
                    	MSComm1.Output = DataToWrite
                    Khi gửi một khối nhỏ dữ liệu, cần phải thiết lập thuộc tính OutBuferSize phải lớn hơn hoặc bằng số lượng lớn nhất các byte mà các bạn cần chuyển trong một lần.

                    Đối với việc truyền dữ liệu có tính lâu dài về thời gian dùng OutBufferCount để chắc chắn rằng bộ đệm không bị tràn. Khi bạn có nhiều dữ liệu cần gửi để tránh cho tràn bộ đệm , bạn nên đọc giá trị của OutBufferCount và so sánh với giá trị của OutBufferCount để kiểm tra xem bộ đệm còn bao nhiêu sau khi gửi dữ liệu đầu tiên. Sau đó làm đầy bộ đệm bằng cách ghi bằng đó các byte hoặc nhở hơn dữ liệu vào bộ đệm thì bộ đệm sẽ không bị tràn. Hoặc bạn có thể gửi dữ liệu đã đóng gói với kích thước xác định và chỉ gửi các gói này được OutBufferCount chỉ rằng có đủ chỗ trống trong bộ đệm cho gói dữ liệu này. Ví dụ, OutBufferSize = 1024 và kích thước 1 gói là 512, bạn chỉ có thể gửi được gói dữ liệu này khi mà OutBuferCount <= 512.

                    2. Nhận dữ liệu:

                    Để đọc dữ liệu được truyền đến, ứng dụng đọc dữ liệu từ InBuferCount theo từng chu kì. Khi bộ đếm chỉ rằng một số các kí tự mà ứng dụng cần đã đến( như muốn lấy 5 byte chẳng hạn) thì ứn dụng sẽ đọc dữ liệu với thuộc tính Input của MSComm:

                    Code:
                    Dim BytesToRead As Integer
                    Dim DataIn As Variant
                    
                    ‘thiết lập số byte cần đọc 
                    NumberOfBytesToRead = 512
                    MSComm1.InputLen = NumberOfBytesToRead
                    
                    ‘ dò bộ đệm nhận đến khi bộ đệm có đầy đủ số byte cần đọc
                    Do 
                    	DoEvents 
                    Loop Until MSComm1.InBufferCount> NumberOfBytesToRead
                    ‘ khi tổng số byte đã tới thì đọc lưu vào DataIn
                    DataIn = MSComm1.Input
                    Thuộc tính InBuferSize phải đủ độ rộng để cho lượng lớn nhất dữ liệu có thể tới mà không bị mất trước khi MSComm có thể đọc chúng. Nếu dữ liệu đến bằng các block với kích thước cố định thì cần thiết lập thuộc tính InBufferSize bằng bội số của kích thước 1 block.

                    Nếu tổng dữ liệu đến không biết kích thước thế nào, ứng dụng nên đọc bộ đệm nhận ngay khi bộ đệm chỉ nhận được 1 byte để tránh việc không kiểm soát đượcbộ đệm gây ra tràn dữ liệu. Chờ đợi nhiều byte để đọc là một việc làm không có hiệu quả bởi vì không có cách nào biết được byte nào sẽ đến cuối cùng. Nếu chờ nhiều hơn 1 byte rồi mới đọc, chương trình nên bao gồm có một “time out” chính là tổng thời gian từ lúc chờ mà tổng số byte vẫn không đến( như bạn chờ 6 byte mà mãi không đến chẳng lẽ ứng dụng chờ mấy giờ à, thế thì bạn cần phải qui định là sao bao nhiêu lâu thì đọc thôi chẳng cần chờ nữa).

                    Bạn có thể kết hợp phương pháp lập trình theo thủ tục và theo sự kiện bằng cách sử dụng timer để biết khi nào thì đọc cổng. Ví dụ, dùng một sự kiện Timer gây ra ở cổng đeer đọc cổng một lần / một giây.

                    Trên đây là cách đọc, ghi dữ liệu bằng phương pháp dò. Ngày mai tôi xin giới thiệu cho các bạn cách dùng ngắt(Interrupt), tức là dùng sự kiện OnComm của MSComm.
                    Last edited by ngohaibac; 04-05-2007, 01:18.
                    Technical sale at WT Microelectronics S'pore
                    Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                    Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                    Comment


                    • #11
                      Phương pháp dùng ngắt (Interupt) dùng OnComm của MSComm

                      Tiếp theo tôi xin giới thiệu với các bạn phương pháp thứ 2 là dùng ngắt( interrupt). Ở đây dùng chương trình con OnComm của MSComm. OnComm dùng để đáp ứng lại một vài sự kiện được gây ra tại cổng. Dùng OnComm chúng ta có thể kiểm tra dữ liệu được gửi đến hoặc gửi đi. Khi một trong 17 sự kiện gây ra tại cổng, ứng dụng sẽ tự động gây ra sự kiện ComEvent hay nói cách khác là gây ra một ngắt tại cổng và nhảy đến chương trình con OnComm của điều khiển ActiveX MSComm. Cách hiệu quả nhất để biết được sự kiện nào xảy ra là dùng Switch.. Case . Để đáp ứng một sự kiện xảy ra bạn có thể thêm các đoạn mã để thực hiện đọc, ghi dữ liệu trên cổng hoặc đơn giản chẳng làm gì cả. Phần lớn sự kiện của OnComm đáp ứng trực tiếp các sự kiện phần cứng được báo hiệu bởi các bit trong UART. Các sự kiện khác gây ra bởi phần mềm.

                      1. Nhận dữ liệu:


                      Trong chiều nhận, OnComm cung cấp một cách đơn giản và hiệu quả để phát hiện khi nào dữ liệu được nhận tại cổng. Thuộc tính Rtheshold của MSComm quyết định số kí tự ít nhất được nhận để gây ra sự kiện OnComm:

                      Code:
                      MSComm1.Rthreshold =1
                      Khi bộ đệm nhận bao gồm 1 hoặc nhiều kí tự, ứng dụng sẽ nhẩy đến chương trình con OnComm. Bảng ngắt có trách nhiệm phát hiện sự kiện ComEvReceive xảy ra và đọc kí tự trong bộ đệm:
                      Code:
                      		Case ComEvReceive
                      		Buffer = MSComm1.Input
                      Nếu bạn thiết lập thuộc tính RThreshold >1 thì những byte đến cuối cùng hoặc có rất là nhiều byte bạn vẫn không đọc đuợc( ví dụ bạn set =2, nếu bộ đệm nhận được 1 byte thì không có sự kiện nhận OnComm nên không chạy đoạn mã trên). Nên tốt nhất là sét thuộc tính này =1 nếu nhận được là biết ngay.

                      Thiết lập thuộc tính RThreshold = 0 thì sẽ vô hiệu hoá sự kiện ComEvReceive tức không dùng ngắt, và sẽ không có sự kiện nhận xảy ra.

                      2. Gửi dữ liệu:

                      Trong chiều gửi (send), bạn nên dùng sự kiện OnComm để kiểm soát dữ liệu gửi đi.

                      CPU có thể ghi ra cổng với tốc độ nhanh hơn tốc độ của cổng gửi dữ liệu nối tiếp ra ngoài( cho các thiết bị ngoại vi, vđk,..). Nếu tổng dung lượng của dữ liệu ghi ra cổng lớn hơn OutBufferSize thì ứng dụng không thể ghi tất cả dữ liệu vào bộ đệm một lần được, nếu cứ ghi vào thì bộ đệm sẽ bị tràn. Bạn có thể dùng OnComm để truyền đi một dung lượng lớn dữ liệu một cách có hiệu hiệu quả bằng cách luôn luôn phải đảm bảo cho bộ đệm truyền không bao giờ rỗng hoặc bị tràn.

                      Thuộc tính SThreshold quyết định số kí tự trong bộ đệm gửi sẽ gây ra sự kiện OnComm. Ví dụ:
                      Code:
                      MSComm1.SThreshold = 256
                      Cách truyền như sau: trong lần truyền đầu tiên dùng thuộc tính Output để điền đầy bộ đệm:
                      Code:
                      MSComm1.Output = DataToSend
                      Khi số kí tự trong bộ đệm giảm từ (SThreshold +1) xuống SThreshold thì sẽ gây ra sự kiện comEvSend và nhảy đến chương trình con OnComm. Dựa vào sự kiện comEvSend chúng ta lại truyền tiếp dữ liệu, cứ thế một dữ liệu dung lượng lớn sẽ được truyền đi.

                      Ví dụ chúng ta có bộ đệm truyền = 1024 byte mà chúng ta cần truyền một file có dung lượng 32k, ứng dụng có thể thiết lập SThreshold =256. Để gửi chúng ta làm như sau: lần đầu tiên ghi ra bộ đệm 1024 byte để làm đầy bộ đệm truyền và cổng bắt đầu gửi dữ liệu đi từng byte theo kiểu truyền từng bít một.Do đó số byte trong bộ đệm sẽ giảm dần. Khi trong bộ đệm vẫn còn 256 byte nữa thì sẽ gây ra sự kiện comEvSend và trong chương trình con MSComm ta có thể gửi tiếp một lượng dữ liệu mới = 1024-256 = 768 byte để làm đầy lại bộ đệm. Khi đó quá trình lại diễn ra liên tục đến khi ta gửi hết file đó thì thôi.

                      Nếu tổng dung lượng của thông tin cần gửi nhỏ hơn OutBufferSize thì không cần dùng OnComm trong trường hợp này. Ứng dụng có thể ghi trực tiếp dữ liệu vào bộ đệm nhận. Đó là cách đơn giản nhất nếu hệ thống có thể dành nhiều bộ nhớ cho bộ đệm. Nếu dành đuợc nhiều thì chúng ta cứ thoải mái tăng bộ đệm lên cho đơn giản. Thiết lập SThreshold = 0 để vô hiệu hoá sự kiện comEvSend và khi đó sẽ không có sự kiện gửi xẩy ra.

                      Như xem ở trên các bạn tưỏng rằng dùng sự kiện comEvSend là có ích, cần thiết cho bạn nhưng thực tế thì nó rất là phức tạp, và không nên dùng. Ví dụ, nếu vì một vài lí do mà CPU làm đầy bộ đệm với tốc độ chậm hơn tốc độ byte gửi đi từ cổng thì bộ đệm sẽ không bao giờ giữ được SThreshold byte trong bộ đệm và do đó sẽ không bao giờ xây ra sự kiện này vì sự kiện này chỉ xảy ra khi mà có sự thay đổi số byte trong bộ đệm giảm qua mức SThreshold byte. Trong trường hợp này thì các bạn nên dùng phương pháp thăm dò vì phương pháp thăm dò vì phương pháp thăm dò hiệu quả và thực tế hơn trong việc gửi dữ liệu.

                      Còn có rât nhiều sự kiện nữa như comEvCTS, comEvDSR,comEvCD, comEventRing, comEvEof, comEventBreak trong sự kiện bắt tay (Handshaking Events),Error Event nhưng tôi không nêu ra ở đây nữa khi nào dùng những sự kiện này thì tôi sẽ nói rõ hơn cho các bạn.

                      Trên đây là phương pháp dùng ngắt. Hẳn các bạn đã có được sự so sánh để lựa chọn cho mình đúng không. Vậy thì bây giờ tôi xin rút lại như sau: gửi dữ liệu thì nên = phương pháp dò, nhận dữ liệu có thể = ngắt hoặc = thăm dò.
                      Qua các bài ở trên chắc các bạn đã có một kiến thức chắc chắn hiểu về giao thức, cách truyền dữ liệu, tín hiệu bắt tay,.. trong truyền thông nối tiếp dùng cổng Com.

                      Còn nhiều vấn đề chúng ta cần quan tâm hơn.Tôi sẽ hướng dẫn các bạn lập trình từ những dạng rất đơn giản đến phức tạp như xác định cổng, ..Do vấn đề này rất hay và hơi dài nên tôi hẹn các bạn 2 hôm nữa( chủ nhật).

                      Chúc ngày cuối tuần vui vẻ.
                      Last edited by ngohaibac; 04-05-2007, 01:24.
                      Technical sale at WT Microelectronics S'pore
                      Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                      Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                      Comment


                      • #12
                        Bài viết của bác rất hay, em ko muốn cắt đứt nên bác cứ tiếp tục viết liền mạch, sau đó nếu có thời gian rỗi bác bàn luận và trả lời hộ em:
                        1-Nếu dùng ngắt để nhận dữ liệu ta đặt:MSComm1.SThreshold =1. Nêu truyền tốc độ cao rất dễ dẫn tới khi đọc thì số byte trong bộ đệm >1===> liệu có gây ra sai sót gì ko? giải pháp khắc phục.
                        2-Theo em:MSComm1.SThreshold =1 sẽ gây lãng phí cho thời gian của PC nhất là khi thiết lập ở tốc độ cao. Thông thường thiết bị ngoại vi ta biết trước về số byte tryền liền một lúc và giả sử = N. Nó sẽ truyền theo mô hình:
                        +Truyền hết N byte.
                        +Delay()
                        +Truyền tiếp N byte.
                        ....
                        Giả sử delay=100 ms thì:
                        +Truyền hết N byte.
                        +Trễ 100 ms.
                        +Truyền tiếp N byte.
                        ....
                        Vậy một giải pháp tối ưu là đặt:MSComm1.SThreshold =N. Thời gian delay của bên truyền sẽ khiến cho bên PC kịp thời xử lý. Nhưng nó sẽ có thể gặp phải một trường hợp xấu có thể xảy ra: bên phát truyền liên tục N byte nhưng bên thu chỉ nhận được <N byte(do đứt dây, do nhiễu, do thời điểm kết nối thì đúng lúc bên phát truyền dở...). Thời điểm này sẽ gây lỗi từ thời điểm đó về sau. Vậy một giải phát đưa ra dùng "timerout" giải quyết vấn đề này. Em đề cử một cách bác xem có chấp nhận được ko?
                        Bên PC: tại ngắt(nghĩa là nó nhận được N byte), đọc bộ đệm, khởi tạo một timer=100/2=50ms.
                        Hàm ngắt đọc dữ liệu viết như sau:
                        Private Sub MSComm1_OnComm()
                        On Error Resume Next
                        if(MSComm1.InBufferCount>=N) then
                        data = MSComm1.Input
                        end if
                        tmer1.interval=50
                        timer1.enable=true
                        End Sub


                        Hàm ngắt timer này viết như sau:
                        Private Sub Timer1_Timer()
                        Dim tam as string
                        tam=MSComm1.input 'Lam rong bo dem
                        timer1.enable=False 'Cam timer
                        End Sub

                        Giải pháp này ổn định nhưng ko vạn năng, nó chỉ áp dụng tốt khi thời gian truyền<delay(). Nên áp dụng cho trường hợp thỉnh thoảng truyền.

                        Vậy bác có giải pháp nào dùng ngắt và giải quyết được các nhước điểm trên ko? vì em sợ cái timer của Win lắm.

                        4-Liệu MSComm có một tính năng như sau ko?
                        +Có quy định được thời gian giữa 2 byte truyền? ví dụ em muốn truyền chữ chuỗi "sjahs" và mỗi byte cách nhau thời gian là 2 bit chẳng hạn? Ví dụ tốc độ 11500kbps.
                        Ví dụ: "s" --(delay 0.05ms) --"j"-----(delay 0.05ms)----"a"--...

                        5-Liệu MSComm có một tính năng như sau ko?
                        +Nếu mà có một sự kiện như sau thì tốt quá: ví dụ vi điều khiển truyền về PC một chuỗi theo quy luật sau:
                        byte1-----byte2....--delay ---byteN--delay(1ms)-- byte1---byte2...--delay ---byteN...
                        Vậy giá như bên MSComm có cài đặt một chế độ sau thì tốt biết mấy:PC liên tục nhận các byte bên VDK gửi sang, hễ nó thấy một thời điểm nào đó, 2 byte cách nhau quá 0.5ms nó sẽ nhảy vào ngắt nào ? cái này mà lamtimerout thì ko có gì hay hơn.
                        -------------------

                        Comment


                        • #13
                          Nếu viết như CHIBANG có lẽ là một farm tin không cần có byte start và stop (hè hè ) Các hãng trên thế giới này thua hết CHIBANG rồi !!!
                          Còn về Time out thì thường là 0.5 s trở lên(chuẩn ASCII là 1s)
                          Viết theo CHIBANG thì khi nào thành nhà tích hợp hệ thống mới dám nghĩ tới !!!
                          Bắc ! em viết rất tốt cố gắng lên.Anh đang bận thi nên không giúp gì được !!!
                          CHIBANG có lẽ bạn quá giỏi nên các nhà kinh điển trên thế giới không thể bằng bạn được
                          Last edited by vutricongbka; 16-12-2005, 19:48.

                          Comment


                          • #14
                            Phát nữa vutricongBka này:
                            Tớ vẫn làm timer out = 1.5*10 bit=15 bit tại tốc độ 19600 đó(<1ms cho timerout). Mạng 485: 1 vi điều khiển master+2 slaver vẫn chạy tốt cho đến bây giờ.
                            -------------------

                            Comment


                            • #15
                              gửi ChiBang

                              Thứ nhất, không hề có byte start và byte stop chỉ có bit start và stop thôi.
                              1-Nếu dùng ngắt để nhận dữ liệu ta đặt:MSComm1.SThreshold =1. Nêu truyền tốc độ cao rất dễ dẫn tới khi đọc thì số byte trong bộ đệm >1===> liệu có gây ra sai sót gì ko? giải pháp khắc phục.
                              SThreshold là tham số cho truyền dữ liệu mà bạn có liên quan với nhận đâu vì 2 bộ đệm truyền nhận là khác nhau.
                              Nếu bạn đánh nhầm là RThreshold = 1 .nếu thế thì bạn chưa biết về cách thức nhận dữ liệu bằng sử dụng ngắt của VB rồi. Bạn đọc lại bài ở trên về cách truyền nhận dữ liệu bằng ngắt đó. Tôi xin trả lời bạn chi tiết như sau: khi đặt SThreshold =1 tức là khi trong bộ đệm nhận có sự thay đổi số byte trong bộ đệm từ rỗng( empty) sang bắt đầu có dữ liệu ( 1 byte chuyển đến) và dữ liệu vẫn tiếp tục chuyển đến. Vì có sự chuyển đổi này gây ra sự kiện comEvReceive và nhảy đến thực hiện đoạn code viết trong hàm OnComm và trong hàm OnComm tất nhiên có mã để đọc nội dung của bộ đệm nhận này và làm bộ đệm lại bị rỗng. Do đó nếu lại nhận được dữ liệu nữa thì nó sẽ lại lặp lại quá trình này. Nếu khi đọc số byte trong bộ đệm >1 thì như trên tất nhiên nó cũng đọc hết và lại tiếp tục.. Bạn nên biết là tốc độ đọc của bus dữ liệu qua UART là rất lớn so với tốc độ truyền nhận của cáp qua RS232 hay RS485. Do đó chẳng có thiếu sót gì đâu .
                              2-Theo em:MSComm1.SThreshold =1 sẽ gây lãng phí cho thời gian của PC nhất là khi thiết lập ở tốc độ cao. Thông thường thiết bị ngoại vi ta biết trước về số byte tryền liền một lúc và giả sử = N. Nó sẽ truyền theo mô hình:
                              +Truyền hết N byte.
                              +Delay()
                              +Truyền tiếp N byte.
                              ....
                              Giả sử delay=100 ms thì:
                              +Truyền hết N byte.
                              +Trễ 100 ms.
                              +Truyền tiếp N byte.
                              ....
                              Vậy một giải pháp tối ưu là đặt:MSComm1.SThreshold =N. Thời gian delay của bên truyền sẽ khiến cho bên PC kịp thời xử lý. Nhưng nó sẽ có thể gặp phải một trường hợp xấu có thể xảy ra: bên phát truyền liên tục N byte nhưng bên thu chỉ nhận được <N byte(do đứt dây, do nhiễu, do thời điểm kết nối thì đúng lúc bên phát truyền dở...). Thời điểm này sẽ gây lỗi từ thời điểm đó về sau. Vậy một giải phát đưa ra dùng "timerout" giải quyết vấn đề này. Em đề cử một cách bác xem có chấp nhận được ko?
                              Bên PC: tại ngắt(nghĩa là nó nhận được N byte), đọc bộ đệm, khởi tạo một timer=100/2=50ms.
                              Hàm ngắt đọc dữ liệu viết như sau:
                              Private Sub MSComm1_OnComm()
                              On Error Resume Next
                              if(MSComm1.InBufferCount>=N) then
                              data = MSComm1.Input
                              end if
                              tmer1.interval=50
                              timer1.enable=true
                              End Sub

                              Hàm ngắt timer này viết như sau:
                              Private Sub Timer1_Timer()
                              Dim tam as string
                              tam=MSComm1.input 'Lam rong bo dem
                              timer1.enable=False 'Cam timer
                              End Sub
                              Giải pháp này ổn định nhưng ko vạn năng, nó chỉ áp dụng tốt khi thời gian truyền<delay(). Nên áp dụng cho trường hợp thỉnh thoảng truyền.

                              Vậy bác có giải pháp nào dùng ngắt và giải quyết được các nhước điểm trên ko? vì em sợ cái timer của Win lắm.
                              Bạn có lẽ lại đánh nhầm RThreshold thành SThreshold rồi.
                              Nếu thế thì Chi Bang chưa đọc kĩ bầi dùng ngắt ở trên rồi. Bạn đọc lại về ý nghĩa của RThreshold khi thiết lập > 0 và khi nào xảy ra ngắt comEvSend đi và một vấn đề gặp phải khi sử dụng ngắt trong truyền dữ liệu nha. Bạn chẳng chịu đọc gì cả mà đã hỏi. Với lại sao bạn lại nghĩ đặt RThreshold = 1 là lãng phí thời gian cho hệ thống? . Nếu như tốc độ truyền của bus trong PC vẫn lớn hơn truyền qua cáp ( khi không có trục trặc bất thường nào) thì chính dùng ngắt thì mới là cách tiết kiệm thời gian cho PC nhất,tránh bị tràn bộ đệm nhất đấy, còn dùng thăm dò trong trường hợp này lại gây lãng phí lớn. Nhưng đê đề phòng bất trắc thì không nên dùng ngắt mà nên dùng dò khi truyền.
                              Với lại bên nhận dùng ngắt có thể nhận mọi dữ liệu chẳng hề gì đâu bạn ạ. Tốc độ OK đi. Với tần số bus của hệ thống 9600 bit/s thì truyền được 96
                              0 byte/ s với giao thức truyền 8,N,1. Do vậy chẳng cần delay(100) gì cả.
                              Còn về chương trình của bạn. Khi ví dụ thiết lập Rthreshold= N rồi thì khi nào nó nhận được đủ N byte chuyển sang byte thứ N+1 thì mới có ngắt thì dùng if làm gì. Với lại bạn biết OnComm đang phục vụ ngắt nào. Có tới 14 ngắt tất cả cơ mà. Giả sử có lỗi khi truyền có ngắt khác thì sao?
                              Với lại ở đây khi biết thiết bị ngoại vi có N byte truyền trong mỗi lần tức là truyền theo từng block một thì xử lí lại quá là đơn giản rồi. Bạn nên hiểu Timer chỉ dùng để tạo được thời gian sau mỗi đoạn thời gian ngắn thì sẽ thăm dò bộ đệm nhận thôi. Dùng vào tạo delay phí quá!. Bạn đọc lại về cách thiết lập thời gian như thế nào để không bị mất dữ liệu, dựa vào tốc độ bus,.. Còn ưu nhược điểm của ngắt thì tôi phân tích ở trên rồi. Bạn tự đọc đi.
                              Chết thật, bạn chẳng chịu đọc gì cả thế?
                              [quote]
                              4-Liệu MSComm có một tính năng như sau ko?
                              +Có quy định được thời gian giữa 2 byte truyền? ví dụ em muốn truyền chữ chuỗi "sjahs" và mỗi byte cách nhau thời gian là 2 bit chẳng hạn? Ví dụ tốc độ 11500kbps.
                              Ví dụ: "s" --(delay 0.05ms) --"j"-----(delay 0.05ms)----"a"--...
                              [quote]
                              Có thể bạn ạ. Dựa vào tần số bus là có thể quyết định được tốc độ truyền nhưng giới hạn điều này do tốc độ bus còn phụ thuộc vào hệ thống của bạn, vào bắt tay giữa PC và các thiết bị khác.Khi chúng ta đã vào quá trình truyền dữ liệu, xong xuôi bắt tay,.. thì tốc độ này là cố định. Chúng phải có cùng 1 tốc độ(đọc lại về truyền nhận dữ liệu nối tiếp). Ví dụ với tốc độ 9600 bps và kiểu định dạng dữ liệu 8,N,1 thì sẽ truyền được 960byte/s từ đó bạn tỉnh ra truyền 1 bit hết bao nhiêu.9600 bit/s đấy.
                              5-Liệu MSComm có một tính năng như sau ko?
                              +Nếu mà có một sự kiện như sau thì tốt quá: ví dụ vi điều khiển truyền về PC một chuỗi theo quy luật sau:
                              byte1-----byte2....--delay ---byteN--delay(1ms)-- byte1---byte2...--delay ---byteN...
                              Không có điều đó khi mà bạn truyền một lượng dữ liệu lớn, tốc độ truyền mỗi byte phụ thuộc vào hệ thống của bạn( tần số,..). Cái đó chỉ làm được khi bạn viết chương trình điều khiển bằng phần mềm đơn giản thôi là đầu tiên bạn truyền N byte sau đó delay(1ms) thì tất nhiên cái RS-232 của bạn cũng sẽ delay thời gian tương tự. Tương tự như trên sau khi thiết lập mọi thông số tín hiệu bắt tay,.. thì bạn không thể điều chỉnh cái này được.
                              Thế nhé. Không biết bạn hài lòng chưa.
                              Technical sale at WT Microelectronics S'pore
                              Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                              Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                              Comment

                              Về tác giả

                              Collapse

                              ngohaibac Tìm hiểu thêm về ngohaibac

                              Bài viết mới nhất

                              Collapse

                              Đang tải...
                              X