Tóm tắt nội dung
Luận văn trình bày một cách khái quát bài toán cân đóng bao trong công nghiệp cùng cách giải quyết vấn đề, đồng thời, nghiên cứu một số thiết bị phần cứng cũng như các tiêu chuẩn truyền thông được sử dụng trong công nghiệp. Các nghiên cứu này cho phép thiết kế một hệ thống hoàn chỉnh phục vụ cho bài toán cân đóng bao và một số bài toán liên quan. Từ đó luận văn mô tả một cách chi tiết một hệ thống thực đã được tác giả xây dựng và các kết quả triển khai thực tế của nó trong nhà máy công nghiệp. Phần còn lại trình bày các chương trình điều khiển được viết bằng ngôn ngữ lập trình C sử dụng trong bộ điều khiển. Hi vọng, những kiến thức trong luận văn sẽ mang lại cái nhìn rõ ràng nhất cho người đọc về các hệ thống điều khiển tự động nói chung và hệ thống cân đóng bao nói riêng.
Mục lục
Chương 1: Tổng quan 3
Chương 2: *Nghiên cứu cơ sở lý thuyết 5
Chương 3: *Nghiên cứu tính năng phần cứng* 23
Chương 4: *Thiết kế hệ thống 47
Chương 5: *Triển khai phần cứng và các kết quả đạt được 52
Chương 6: *Kết luận 57
Phụ lục 58
Tài liệu tham khảo 93
95 trang |
Chia sẻ: banmai | Lượt xem: 1820 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Thiết kế hệ thống cân tự động sử dụng trong quá trình đóng gói sản phẩm, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
khối DSP.
Chế độ định địa chỉ đảo bit và module.
Bộ nhân bằng phần cứng 17 x 17 bit chỉ trong 1 chu kỳ lệnh đơn.
Tất cả lệnh DSP thực hiện trong một chu kỳ đơn.
Các ngoại vi tích hợp trên chip :
Các chân vào/ra có khả năng chịu dòng cao: 25mA.
5 module định thời (Timer) với tần số xung clock có thể chia được và cấu hình thành 1 cặp Timer 16 bit hoặc 1 Timer 32 bit.
Bộ điều chế độ rộng xung (PWM) với độ phân giải 16 bit.
Module truyền dữ liệu SPI qua 3 dây dẫn (hỗ trợ chế độ 4 khung truyền).
Module truyền dữ liệu I2C hỗ trợ chế độ đa chủ/tớ và các chế độ định địa chỉ 7 bit/ 10 bit.
2 module truyền thông nối tiếp (UART) với bộ đệm FIFO.
Module truyền thông CAN tương thích chuẩn 2.0B.
Module điều khiển PWM:
8 cổng vào/ra PWM với các chế độ bù hoặc đầu ra độc lập và các chế độ sườn xung hoặc trung tâm.
4 khối tạo chu kỳ làm việc khác nhau.
Cơ sở thời gian riêng biệt với toàn chip.
Đầu ra phân cực lập trình được.
Hỗ trợ ngắt cho việc cập nhật không đối xứng trong chế độ trung tâm.
Bộ so sánh sự kiện đặc biệt cho việc lập lịch những sự kiện ngoại vi khác.
Module encoder với góc 90˚(QEI).
3 kênh đầu vào cho hai tín hiệu pha A và B và xung chỉ số.
Bộ đếm tăng/giảm vị trí 16 bit.
Đếm số lần đảo chiều.
Đo vị trí với chế độ x2 và x4.
Bộ lọc nhiễu trên đầu vào có thể lập trình.
Lựa chọn chế độ Timer/Counter 16 bit.
Các ngắt QEI.
Các module tương tự:
4 bộ chuyển đổi tín hiệu tương tự - số (ADC) 10 bit với tốc độ lấy mẫu lên tới 500Ksps, 16 kênh vào và có thể chuyển đổi ngay cả trong chế độ ngủ (sleep).
Có thể lâp trình để bảo vệ hệ thống ở điện thế thấp.
Có thể lập trình ở mức bảo vệ Brown-out và khởi động lại hệ thống.
Các tính năng vi điều khiển đặc biệt:
Bộ nhớ chương trình Flash với chu kỳ ghi/xóa tới 10.000 lần.
Bộ nhớ EEPROM với chu kỳ ghi/xóa 100.000 lần.
Có khả năng tự lập trình lại dưới sự điều khiển của phần mềm.
Bộ định thời Watchdog sử dụng bộ giao động RC riêng trên chip tiêu thụ ít năng lượng với độ tin cậy rất cao.
Chế độ bảo vệ mã lệnh lập trình được.
Có thể lựa chọn các chế độ quản lý năng lượng: Ngủ, chờ và đông hồ luân phiên.
Hỗ trợ khả năng lập trình trên bo mạch (In-circurt Serial Programing).
Chế tạo theo công nghệ CMOS:
Công nghệ Flash với hiệu suất cao.
Dải điện áp nguồn rất rộng 2,5V đến 5,5V.
Dải nhiệt độ công nghiệp và dải nhiệt độ mở rộng.
Tiêu thụ năng lượng rất nhỏ.
Module truyền thông không đồng bộ UART
Module UART (Universal Asynchronous Receiver/Transmitter), thường được tích hợp trên các vi xử lý hoặc máy tính cũng như dsPIC nói riêng, là một khối phần cứng với chức năng chuyển đổi giữa dạng tín hiệu nối tiếp và tín hiệu song song. UART thường được sử dụng với giao thức truyền thông nối tiếp RS-232 và được kết nối với cổng nối tiếp của các thiết bị ngoại vi.
Các đặc điểm chính của module UART :
Truyền dữ liệu 8 hoặc 9 bit.
Các tùy chọn chẵn, lẻ hoặc không bit chẵn lẻ (cho dữ liệu 8 bit).
Một hoặc hai bit Stop.
Tích hợp bộ tạo tốc độ Baud đầy đủ 16 bit.
Dải tốc độ Baud từ 38 bps đến 1,875 Mbps với tốc độ thực hiện lệnh 30 MHz.
Bộ đệm dữ liệu truyền 4 từ đơn.
Bộ đệm dữ liệu nhận 4 từ đơn.
Phát hiện lỗi chẵn lẻ, lỗi khung truyền và lỗi tràn bộ đệm.
Hỗ trợ ngắt cho chế độ dò tìm địa chỉ (bit thứ 9 = 1).
Phân chia riêng biệt ngắt truyền và ngắt nhận.
Sơ đồ khối bộ truyền dữ liệu UART.
Sơ đồ khối bộ nhận dữ liệu UART.
Bộ điều khiển truyền thông CAN của dsPIC 30F6010
Module CAN (Controller Area Network) là một giao diện nối tiếp, phù hợp cho việc truyền thông với những module CAN khác hoặc các thiết bị vi điều khiển. Giao thức này được thiết kế để cho phép truyền thông trong môi trường có nhiễu. DSPIC 30F6010có hai mudule CAN với các đặc điểm như sau:
Thực hiện giao thức CAN 1.2, CAN 2.0A, CAN 2.0B.
Khung dữ liệu chuẩn và mở rộng .
Độ dài dữ liệu 0-8 byte.
Tốc độ bit có thể lập trình lên tới 1Mbit/s.
Hỗ trợ chế độ truyền xa.
2 bộ đệm nhận tín hiệu đầu vào( mỗi bộ lên tới 8 byte dữ liệu).
6 bộ lọc đầy đủ, trong đó 2 bộ lọc liên kết với quyền ưu tiên cao và 4 bộ lọc với quyền ưu tiên thấp.
3 bộ đệm truyền với mức ưu tiên xác định( lên tới 8 byte dữ liệu).
Tính năng Wake-up với bộ lọc thông thấp có thể lập trình.
Chế độ Loopback có thể lập trình hỗ trợ khả năng tự kiểm tra (self-test).
Nguồn khóa có thể lập trình.
Kết nối với module Input Capture(IC2 cho cả CAN1 và CAN2) cho thời gian lấy mẫu và đồng bộ mạng.
Chế độ tiết kiệm năng lượng.
Sơ đồ khối module CAN của dsPIC 30F6010.
Module CAN chứa một lõi giao thức và phần điều khiển/đệm bản tin. Lõi giao thức CAN kiểm soát tất cả các chức năng nhận và truyền bản tin trên bus CAN. Bản tin được truyền bằng việc tải đầu tiên các thanh ghi dữ liệu phù hợp. Trạng thái và lỗi có thể được kiểm tra bằng cách đọc các thanh ghi phù hợp. Bất kỳ bản tin nào được phát hiện trên bus CAN đều được kiểm tra lỗi.
Module CAN truyền các kiểu khung bản tin khác nhau :
Khung dữ liệu chuẩn: Một khung dữ liệu chuẩn được tạo bởi một nút khi nút này muốn truyền dữ liệu. Nó bao gồm một bộ nhận dạng chuẩn 11 bit (Standard Identifier –SID).
Khung dữ liệu mở rộng: Tương tự như khung dữ liệu chuẩn nhưng sử dụng bộ nhận dạng chuẩn 18 bit
Khung dữ liệu xa: Nó có khả năng đối với một nút đích khi yêu cầu dữ liệu từ một nguồn nào đó. Để thực hiện được điều này, nút đích gửi một bản tin xa với một bộ nhận dạng xác định dữ liệu yêu cầu, nút nguồn dữ liệu phù hợp sau đó sẽ gửi một khung dữ liệu đáp ứng với yêu cầu từ xa này.
Khung dữ liệu lỗi: Một khung dữ liệu lỗi được tạo ra bởi bất kỳ nút nào khi phát hiện ra có lỗi trên bus. Một khung lỗi bao gồm 2 trường: một trường cờ lỗi và một trường xác định ranh giới lỗi.
Khung dữ liệu quá tải: Một khung dữ liệu quá tải có thể được tạo ra bởi một nút như kết quả của hai điều kiện. Thứ nhất là: Nút này phát hiện ra một bit trội trong nội bộ khung - điều này là bất hợp lệ. Thứ hai là: vì điều kiện nội tại nên nút không có khả năng nhận bản tin tiếp theo. Một nút có thể tạo ra nhiều nhất 2 khung qua tải liên tiếp để trì hoãn việc bắt đầu của bản tin tiếp theo.
Không gian nội bộ bản tin: Không gian nội bộ bản tin phân biệt một khung dữ liệu đi đến là từ bản tin tiếp theo hay từ bản tin từ xa.
Bộ định thời TIMER
DSPIC 30F6010 cung cấp cho người dùng 5 bộ định thời với các chế độ làm việc riêng lẻ 16 bit (Timer1) hay kết hợp thanh cặp trong chế độ 32 bit(Timer2/3 và Timer4/5).
Module Timer1 là một bộ định thời 16-bit có thể được sử dụng như bộ đếm (counter) thời gian cho đồng hồ thời gian thực hoặc như một bộ định thời/bộ đếm hoạt động tự do. Timer 16 bit có các chế độ sau :
Bộ định thời 16-bit.
Bộ đếm đồng bộ 16-bit.
Bộ đếm không đồng bộ 16-bit.
Ngoài ra, các đặc trưng hoạt động sau cũng được cung cấp:
Quản lý cổng thời gian khi đặt trong chế độ tích lũy thời gian đóng kín (Gated Time Accumulation mode).
Cài đặt được tỷ lệ chia tần số xung đồng hồ.
Hoạt động trong các chế độ Chờ (Idle) và Ngủ (Sleep) của CPU.
Ngắt phù hợp với thanh ghi chu kỳ 16-bit và sườn xuống của tín hiệu gate bên ngoài.
Các chế độ hoạt động này được lựa chọn bằng cách đặt các bit tương ứng trên thanh ghi SFR 16-bit T1CON.
Bộ định thời của dsPIC 30F6010
Module Timer2/3 là một timer 32 bit, được cấu hình bởi 2 timer 16-bit với các chế độ hoạt động có thể lựa chọn được. Các timer này được sử dụng bởi các module ngoại vi như chụp tín hiệu đầu vào (input capture) hay so sánh đầu ra/bộ điều chế độ rộng xung đơn giản(output compare/simple PWM).
Timer 32-bit có các chế độ hoạt động như sau:
2 timer 16-bit độc lâp với toàn bộ các chế độ hoạt động của timer 16-bit (trừ bộ đếm không đồng bộ).
Bộ định thời 32-bit.
Bộ đếm đồng bộ 32-bit.
Ngoài ra, các đặc trưng hoạt động sau cũng được cung cấp:
Tri-gơ sự kiện ADC (ADC Event Trigger).
Quản lý cổng thời gian khi đặt trong chế độ tích lũy thời gian đóng kín (Gated Time Accumulation mode).
Cài đặt được tỷ lệ chia tần số xung đồng hồ.
Hoạt động trong các chế độ Chờ (Idle) và Ngủ (Sleep) của CPU.
Ngắt phù hợp với thanh ghi chu kỳ 32-bit.
Các chế độ hoạt động này được lựa chọn bằng cách đặt các bit tương ứng trên thanh ghi SFR 16-bit T2CON và T3CON.
Module Timer4/5 cũng tương tự như module Timer2/3 nhưng có những điểm khác biệt như sau:
Không hỗ trợ đặc tính ADC Event Trigger.
Không được sử dụng bởi các module ngoại vi khác.
Các chế độ hoạt động này được lựa chọn bằng cách đặt các bit tương ứng trên thanh ghi SFR 16-bit T2CON và T3CON.
Bộ chuyển đổi tương tự - số ADC
DSPIC 30F6010 cung cấp một module ADC tốc độ cao cho phép chuyển đổi tín hiệu đầu vào tương tự sang tín hiệu số 10-bit. Module này dựa trên kiến trúc của thanh ghi xấp xỉ kế tiếp (Successive Approximate Register) với tốc độ lấy mẫu tối đa là 500kbps. Module ADC có 16 lối vào tương tự được hợp kênh bởi 4 bộ khuếch đại lấy và giữ mẫu. Đầu ra của bộ lấy và giữ mẫu là đầu vào của bộ chuyển đổi, nơi tạo ra kết quả. Bộ chuyển đổi A/D là bộ phận duy nhất được phép làm việc khi thiết bị ở chế độ ngủ.
Module A/D có các thanh ghi 16-bit :
Thanh ghi điều khiển A/D 1 (ADCON1).
Thanh ghi điều khiển A/D 2 (ADCON2).
Thanh ghi điều khiển A/D 3 (ADCON3).
Thanh ghi lựa chọn đầu vào A/D (ADCHS).
Thanh ghi cấu hình cổng A/D (ADPCFG).
Thanh ghi lựa chon quét đầu vào (ADCSSL).
Các thanh ghi ADCON1, ADCON2, ADCON3 điều khiển hoạt động của module A/D. Thanh ghi ADCHS lựa chọn kênh vào để chuyển đổi. Thanh ghi ADPCFG cấu hình cho cổng là đầu vào tương tự hay vào ra số. Thanh ghi ADCSSL chọn đầu vào để quét.
Vi điều khiển PSOC
Các dòng vi điều khiển PSOC
PSoC là một từ viết tắt của cụm từ tiếng Anh Programmable System on Chip, nghĩa là hệ thống khả trình trên một chip. Các chip chế tạo theo công nghệ PSoC cho phép thay đổi được cấu hình đơn giản bằng cách gán chức năng cho các khối tài nguyên có sẵn trên chip. Hơn nữa, nó có thể kết nối tương đối mềm dẻo các khối chức năng với nhau hoặc giữa các khối chức năng với các cổng vào ra. Chính vì vậy mà PSoC có thể thay thế cho rất nhiều chức năng nền của một số hệ thống cơ bản chỉ bằng một đơn chip. Thành phần của chip PSoC bao gồm các khối ngoại vi số và tương tự có thể cấu hình được, một bộ vi xử lý 8 bit, bộ nhớ chương trình (EEROM) có thể lập trình được và bộ nhớ RAM khá lớn. Để lập trình hệ thống, người sử dụng được cung cấp một phần mềm lập trình được xây dựng trên cơ sở hướng đối tượng với cấu trúc module hóa. Mỗi khối chức năng là một module mềm. Việc cấu hình chip như thế nào tùy thuộc vào người lập trình thông qua một số thư viện chuẩn. Người lập trình thiết lập cấu hình trên chíp chỉ đơn giản bằng cách muốn chip có chức năng gì thì kéo chức năng đó và thả vào khối tài nguyên số hoặc tương tự, hoặc cả hai tùy theo từng chức năng (phương pháp lập trình kéo thả). Việc thiết lập ngắt trên chân nào, loại ngắt gì, các chân vào ra được hoạt động ở chế độ như thế nào đều tùy thuộc vào việc thiết lập của người lập trình khi thiết kế và lập trình cho PSoC. Với khả năng cấu hình mạnh mẽ như vậy, một thiết bị điều khiển, đo lường có thể được gói gọn trong một chip duy nhất. Chính vì lý do đó, hãng Cypress Micro Systems đã không gọi sản phẩm của mình là vi điều khiển như truyền thống, mà goị là “thiết bị PsoC”, và họ hy vọng rằng, với khả năng đặt cấu hình mạnh mẽ, người sử dụng sẽ có những thiết bị điều khiển, những thiết bị đo có giá thành rẻ, kích thước nhỏ gọn, và sản phẩm PsoC của họ sẽ thay thế được những thiết bị dựa trên vi xử lý hoặc vi điều khiển đã có từ trước đến nay.
Vi điều khiển CY8C27443
Đặc điểm chính của PSoC CY8C27443:
Bộ xử lý với kiến trúc Harvard mạnh mẽ.
Tốc độ của bộ xử lý lên đến 24MHz.
Lệnh nhân 8 bit x 8 bit, thanh ghi tích lũy là 32 bit.
Hoạt động ở tốc độ cao mà tiêu hao ít năng lượng.
Dải hoạt động từ 3.0 tới 5.25V.
Điện áp hoạt động có thể giảm xuống 1.0V sử dụng chế độ kích điện áp.
Hoạt động trong dải nhiệt độ từ -40 đến 85°C
Các khối ngoại vi có thể được sử dụng độc lập hoặc kết hợp.
12 khối ngoại vi tương tự có thể được thiết lập để làm các nhiệm vụ:
Các bộ ADC 14 bit.
Các bộ DAC 9 bit.
Các bộ khuếch đại có thể lập trình hệ số khuếch đại.
Các bộ lọc và các bộ so sánh có thể lập trình được.
8 khối ngoại vi số có thể được thiết lập để làm các nhiệm vụ:
Các bộ định thời đa chức năng, đếm sự kiện, động hồ thời gian thực, bộ điều chế độ rộng xung có và không có dải an toàn (deadband).
Các module kiểm tra lỗi (CRC modules).
2 bộ truyền thông nối tiếp không đồng bộ 2 chiều.
Các bộ truyền thông SPI Master và Slave có thể cấu hình được.
Có thể kết nối với tất cả các chân vào ra.
Bộ nhớ linh hoạt trên chip.
Không gian bộ nhớ chương trình Flash 16 Kbyte với chu kỳ ghi xóa la 50.000 lần.
Không gian bộ nhớ RAM là 256 byte.
Chip có thể lập trình thông qua chuẩn nối tiếp (ISSP).
Bộ nhớ Flash có thể được nâng cấp từng phần.
Một phần bộ nhớ Flash có thể được giả lập như một bộ nhớ EEPROM, cho phép lưu các thông số trong lúc chạy chương trình.
Chế độ bảo mật đa năng, tin cậy.
Có thể tạo được không gian bộ nhớ Flash trên chip lên tới 2.304 byte.
Có thể cấu hình cho các chân khả trình.
Các chân vào ra ba trang thái sử dụng Trigger Schmitt.
Đầu ra logic có thể cung cấp dòng 25 mA với điện trở treo cao hoặc thấp bên trong.
Thay đổi được ngắt trên từng chân.
Đường ra tương tự có thể cung cấp dòng tới 40mA.
Đường ra đa chức năng có từ 6 đến 44
Xung nhịp của chip có thể lập trình được.
Bộ tạo dao động trong 24/48 MHz chính xác 2.5%.
Có thể lựa chọn bộ dao động ngoại 24 MHz.
Bộ dao động thạch anh nội 32,768 kHz.
Bộ tạo dao động tốc độ thấp bên trong sử dụng cho Watchdog và Sleep.
Ngoại vi được thiết lập sẵn.
Bộ định thời Watchdof và Sleep phục vụ chế độ an toàn và chế độ nghỉ.
Module truyền thống I2C™ Slave, Master tốc độ lên tới 400kHz.
Module phát hiện điện áp thấp được cấu hình bởi người sử dụng.
Công cụ phát triển.
Phần mềm phát triển miễn phí (PSoC™ Designer).
Bộ lập trình và bộ mô phỏng với đầy đủ tính năng.
Kiến trúc của PsoC được chỉ ra trong hình 12, bao gồm 4 thành phần chính: nhân PsoC (PSoC core), hệ thống số, hệ thống tương tự, và các tài nguyên hệ thống. Bus toàn cục có thể cấu hình được cho phép tất cả tài nguyên của thiết bị kết hợp thành một hệ thống hoàn chỉnh cho người sử dụng. Họ PsoC CY8C27x43 có thể có tới 5 cổng vào ra được kết nối với các liên kết số và tương tự toàn cục, cung cấp truy cập tới 8 khối số và 12 khối tương tự.
Sơ đồ khối cấu trúc của PSoC CY8C27433
Các khối số
Hệ thống số là tập hợp của 8 khối số 8 bit có thể được sử dụng độc lập hoặc kết hợp với các khối khác thành các ngoại vi 8, 16, 24 hay 32bit.
Các khối số của PSOC
Các khối số được tổ chức dưới dạng các hàng bốn khối với số khối biến đổi theo từng họ thiết bị PSoC. Điều này cho phép bạn lựa chọn các tài nguyên hệ thống cho ứng dụng của mình.
Những ngoại vi được tạo bởi khối PSoC số :
Bộ điều chế độ rộng xung (8 đến 32 bit).
Bộ điều chế độ rộng xung với dải an toàn (8 đến 32 bit).
Bộ đếm (8 đến 32 bit).
Bộ định thời (8 đến 32 bit).
Bộ truyền thông không đồng bộ UART 8 bit với bit chẵn lẻ lựa chọn được.
Bộ truyền thông nối tiếp SPI master và slave.
Bộ truyền thông I2C slave và master (đã có sẵn như tài nguyên hệ thống).
Bộ tạo dãy CRC phục vụ việc kiểm tra lỗi.
Bộ truyền và nhận giao tiếp quang học.
Các khối PSoC số có thể được kết nối với mọi GPIO thông qua một loạt bus toàn cục đảm bảo cho mọi tín hiệu đến được với tất cả các chân. Những bus này cũng cho phép dồn kênh tín hiệu và điều hành việc thực hiện các phép toán logic.
Bộ đếm COUNTER
Loại
Số khối PSoC
Bộ nhớ(Byte)
Số chân
Số
Tương tự CT
Tương tự SC
Flash
RAM
8-bit
1
0
0
71
0
1
16-bit
2
0
0
93
0
1
24-bit
3
0
0
128
0
1
32-bit
4
0
0
146
0
1
Các bộ đếm 8, 16, 24, 32-bit với các đặc điểm sau:
Độ rộng thanh ghi 8, 16, 24, 32 bit, sử dụng 1, 2, 3, 4 khối PSoC theo thứ tự.
Xung nhịp nguồn lên tới 48 MHz.
Tự động nạp lại chu ký khi đếm xong.
Khả năng chụp (capture) tới 24 MHz.
Đầu ra đếm kết thúc có thể được sử dụng như là đầu vào xung nhịp cho các khối chức năng số và tương tự khác.
Lựa chọn chế độ ngắt khi đếm kết thúc, chụp, hoặc là khi bộ đếm đạt một giá trị đặt trước.
Sơ đồ khối bộ đếm của PSoC CY8C27433
Các module Counter là những bộ đếm lùi với chu kỳ có thể lập trình được, có khả năng chụp giữ. Xung nhịp và các tín hiệu cho phép có thể được lựa chọn từ nguồn ngoài hoặc từ xung nhịp hệ thống. Sau khi được khởi động, bộ đếm hoạt động liên tục và sẽ tải giá trị bên trong của nó từ thanh ghi chu kỳ sau khi đạt đến giá trị đếm kết thúc. Trong mỗi chu kỳ xung nhịp, bộ đếm sẽ so sánh giá trị đếm hiện thời với giá trị được lưu trữ trong thanh ghi so sánh. Điều kiện so sánh là “nhỏ hơn” hay “nhỏ hơn hoặc bằng” liên tục được kiểm tra trong mỗi chu kỳ xung nhịp. Các ngắt có thể được sinh ra dựa trên tín hiệu đếm kết thúc hoặc điều kiện so sánh.
Config các khối UART
Loại
Số khối PSoC
Bộ nhớ(Byte)
Số chân
Số
Tương tự CT
Tương tự SC
Flash
RAM
API mức thấp
2
0
0
310
0
2
API mức cao
2
0
0
506
3+Buffer
2
Bộ truyền thông không đồng bộ UART có các đặc điểm sau:
Bộ nhận và truyền tín hiệu không đồng bộ.
Định dạng dữ liệu tương thích với định dạng dữ liệu RS-232.
Tốc độ xung đồng bộ lên tới 6Mbit/s.
Khung dữ liệu bao gồm bit Start, bit chẵn lẻ (lựa chọn) và các bit Stop.
Ngắt khi thanh ghi nhận đầy (lựa chọn) hoặc khi bộ đệm truyền rỗng.
Phát hiện chẵn lẻ, khung quá tải, khung báo lỗi.
Các chức năng phát và thu ở mức cao.
Module người sử dụng UART là một bộ truyền nhận nối tiếp không đồng bộ hỗ trợ chuẩn kép RS-232, định dạng truyền thông nối tiếp qua hai dây. Người sử dụng có thể lập trình xung nhịp đồng hồ và lựa chọn ngắt phù hợp. Phần mềm nhúng với giao diện chương trình ứng dụng (API) thông thường được cung cấp để khởi tạo, cấu hình và điều khiển UART. Thêm vào đó, một API mức cao cũng được cung cấp để hỗ trợ việc nhận các lệnh cơ sở và in các chuỗi ký tự.
Module UART được xây dựng bởi hai module TX và RX cùng với một số thư viện hỗ trợ cho việc truyền thông. Hai module TX va RX có thể được sử dụng riêng.
Sơ đồ nguyên lý module UART của PSOC
Thiết bị cân
Thiết bị cân Mettler Toledo IND130
Mettler Toledo IND130 là một thiết bị cân điện tử thông minh được cung cấp bởi Metter Toledo, một công ty lớn với nhiều năm kinh nghiệm với các sản phẩm trong lĩnh vực đo lường, khá quen thuộc với thị trường Việt Nam. Lắp đặt nhanh chóng và vận hành đơn giản, khả năng kết nối trực tiếp với PLC cũng như PC, cung cấp tín hiệu ổn định, Mettler Toledo IND130 được lựa chọn sử dụng rất rộng rãi trong các dây chuyền công nghiệp cũng như những ứng dụng đòi hỏi sự chính xác, tin cậy cao và khả năng hoạt động liên tục.
Các thông số và đặc tính :
Kích thước: 102 x 50 x 125 mm.
Trọng lượng: 0,34kg.
Nguồn nuôi: 24 VDC.
Nhiệt độ làm việc: -10˚C đến 45˚C.
Độ phân giải tối đa: 10.000 mức.
Bộ lọc số: TraxDSP.
Giao diện PC/PLC: tuỳ chọn RS-232, PROFIBUS, Allen-Bradley RIO, DeviceNet**.
Các cổng vào ra trên Mettler Toledo IND130
Chức năng
Không chỉ là một chiếc cân điện tử với độ chính xác cao, Mettler Toledo IND130 được sản xuất với mục đích điều khiển một hệ thống cân đóng bao trong công nghiệp. Nó có các cổng giao tiếp với PC/PLC cùng với một số đường vào ra để điều khiển các quá trình hệ thống. Các cổng này được nối với các van khí nén trong hệ thống, cung cấp tín hiệu điều khiển đóng mở van.
Cổng nối tiếp
Mettler Toledo IND130 có một cổng nối tiếp 2 chiều RS-232/485 có thể được lập trình cho nhiều chức năng. Việc lựa chọn giữa hai chuẩn này được thực hiện bằng cách thay đổi vị trí chốt (jumper) trên thiết bị.
Vị trí chốt của RS-232 và RS-485
Độ dài tối đa của cáp nối là 15m cho RS-232 và 330m cho RS-485.
Đầu vào này có thể được sử dụng để cung cấp các lệnh đơn giản từ thiết bị khác hoặc nếu được lập trình trong chế độ MODBUS RTU, có thể nhận dữ liệu từ bên ngoài. Đầu ra có thể được cấu hình để trao đổi thông tin với máy in hoặc máy tính, hoặc cấu hình thành đầu ra liên tục đến màn hình điều khiển hoặc như một giao diện MODBUS RTU cao cấp hơn.
Truyền thông Modbus RTU
Địa chỉ
Bit
Dữ liệu chỉ ghi
40101
.0
.1
.2
.3
0001~0100:
Nguyên liệu được dùng
.4
.5
.6
.7
0001:
Bắt đầu đổ nguyên liệu được xác định bởi bit 0~3
.8
Bắt đầu quá trình cân
.9
Giữ quá trình cân
.10
Kết thúc quá trình cân
.11
Xả
.12
Đóng bao
.13
Đẩy bao ra
.14
Trở về mức 0
40102
.0
.1
.2
.3
0001~0011:
Chọn chế độ làm việc (1~3)
.4
10: chế độ tự động đổ từng nguyên liệu
11: tiếp tục chế độ đổ tự động
.5
.6
10: chế độ xả thủ công
11: chế độ xả tự động
.7
40103
Kiểm tra đĩa cân:
0:lưu trọng lượng điểm 0
xxxx: lưu trọng lượng tải (xxxx là trọng lượng kiểm tra)
Địa chỉ
Bit
Dữ liệu chỉ đọc
40001
Tổng trọng lượng
40002
Trọng lượng thực
40003
.0
Nguyên liệu 1 đang trong quá trình tinh
.1
Nguyên liệu 1 đang trong quá trình thô
.4
Nguyên liệu 2 đang trong quá trình tinh
.5
Nguyên liệu 2 đang trong quá trình thô
.8
Nguyên liệu 3 đang trong quá trình tinh
.9
Nguyên liệu 3 đang trong quá trình thô
.12
Nguyên liệu 4 đang trong quá trình tinh
.13
Nguyên liệu 4 đang trong quá trình thô
40004
.0
0001~0011:
Chế độ hiện tại (1~3)
.1
.2
.3
.4
Cân đang hoạt động
.5
Cân đang giữ
.6
Đang xả
.7
Tất cả nguyên liệu đã đổ, đang chờ xả
.8
Kích thước tải trọng:
0000=0.001 0001=0.002 0010=0.005 0011=0.01
0100=0.02 0101=0.05 0110=0.1 0111=0.2
1000=0.5 1001=1 1010=2 1011=5 1100=10
.9
.10
.11
.12
Nguyên liệu được đổ đã quá dung sai cho phép
.13
Bàn cân đang hoạt động
.14
Chế độ đổ nguyên liệu
.15
Chế độ xả
40005
Kết quả đổ nguyên liệu 1
40006
Kết quả đổ nguyên liệu 2
40007
Kết quả đổ nguyên liệu 3
40008
Kết quả đổ nguyên liệu 4
Địa chỉ
Dữ liệu có thể đọc và ghi
40009
Bao bì
40010
Lượng đặt cho nguyên liệu 1
40011
Lượng đặt cho nguyên liệu 2
40012
Lượng đặt cho nguyên liệu 3
40013
Lượng đặt cho nguyên liệu 4
40014
Lượng thô của nguyên liệu 1
40015
Lượng thô của nguyên liệu 2
40016
Lượng thô của nguyên liệu 3
40017
Lượng thô của nguyên liệu 4
40018
Lượng dư của nguyên liệu 1
40019
Lượng dư của nguyên liệu 2
40020
Lượng dư của nguyên liệu 3
40021
Lượng dư của nguyên liệu 4
40022
Khoảng trọng lượng 0 (zero range)
40023
Chu kỳ tự động sửa lượng dư
40024
Bắt đầu thời gian trễ
40025
Thời gian cấm
40026
Thời gian trễ đóng van xả
40027
Thời gian trễ để giải quyết sai số cho vật liệu 1
40028
Thời gian trễ để giải quyết sai số cho vật liệu 2
40029
Thời gian trễ để giải quyết sai số cho vật liệu 3
40030
Thời gian trễ để giải quyết sai số cho vật liệu 4
Thiết kế hệ thống
Cấu trúc hệ thống
Sơ đồ khối hệ thống
Hệ thống cân đóng bao được thiết kế với 3 thành phần chính: khối giao diện người – máy, khối điều khiển và bộ cân. Ngoài ra, hệ thống còn có khả năng kết nối với máy tính.
LCD
Keyboard
Modbus
Modbus
CAN/RS232-485
Sơ đồ khối hệ thống cân đóng bao
Khối giao tiếp người – máy
Khối giao tiếp người máy (HMI) là một phần không thể thiếu trong các hệ thống tự động hóa với chức năng chính là cầu nối giữa hệ thống và người điều khiển. Thực chất, HMI là một bản mạch với thành phần chính là một màn hình LCD với nhiệm vụ hiển thị thông tin về hệ thống, và một bàn phím để người sử dụng bật/tắt hệ thống, nhập dữ liệu, cũng như lựa chọn các chế độ hoạt động cho hệ thống.
HMI được thiết kế với một thiết bị PSoC riêng với mục đích điều khiển màn hình, bàn phím và giao tiếp với các khối khác qua module UART của mình.
Khối giao tiếp người-máy
Khối điều khiển
Nếu như khối giao diện người – máy được coi như bộ mặt của hệ thống, nơi có các ‘giác quan’ để giao tiếp với con người thì khối điều khiển có thể được xem là bộ não, nơi điều khiển toàn bộ hành vi của hệ thống. ‘Linh hồn’ của khối điều khiển chính là vi điều khiển dsPIC 30F6010. Tại đây, tín hiệu từ HMI cũng như khối cân gửi về qua module UART được xử lý, đồng thời các tín hiệu điều khiển cũng được phát đi theo đúng lưu đồ thuật toán đã phân tích ở trên.
Khối điều khiển cũng được thiết kế với một chip điều khiển truyền thông CAN MCP2515. Đây là một thiết bị được cung cấp bởi MicroChip với đầy đủ thanh ghi, bộ đệm, đồng hồ xung nhịp, khối điều khiển logic... như một chip điều khiển chuyên dụng có khả năng hoạt động độc lập để phục vụ truyền thông CAN. Việc tích hợp thiết bị này nhằm hướng đến việc trao đổi dữ liệu với máy tính trong cấu hình chung gồm nhiều hệ thống tự động được quản lý bởi một máy chủ của nhà máy. Trong khuôn khổ luận văn này, MCP2515 tạm thời chưa được sử dụng đến.
Khối điều khiển
Khối cân
Như đã trình bày ở chương 3, hệ thống cân đóng bao sử dụng thiết bị cân Mettler Toledo IND130. Đây là thiết bị cân có sẵn trên thị trường, được chế tạo nhằm phục vụ cho các bài toán cân mẻ nói chung và cân đóng bao nói riêng. Thiết bị này có một cổng nối tiếp theo chuẩn RS-232/RS485 được sử dụng để truyền dữ liệu cân về khối điều khiển.
Truyền thông trong hệ thống
Hệ thống sử dụng hai giao thức truyền dữ liệu là Modbus và CAN. Với ưu điểm là tính đơn giản, Modbus được lựa chọn để thực hiện việc truyền dữ liệu giữa khối điều khiển với khối HMI và khối cân. Hơn nữa, Modbus được hỗ trợ bởi đường truyền nối tiếp RS-232 hoặc RS-485 được tích hợp trong cả vi điều khiển dsPIC, PSoC, cũng như trong khối cân Mettler Toledo IND130. Modbus được sử dụng trong việc truyền thông giữa HMI và khối điều khiển. Giao thức CAN tỏ ra vượt trội trong việc kết nối hệ thống cân đóng bao với các hệ thống khác cũng như với máy chủ điều khiển toàn bộ các quá trình trong cả nhà máy. Với cơ chế giao tiếp theo phương pháp định địa chỉ và giao tiếp hướng đối tượng của mình, CAN mang lại hiệu quả cao khi đặt trong truyền thông với phạm vi toàn cục.
Phần mềm giám sát hệ thống
Phần mềm giám sát hệ thống là phần mềm chạy trên máy tính, hệ điều hành WinXP. Thông qua bộ chuyển đổi USB-RS485, với trình điều khiển thiết bị cho phép người lập trình giao tiếp với mạng RS485 thông qua cổng USB của máy tính bằng một cổng COM ảo. Phầm mềm giao tiếp với hệ thống theo chuẩn truyền thông Modbus, hỗ trợ các hàm 03, 06, 16.
Các tính năng chính của phần mềm giám sát :
Hiển thị và cho phép người sử dụng thay đổi các thông số của hệ điều khiển như lượng đặt, lượng cắt thô, tinh…
Giám sát quá trình cân đóng bao theo thời gian thực
Đếm số bao đã được đóng gói, số bao bị lỗi (thừa/thiếu cân), in và lưu vào cơ sở dữ liệu.
Triển khai phần cứng và các kết quả đạt được
Giao diện người – máy
Sơ đồ nguyên lý
Sơ đồ nguyên lý khối giao tiếp người-máy
Phương thức hoạt động
Khối giao tiếp người – máy cho phép người sử dụng cài đặt cấu hình cho hệ thống điều khiển, chỉnh sửa các giá trị đặt trước, kiểm tra trạng thái các đầu vào, ra. Giao tiếp giữa khối HMI và khối điều khiển là Modbus.
Bộ điều khiển
Sơ đồ
Sơ đồ nguyên lý khối điều khiển
Phương thức hoạt động
Trong quá trình triển khai thực tế, hệ thống cơ khí đang có là hệ thống đóng bao bằng tay, với một người công nhân sẽ nhìn số cân để đóng van. Việc nâng cấp hệ thống này bằng việc đưa vào hệ thống điều khiển tự động yêu cầu phải thực hiện trong thời gian rất ngắn. Việc nâng cấp hệ thống cơ khí cho 2 van xả với tốc độ dòng liệu lớn và nhỏ đòi hỏi chi phí lớn, thời gian dài. Do đó, giải pháp cho vấn đề là sử dụng cửa xả liệu hiện tại, đóng mở cửa xả này bằng xilanh khí nén với van 2 ngả. Cùng với một sensor báo hành trình pittong khí nén, bộ điều khiển có thể dừng xilanh khí nén tại điểm có sensor, tương đương với mở van một góc nhỏ, dòng liệu chảy qua van nhỏ.
Bộ điều khiển liên tục nhận dữ liệu cân từ thiết bị đọc đầu cân IND130 gửi về. Thuật toán điều khiển chỉ phải chỉnh sửa khi hệ thống chuyển trạng thái từ xả thô sang xả tinh. Khi đó, bộ điều khiển ra lệnh đóng van cho đến khi gặp tín hiệu báo pittong đã chạy đến điểm đặt thì ngắt tín hiệu đóng van. Xilanh sẽ dừng tại điểm đặt, tương đương với van xả mở nhỏ. Khi bao đầy, bộ điều khiển ra lệnh đóng van bình thường.
Triển khai ứng dụng hệ thống tại nhà máy Phân lân Ninh Bình
Một số hình ảnh của các thiết bị đã chế tạo được trong hệ thống
Ảnh tủ điều khiển
Ảnh mạch nguồn
Ảnh khối giao tiếp người máy
Ảnh tủ van khí nén
Ảnh khối cân Mettler Toledo IND130
Kết luận
Tóm lại, luận văn đã xây dựng thành công một hệ thống cân đóng bao hoàn chỉnh, có khả năng vận hành trong thực tế. Hệ thống có giao diện thân thiện, khả năng xử lý thông minh, làm cho giai đoạn đóng gói sản phẩm trở nên nhanh chóng, chính xác, đồng thời có khả năng kết nối, đồng bộ cao trong cấu hình chung của cả một nhà máy. Một hệ thống hoàn toàn tự động như vậy không chỉ mang lại hiệu quả cao về thời gian và tiền bạc, mà còn giúp giảm bớt nhân công, đóng góp vào việc nâng cao hiệu suất lao động.
Trong tương lai, hệ thống có thể được phát triển thêm bằng cách tập trung nâng cấp bộ truyền thông CAN để ghép nối được với máy chủ cũng như các hệ thống tự động khác. Khi đó chỉ cần ngồi ở một máy chủ để điều khiển toàn bộ các quá trình đang vận hành trong nhà máy. Cùng với việc xây dựng các hệ thống tương tự, tin rằng trong tương lai không xa, các dây chuyền sản xuất công nghiệp ở nước ta sẽ hoàn toàn được tự động hóa, đưa Việt Nam trở thành một nước công nghiệp hiện đại, sánh vai với các nước trong khu vực cũng như trên toàn thế giới.
Phụ lục
Mã nguồn các loại
Chương trình chính, đọc dữ liệu, xử lý thuật toán
#include // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include "const.h" // PSoC API definitions for all User Modules
#include "modbusmachine.h"
//khai bao cac gia tri
#define THIS_DEVICE_ADDRESS 181
#define ACK 0x06
#define STATE_IDLE 0x00
#define STATE_VAOBAO 0x01
#define STATE_COARSE_FEED 0x02
#define STATE_FINE_FEED 0x03
#define STATE_MOVE_FINE_PITT 0x04
#define STATE_RABAO 0x05
#define MODE_MAN 0x00
#define MODE_AUTO 0x01
#define OUT_CLOSE_VAL 0b10000000
#define OUT_OPEN_VAL 0b01000000
#define OUT_KEP_BAO 0b00100000
#define OUT_DAY_BAO 0b00010000
#define OUT_TOL 0b00001000
#define OUT_ERR 0b00000001
#define OUT_TO_IN0 0b00000010
#define IN_COARSE in0 & 0b10000000
#define IN_FINE in0 & 0b01000000
#define IN_DISCH in0 & 0b00100000
#define IN_TOL in0 & 0b00010000
#define IN_VAOBAO in1 & 0b00100000
#define IN_HT_PITT in1 & 0b00010000
#define IN_MODE in0 & 0b00001000
#define IN_M_CLOSE in0 & 0b00000010
#define IN_M_OPEN in0 & 0b00000100
#define IN_M_OUT in0 & 0b00000001
#define OUT_CLOSE_VAL 0b10000000
#define OUT_OPEN_VAL 0b01000000
#define OUT_KEP_BAO 0b00100000
#define OUT_DAY_BAO 0b00010000
#define OUT_TOL 0b00001000
#define OUT_ERR 0b00000001
#define OUT_TO_IN0 0b00000010
char heartbeat = 0;
char x = 0;
char timeout = 0;
char j = 0;
char i = 0;
char in0 = 0;
char in1 = 0;
char out0 = 0;
unsigned int iTime = 0;
unsigned int iDelay = 0;
char nState = STATE_IDLE;
char nMode = MODE_MAN;
char CheckTimeOut()
{
if(!iTime)
{
return 1; }
else
{
iTime--;
return 0; }
}
void delayms(int ndelay)
{
heartbeat = 0;
while(ndelay)
{
while(!heartbeat);
heartbeat = 0;
while(!heartbeat);
heartbeat = 0;
ndelay--;
}
}
void main()
{
int k;
M8C_EnableGInt ; // Turn on interrupts
SerMB_1_TxIntMode(SerMB_1_INT_MODE_TX_COMPLETE);
SerMB_1_EnableInt();
SerMB_1_Start(UART_PARITY_NONE); // Enable UART
TimeMB_1_EnableInt();
TimeMB_1_WritePeriod(250);
Counter8_1_Start();
Counter8_2_EnableInt();
// Counter8_2_WritePeriod(40);
PRT0DR = 0b00000000;
PRT1DR = 0b00000000;
PRT2DR = 0b00000000; //out
out0 = 0b00;
nState = STATE_IDLE;
Counter8_2_Start();
TESTLOOP:
if(!heartbeat)
goto TESTLOOP;
heartbeat = 0;
in1 = PRT1DR & 0b11110000;
in0 = PRT0DR & 0b11111111;
PRT2DR = out0;
// if(in0 & 0b00000001) //ct hanh trinh pittong
if(nState == STATE_IDLE)
{
PRT1DR &= 0b11110011;
if(in1 & IN_VAOBAO)
{
out0 = OUT_KEP_BAO | OUT_TO_IN0;
iDelay = 1000;
iTime = 20000; //dat 10s cho vao bao
nState = STATE_VAOBAO;
goto TESTLOOP;
}
out0 = 0x00;
}
if(nState == STATE_MOVE_FINE_PITT)
{
// PRT1DR &= 0b11110011;
// PRT1DR |= 0b00001100;
if(IN_FINE) //co fine
{
out0 = OUT_CLOSE_VAL|OUT_KEP_BAO;
if(IN_HT_PITT) //pit den ct hanh trinh
{
nState = STATE_FINE_FEED;
iTime = 30000; //dat 15s cho fine feed
// out0 = OUT_CLOSE_VAL|OUT_OPEN_VAL|OUT_KEP_BAO;
out0 = OUT_KEP_BAO;
goto TESTLOOP;
}
}
else //chay 1 toc do
{
out0 = OUT_CLOSE_VAL|OUT_KEP_BAO;
iTime = 3000; //dat 2.5s cho ra bao
iDelay = 2000; //doi mo kep bao
nState = STATE_RABAO;
goto TESTLOOP;
}
if(CheckTimeOut())
{
nState = STATE_IDLE;
out0 = 0x00;
}
}
if(nState == STATE_VAOBAO)
{
if(iDelay)
{
out0 = OUT_KEP_BAO | OUT_TO_IN0;
if(IN_COARSE) //coarse tat
{
out0 |= OUT_OPEN_VAL;
}
iDelay--;
goto TESTLOOP;
}
out0 = OUT_KEP_BAO ;
if(IN_COARSE)
{
nState = STATE_COARSE_FEED;
iTime = 60000; //dat 30s cho coarse feed
goto TESTLOOP;
}
if(CheckTimeOut())
{
nState = STATE_IDLE;
out0 = 0x00;
goto TESTLOOP;
}
}
if(nState == STATE_COARSE_FEED)
{
if(IN_COARSE) //coarse tat
{
out0 = OUT_OPEN_VAL|OUT_KEP_BAO;
}
else
{
out0 = OUT_CLOSE_VAL|OUT_KEP_BAO;
iTime = 20000; //dat 0.5s cho move fine
iDelay = 4000; //doi mo kep bao
nState = STATE_MOVE_FINE_PITT;
goto TESTLOOP;
}
if(CheckTimeOut())
{
nState = STATE_IDLE;
out0 = 0x00;
}
}
if(nState == STATE_FINE_FEED)
{
// PRT1DR &= 0b11110011;
// PRT1DR |= 0b00000100;
if(IN_FINE) //coarse tat
{
// out0 = OUT_CLOSE_VAL|OUT_OPEN_VAL|OUT_KEP_BAO;
out0 = OUT_KEP_BAO;
}
else
{
out0 = 0;
iDelay = 2000; //doi mo kep bao
iTime = 3000; //dat 2.5s cho ra bao
nState = STATE_RABAO;
goto TESTLOOP;
}
if(CheckTimeOut())
{
nState = STATE_IDLE;
out0 = 0x00;
}
}
if(nState == STATE_RABAO)
{
if(iDelay)
{
out0 = OUT_CLOSE_VAL; //doi mo kep bao va dong van
iDelay--;
}
else
{
out0 = OUT_DAY_BAO; //doi mo kep bao va dong van
if(CheckTimeOut())
{
nState = STATE_IDLE;
out0 = 0x00;
}
}
}
heartbeat = 0;
goto TESTLOOP;
MAINLOOP:
goto MAINLOOP;
}
#pragma interrupt_handler COUNTER8_2_ISR_C
void COUNTER8_2_ISR_C()
{
heartbeat = 1;
}
Chương trình đọc phím, hiển thị LCD
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include "modbusmachine.h"
#define THIS_DEVICE_ADDRESS 181
#define ACK 0x06
#define KEY_IDLE 0x00
#define KEY_DOWN 0x01
#define KEY_UP 0x02
#define KEY_HOLD 0x03
#define KEY_WAIT 0x04
#define KF_CANCEL 0x01
#define KF_SET_RECIPE 0x02
#define KF_SET_FINE 0x03
#define KF_ENTER 0x04
#define LCD_DATA_POINT0 9
#define STATE_IDLE 0x00
#define STATE_SET_RECIPE 0x01
#define STATE_SET_FINE 0x02
#define STATE_CANCEL 0x04
#define STATE_SEND_RECIPE 0x05
#define STATE_SEND_FINE 0x06
#define STATE_PARAM_ERR 0x03
#define STATE_COMM_ERR 0x0f
char nState = STATE_IDLE;
char LCDport = 0;
char LCDCurRow = 0;
char LCDCurPos = 0;
char heartbeat = 0;
char x = 0;
char j = 0;
char i = 0;
char nKeyScan = 0;
char nBeep = 0;
char nSpeakerState = 0;
int iTime = 0;
char nKeyPress = 0;
char* pTempChar = 0;
char tmp = 0;
char nRecipe1 = 0;
char nRecipe2 = 0;
char nRecipe3 = 0;
char nRecipe4 = 0;
char nFine1 = 0;
char nFine2 = 0;
char nFine3 = 0;
char nFine4 = 0;
char nTempRecipe1 = 0;
char nTempRecipe2 = 0;
char nTempRecipe3 = 0;
char nTempRecipe4 = 0;
char nTempFine1 = 0;
char nTempFine2 = 0;
char nTempFine3 = 0;
char nTempFine4 = 0;
void SendBuffWithCRC()
{
mb_crc(pInBuff,nInBuffCount);
SerMB_1_Start(UART_PARITY_NONE); // Enable UART bat dau nhan lenh MODBUS
for(i=0;i<nInBuffCount;i++)
{
PRT0DR |= 0b00001000; //Enable Transmitter
SerMB_1_SendData(pInBuff[i]);
while(PRT0DR & 0b00001000)
;
}
pTempChar = (char*)(&crc);
PRT0DR |= 0b00001000; //Enable Transmitter
SerMB_1_SendData(pTempChar[0]);
while(PRT0DR & 0b00001000)
;
PRT0DR |= 0b00001000; //Enable Transmitter
SerMB_1_SendData(pTempChar[1]);
while(PRT0DR & 0b00001000)
;
}
char nKeyState = KEY_IDLE;
char nKeyRow = 1;
char nKeyCol = 1;
char nKeyOldRow = 0;
char nKeyOldCol = 0;
char nKeyHoldTime = 0;
char GetKeyFunc()
{
switch(nKeyOldRow)
{
case 6: //fim cancel
return KF_CANCEL;
case 5: //fim F1
return KF_SET_RECIPE;
case 4: //fim F2
return KF_SET_FINE;
case 3: //fim F3 = Enter
return KF_ENTER;
}
return KF_CANCEL;
}
char GetKeyNum()
{
switch(nKeyOldRow)
{
case 6: //fim cancel
switch(nKeyOldCol)
{
case 0b11111011:
return 7;
case 0b11111101:
return 8;
case 0b11111110:
return 9;
}
break;
case 5: //fim F1
switch(nKeyOldCol)
{
case 0b11111011:
return 4;
case 0b11111101:
return 5;
case 0b11111110:
return 6;
}
break;
case 4: //fim F2
switch(nKeyOldCol)
{
case 0b11111011:
return 1;
case 0b11111101:
return 2;
case 0b11111110:
return 3;
}
break;
case 3: //fim F3 = Enter
switch(nKeyOldCol)
{
case 0b11111011:
return 0;
case 0b11111101:
return '.';
case 0b11111110:
return '+';
}
break;
}
return KF_CANCEL;
}
char KeyScan()
{
PRT2DR |= 0b00111111;
switch(nKeyRow)
{
case 1: //chua dung
// PRT2DR &= 0b11111110;
break;
case 2: //chan ban phim loi
// PRT2DR &= 0b11111101;
break;
case 3:
PRT2DR &= 0b11111011;
break;
case 4:
PRT2DR &= 0b11110111;
break;
case 5:
PRT2DR &= 0b11101111;
break;
case 6:
PRT2DR &= 0b11011111;
break;
}
PRT0DR |= 0b01001111; //chot
PRT0DR &= 0b10111111; //
if(nKeyState == KEY_IDLE)
{
PRT0DR |= 0b00001111;
nKeyCol = PRT0DR | 0b11110000;
if(nKeyCol != 0b11111111) //phim duoc bam
{
nKeyOldCol = nKeyCol;
nKeyOldRow = nKeyRow;
nKeyHoldTime = 1;
nKeyState = KEY_DOWN;
return 0;
}
nKeyRow++;
if(nKeyRow==7)
{
nKeyRow = 1;
}
}
if(nKeyState == KEY_DOWN)
{
PRT0DR |= 0b00001111;
nKeyCol = PRT0DR | 0b11110000;
if(nKeyCol == 0b11111111) //phim duoc tha
{
if(nKeyHoldTime > 3)
{
nKeyRow = 1;
nKeyHoldTime = 1;
nKeyState = KEY_UP;
nBeep = 5;
return KEY_UP;
}
else
{
nKeyRow = 1;
nKeyHoldTime = 1;
nKeyState = KEY_IDLE;
return 0;
}
}
else
{
if((nKeyCol & nKeyOldCol) == nKeyOldCol)
{
nKeyHoldTime++;
if(nKeyHoldTime>250) //giu 3s
{
nKeyHoldTime = 250;
nKeyState = KEY_HOLD;
nBeep = 50;
return KEY_HOLD;
}
}
else //phim da duoc tha, 1 phim khac dang bi giu
{
nKeyRow = 1;
nKeyState = KEY_WAIT;
return 0;
}
}
}
if(nKeyState == KEY_UP)
{
nKeyRow = 1;
nKeyState = KEY_WAIT;
}
if(nKeyState == KEY_HOLD)
{
nKeyRow = 1;
nKeyState = KEY_WAIT;
}
if(nKeyState == KEY_WAIT)
{
PRT0DR |= 0b00001111;
nKeyCol = PRT0DR | 0b11110000;
if(nKeyCol != 0b11111111) //row co phim duoc bam
{
return 0;
}
nKeyRow++;
if(nKeyRow==7)
{
nKeyRow = 1;
nKeyHoldTime ++;
if(nKeyHoldTime > 3)
{
nKeyHoldTime = 0;
nKeyState = KEY_IDLE;
}
}
}
return 0;
}
void LCD_UpdateData()
{
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
// LCD_1_Position(0, 12);
LCD_1_Control(LCD_1_CURSOR_OFF);
LCD_1_Position(0, LCD_DATA_POINT0);
LCD_1_WriteData(nTempRecipe1 + 48);
LCD_1_WriteData(nTempRecipe2 + 48);
LCD_1_WriteData('.');
LCD_1_WriteData(nTempRecipe3 + 48);
LCD_1_WriteData(nTempRecipe4 + 48);
LCD_1_Position(1, LCD_DATA_POINT0);
LCD_1_WriteData(nTempFine1 + 48);
LCD_1_WriteData(nTempFine2 + 48);
LCD_1_WriteData('.');
LCD_1_WriteData(nTempFine3 + 48);
LCD_1_WriteData(nTempFine4 + 48);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
}
char CheckTimeOut()
{
if(!iTime)
{
return 1;
}
else
{
iTime--;
return 0;
}
}
void main()
{
int k;
M8C_EnableGInt ; // Turn on interrupts
// SerMB_1_TxIntMode(SerMB_1_INT_MODE_TX_COMPLETE);
// SerMB_1_EnableInt();
// SerMB_1_Start(UART_PARITY_NONE); // Enable UART
TimeMB_1_EnableInt();
TimeMB_1_WritePeriod(250);
// Counter8_1_Start();
Counter8_2_EnableInt();
// Counter8_2_WritePeriod(40);
UART_2_TxIntMode(UART_2_INT_MODE_TX_COMPLETE);
UART_2_EnableInt();
PRT0DR = 0b00111111;
PRT1DR = 0b11110011;
PRT2DR = 0b11111111; //mo phanh
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Init();
//LCD_1_PrString(char * sRamString);
LCD_1_Position(0, 3);
LCD_1_PrCString("AU LAC Co");
Counter8_2_Start();
SpeakerPWM8_1_CONTROL_REG = SpeakerPWM8_1_CONTROL_REG_START_BIT;
for(i = 0;i<15;i++)
{
while(!heartbeat);
heartbeat = 0;
}
SpeakerPWM8_1_CONTROL_REG = 0;
LCD_1_Position(0, 0);
LCD_1_PrCString("Dat : kg");
LCD_1_Position(1, 0);
LCD_1_PrCString("Cat tinh: kg");
LCDport = PRT2DR;
LCD_UpdateData();
TESTLOOP:
if(!heartbeat)
goto TESTLOOP;
if(nState == STATE_IDLE )
{
tmp = KeyScan();
if(tmp==KEY_UP )
{
iTime = 1000;
if(nKeyOldCol == 0b11110111) //fim chuc nang
{
tmp = GetKeyFunc();
if(tmp==KF_SET_RECIPE)
{
nState = STATE_SET_RECIPE;
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0, LCD_DATA_POINT0);
// LCD_1_Control(LCD_1_CURSOR_ON);
LCD_1_Control(LCD_1_CURSOR_WINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
LCDCurPos = 0;
}
if(tmp==KF_SET_FINE)
{
nState = STATE_SET_FINE;
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(1, LCD_DATA_POINT0);
LCD_1_Control(LCD_1_CURSOR_BLINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
LCDCurPos = 0;
}
}
}
}
if(nState == STATE_SET_RECIPE)
{
tmp = KeyScan();
if(tmp==KEY_UP )
{
if(nKeyOldCol == 0b11110111) //fim chuc nang
{
tmp = GetKeyFunc();
if(tmp==KF_SET_FINE)
{
nTempRecipe1 = nRecipe1;
nTempRecipe2 = nRecipe2;
nTempRecipe3 = nRecipe3;
nTempRecipe4 = nRecipe4;
LCD_UpdateData();
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(1, LCD_DATA_POINT0);
LCD_1_Control(LCD_1_CURSOR_BLINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
nState = STATE_SET_FINE;
goto TESTLOOP;
}
if(tmp==KF_CANCEL)
{
nState = STATE_CANCEL;
}
if(tmp==KF_ENTER)
{
nRecipe1 = nTempRecipe1;
nRecipe2 = nTempRecipe2;
nRecipe3 = nTempRecipe3;
nRecipe4 = nTempRecipe4;
nState = STATE_SEND_RECIPE;
}
goto TESTLOOP;
}
else //fim so
{
tmp = GetKeyNum();
if(tmp!='.' && tmp!='+')
{
switch(LCDCurPos)
{
case 0 :
nTempRecipe1 = tmp;
LCD_UpdateData();
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0,LCD_DATA_POINT0+1);
LCD_1_Control(LCD_1_CURSOR_WINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
break;
case 1 :
nTempRecipe2 = tmp;
LCD_UpdateData();
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0,LCD_DATA_POINT0+3);
LCD_1_Control(LCD_1_CURSOR_WINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
break;
case 2 :
nTempRecipe3 = tmp;
LCD_UpdateData();
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0,LCD_DATA_POINT0+4);
LCD_1_Control(LCD_1_CURSOR_WINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
break;
case 3 :
nTempRecipe4 = tmp;
LCD_UpdateData();
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0,LCD_DATA_POINT0);
LCD_1_Control(LCD_1_CURSOR_WINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111;
break;
}
LCDCurPos++;
if(LCDCurPos>3)
LCDCurPos = 0;
}
}
iTime = 1000;
}
if(CheckTimeOut())
{
LCDCurPos = 0;
nState = STATE_CANCEL;
}
}
if(nState == STATE_SET_FINE)
{
LCD_UpdateData();
nState = STATE_IDLE;
}
if(nState == STATE_SEND_RECIPE)
{
LCD_UpdateData();
nState = STATE_IDLE;
}
if(nState == STATE_SEND_FINE)
{
LCD_UpdateData();
nState = STATE_IDLE;
}
if(nState == STATE_PARAM_ERR)
{
LCD_UpdateData();
nState = STATE_IDLE;
}
if(nState == STATE_COMM_ERR)
{
}
if(nState == STATE_CANCEL)
{
nTempRecipe1 = nRecipe1;
nTempRecipe2 = nRecipe2;
nTempRecipe3 = nRecipe3;
nTempRecipe4 = nRecipe4;
nTempFine1 = nFine1;
nTempFine2 = nFine2;
nTempFine3 = nFine3;
nTempFine4 = nFine4;
LCD_UpdateData();
nState = STATE_IDLE;
}
if(tmp==KEY_UP )
{
if(nKeyOldCol == 0b11110111) //fim chuc nang
{
switch(nKeyOldRow)
{
case 6: //fim cancel
// if(LCDCurRow == 0)
iTempRecipeH = iRecipeH;
iTempRecipeL = iRecipeL;
iTempFineH = iFineH;
iTempFineL = iFineL;
LCD_UpdateData();
break;
case 5: //fim F1
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0, 11);
LCD_1_Control(LCD_1_CURSOR_BLINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
LCDCurRow = 0;
break;
case 4: //fim F2
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(1, 11);
LCD_1_Control(LCD_1_CURSOR_BLINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
LCDCurRow = 1;
break;
case 3: //fim F3 = Enter
iRecipeH = iTempRecipeH;
iRecipeL = iTempRecipeL;
iFineH = iTempFineH;
iFineL = iTempFineL;
LCD_UpdateData();
break;
}
}
if(nKeyOldCol == 0b11111011) //fim 7,4,1,0
{
switch(nKeyOldRow)
{
case 6: //fim 7
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
// LCD_1_Position(0, 11);
iRecipeH/10 + 48);
if(LCDCurRow == 0)
{
iTempRecipeH = iRecipeH;
iTempRecipeL = iRecipeL;
LCD_UpdateData();
}
if(LCDCurRow == 1)
{
iTempFineH = iFineH;
iTempFineL = iFineL;
LCD_UpdateData();
}
LCD_1_WriteData(iRecipeH/10 + 48);
LCD_1_WriteData(iRecipeH%10 + 48);
LCD_1_WriteData('.');
LCD_1_WriteData(iRecipeL/10 + 48);
LCD_1_WriteData(iRecipeL%10 + 48);
LCD_1_Position(1, 11);
LCD_1_WriteData(iFineH/10 + 48);
LCD_1_WriteData(iFineH%10 + 48);
LCD_1_WriteData('.');
LCD_1_WriteData(iFineL/10 + 48);
LCD_1_WriteData(iFineL%10 + 48);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
break;
case 5: //fim F1
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(0, 11);
LCD_1_Control(LCD_1_CURSOR_BLINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
break;
case 4: //fim F2
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
LCD_1_Position(1, 11);
LCD_1_Control(LCD_1_CURSOR_BLINK);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
break;
case 3: //fim F1
PRT2DR = LCDport;
PRT0DR |= 0b10000000; //chot LCD
// LCD_1_Position(0, 12);
LCD_1_Control(LCD_1_CURSOR_OFF);
LCDport = PRT2DR;
PRT0DR &= 0b01111111; //
break;
}
}
iTime = 250; //5 s 0 bam nut
nBeep = 5;
}
if(nBeep)
{
nBeep--;
SpeakerPWM8_1_CONTROL_REG = SpeakerPWM8_1_CONTROL_REG_START_BIT;
PRT2DR &= 0b00111111; //bat den led
PRT0DR |= 0b01000000; //chot
PRT0DR &= 0b10111111; //
}
else
{
SpeakerPWM8_1_CONTROL_REG = 0;
PRT2DR |= 0b11000000; //tat led
PRT0DR |= 0b01000000; //chot
PRT0DR &= 0b10111111; //
}
heartbeat = 0;
goto TESTLOOP;
/*
MAINLOOP:
if(nState == STATE_CMD_ENDFR)
{
SerMB_1_Stop();
//Check crc
mb_crc(pInBuff, nInBuffCount-2);//du lieu khong co CRC
if(pInBuff[0] == 0)//neu byte dau tien bang 0
{
switch (pInBuff[1]) //check Funtion
{
case 71: //dong bo chuyen dong
nState = STATE_MOTION_SYNC;
goto MAINLOOP;
case 72: //reset
nState = STATE_RESET;
goto MAINLOOP;
default:
nState = STATE_IDLE;
nInBuffCount = 0;
SerMB_1_Start(UART_PARITY_NONE); //
goto MAINLOOP;
}
}
if(pInBuff[0] == THIS_DEVICE_ADDRESS)//neu byte dau tien bang dia chi cua thiet bi 181
{
switch (pInBuff[1]) //check Funtion
{
case 71: //dong bo chuyen dong
nState = STATE_MOTION_SYNC;
goto MAINLOOP;
case 72: //reset
nState = STATE_RESET;
goto MAINLOOP;
case 3:
nState = STATE_READ;//doc
goto MAINLOOP;
case 6:
nState = STATE_WRITE;//ghi
goto MAINLOOP;
case 16:
nState = STATE_MUL_WRITE;//
goto MAINLOOP;
default:
pInBuff[2] = E_CODE_ILLEGAL_FUNC;
nState = STATE_SLAVE_ERR;
goto MAINLOOP;
}
}
else
{
nInBuffCount = 0;
nState = STATE_IDLE;
SerMB_1_Start(UART_PARITY_NONE); //
}
}
if(nState == STATE_RESET)
{
nInBuffCount = 0;
nState = STATE_IDLE;
SerMB_1_Start(UART_PARITY_NONE); //
}
if(nState == STATE_MOTION_SYNC)//neu trang thai bang trang thai dong bo chuyen dong
{
nInBuffCount = 0;
nState = STATE_IDLE;
SerMB_1_Start(UART_PARITY_NONE); //
}
if(nState == STATE_READ)//neu la trang thai doc
{
switch (pInBuff[3]) //check Dia chi can doc
{
case REG_MODE: //Doi mode nState == STATE_READ
if(pInBuff[5]==1) //check so luong thanh ghi can doc
{
goto MAINLOOP;
}
else //doc nhieu qua, o ho tro
{
pInBuff[2] = E_CODE_ILLEGAL_DATA_VAL;
nState = STATE_SLAVE_ERR;
}
goto MAINLOOP;
// case REG_STATUS: //reset
// goto MAINLOOP;
case REG_CUR_POS: //nState == STATE_READ
if(pInBuff[5]==2) //check so luong thanh ghi can doc
{
}
else //doc nhieu qua, o ho tro
{
pInBuff[2] = E_CODE_ILLEGAL_DATA_VAL;
nState = STATE_SLAVE_ERR;
}
goto MAINLOOP;
case REG_IM_SPEED: //nState == STATE_READ
if(pInBuff[5]==1) //check so luong thanh ghi can doc
{
}
else //doc nhieu qua, o ho tro
{
pInBuff[2] = E_CODE_ILLEGAL_DATA_VAL;
nState = STATE_SLAVE_ERR;
}
goto MAINLOOP;
case REG_SYNC_SPEED: //nState == STATE_READ
nState = STATE_IDLE;
SerMB_1_Start(UART_PARITY_NONE); //
goto MAINLOOP;
default: //nState == STATE_READ
pInBuff[2] = E_CODE_ILLEGAL_DATA_ADDR;
nState = STATE_SLAVE_ERR;
goto MAINLOOP;
}
}
goto MAINLOOP;
*/
}
#pragma interrupt_handler UART_2_RX_ISR_C
void UART_2_RX_ISR_C()
{
UART_2_bReadRxData();
UART_2_bReadRxStatus();
}
#pragma interrupt_handler UART_2_TX_ISR_C
void UART_2_TX_ISR_C()
{
UART_2_bReadTxStatus();
}
#pragma interrupt_handler COUNTER8_2_ISR_C
void COUNTER8_2_ISR_C()
{
heartbeat = 1;
}
Tài liệu tham khảo
Tiếng Việt
[1] Hoàng Minh Sơn. Mạng truyền thông công nghiệp. NXB KH & KT, 2006, tr.161-170, 182-189.
[2] Nguyễn Xuân Sơn. Tài liệu về PSoC. Luận văn tốt nghiệp, tr.1-3.
Tiếng Anh
[3] dsPIC30F6010A/6015 datasheet, Microchip, 2007, tr.3,4, 65-77, 117-131.
[4] IND130 Technical Manual, Mettler Toledo, 2002, tr.61-68.
[5] PSoC Mixed Signal Aray Final Datasheet, Cypress MicroSystems, 2004, tr.1-3.
Các file đính kèm theo tài liệu này:
- h7879 th7889ng cn t7921 2737897ng s7917 d7909ng trong qu tramp23.doc