Công cụ: Phần mềm thiết kế mạch in Altium.
Thiết kế nguyên lý cho vi điều khiển STM32F103C8T6 của hãng ST, phần nguyên lý được tham khảo theo tài liệu của hãng, có một số tùy biến nhỏ cho phù hợp với mục đích của đồ án.
Hình 3.23 Nguyên lý STM32F103C8T6
Chân BOOT0 được nối đất thông quả trở 10k. Lý do như sau: STM32F103C8 có 3 chế độ BOOT:
Hình 3.24 Chế độ BOOT của STM32F103C8 [ CITATION ST18 \l 1033 ]
Chân BOOT = 0: Boot từ Flash. Thực thi chương trình do người dùng viết code nạp vào.
Chân BOOT0 = 1, BOOT1 = 0: Chạy chương trình từ bộ nhớ hệ thống: chương trình bootloader của hãng ST.
Chân BOOT0 = 1, BOOT1 = 1: Chạy chương trình từ RAM.
Với thiết kế thông thường, nối chân BOOT0 qua điện trở 10k xuống GND để khi cấp nguồn chip sẽ chạy luôn chương trình người dùng nạp vào.
Phần tạo dao động cho mạch, sử dụng thạch anh nội 8MHz (tham khảo của ST).
Hình 3.25 Thạch anh tạo dao động cho vi điều khiển
Hai tụ 22pF được sử dụng để tăng ổn định tần số dao động cho mạch. Trong những ứng dụng yêu cầu tạo Timer chính xác cỡ us, yêu cầu tần số dao động phải càng ổn định càng tốt.
STM32F103C8 có hỗ trợ giao tiếp với thạch anh ngoại,nghĩa là ngoài thạch anh 8MHz chính được sử dụng để tạo dao động cho mạch, có thể có thêm thạch anh bên ngoài cho những mục đích khác. Trong nguyên lý của ST sử dụng thạch anh ngoại 32.768kHz. Trong những ứng dụng thông thường không cần đến thạch anh ngoại này. Nhưng trong phạm vi đồ án, có sử dụng Watchdog Timer, do vậy mạch nguyên lý cho thạch anh ngoại như sau (tham khảo của ST):
Hình 3.26 Thạch anh ngoại cho STM32F103C8
STM32F103C8 không cần sử dụng thêm bất kỳ thêm mạch reset bên ngoài
nào.
Hình 3.27 Mạch reset cho STM32F103C8
Để có thể hoạt động tốt hơn có thể dụng phối hợp tụ 104 với điện trở 10k. Nguồn 12V cung cấp cho thiết bị được qua ổn áp LM2596S, đầu ra của LM2596S là 5V. Phần nguyên lý của ổn áp LM2596S được tham khảo trong datasheet của LM2596S.
Hình 3.28 Ổn áp 5V sử dụng LM2596S
Vì STM32F103C8 yêu cầu nguồn cung cấp 3.3V, mạch nguyên lý cho ổn áp 3.3V cung cấp cho vi điều khiển (tham khảo của ST):
Hình 3.29 Ổn áp 3.3V dùng RT9193-33GB
Về cảm biến DHT22 và DS18B20, cả hai đều sử dụng giao thức 1 – Wire, bus data được nối với nguồn cung cấp thông qua trở kéo 4.7k. Nguồn cung cấp là nguồn ngoài, không sử dụng nguồn ký sinh của bus để đảm bảo độ tin cậy và tăng tính ổn định.
Hình 3.30 Nguyên lý cho cảm biến
Về phần nút nhấn, được nối thẳng với chân I/O của vi điều khiển và nối xuống đất chứ không qua điện trở kéo.
Hình 3.31 Nút nhấn
Lý do không dùng trở kéo ngoài vì trên các chân I/O của STM32F103C8 đã có sẵn trở kéo, dùng luôn các trở kéo đấy để làm trở kéo cho nút nhấn.
Hình 3.32 Trở kéo có sẵn trên STM32F103C8
Về phần LED cho mạch, trong đồ án chọn LED SMD 0805 có điện áp định mức của LED là 2.4V, dòng định mức 20mA (tra trong datasheet của LED SMD 0805):
Hình 3.33 LED
LED được mắc theo kiểu sinh dòng, đảm bảo cho LED sáng ổn định hơn phòng trường hợp mắc hạn dòng thì dòng ra từ vi điều khiển bé, không đủ dòng định mức cung cấp cho LED.
Về giao thức cho Modbus RTU, sử dụng đường truyền vật lý RS485
Hình 3.34 MAX485
Tín hiệu TTL từ vi điều khiển (mức cao/mức thấp) qua bộ MAX485 được chuyển thành tín hiệu của đường bus A, B vì mức điện áp của RS232/RS485 không tương thích với TTL.
Khi MCU đưa mức TTL thấp vào bộ chuyển đổi MAX48 làm cho điện áp của B cao hơn điện áp của A, ngược lại, khi MCU đưa mức cao TTL vào, điện áp của A sẽ cao hơn điện áp của B.
Chân 2 và 3 của MAX485 được nối với nhau và nối với I/O của vi điều khiển. Khi ở chế độ truyền, set mức logic cho chân I/O này ở mức cao và ngược lại set ở mức thấp ở chế độ nhận dữ liệu. Modbus hoạt động theo bán song công (half – duplex). Các điện trở kéo R6, R7, R9 là không cần thiết, có thể nối trực tiếp với vi điều khiển. Ở đây sử dụng trở kéo để đảm bảo trạng thái chân 1, 2, 3, 4 được xác định (mức cao) ngay cả khi vi điều khiển bị mất nguồn, hay ở trạng thái chờ (không có truyền/nhận dữ liệu).
Hai trở kéo R10 và R13 là hai điện trở phân cực (phân cực đường truyền), được sử dụng để đảm bảo rằng sự chênh lệch điện áp giữa A và B sẽ là khoảng 200mV khi bus không hoạt động, tránh hiện tượng nhảy mức tín hiệu trên bus lúc thì mức thấp lúc thì mức cao. Bus ở trạng thái nghỉ phải luôn ở mức cao (quy định của đường truyền), nếu có nhảy sang mức thấp bus bị hiểu nhầm là chuẩn bị có truyền/nhận tín hiệu.
Sơ đồ nguyên lý của toàn bộ thiết bị được thể hiện ở Hình 3 .35
CHƯƠNG 4. THIẾT KẾ PHẦN MỀM 4.1 Phần mềm cho vi điều khiển
4.1.1 Lưu đồ thuật toán của thiết bị gateway
Bắt đầu
Khởi tạo phần cứng
Đọc cảm biến, trạng thái nút nhấn, trạng thái Led
Gửi request đến slave có địa chỉ là ID
N
Có dữ liệu từ slave Timeout
N Y Y N CRC đúng Hiển thị lỗi Y Slave phản hồi
4.1.2 Khối cảm biến
Cảm biến được lựa chọn sử dụng trong đồ án là cảm biến nhiệt độ độ ẩm DHT22 và cảm biến nhiệt độ DS18B20. Hai cảm biến đều giao tiếp theo chuẩn 1 – Wire.
Sơ đồ thuật toán đọc cảm biến:
Giá trị cảm biến đọc được vi điều khiển đọc về và ghi xuống vùng thanh ghi Holding của Modbus. Master đọc thanh ghi này để lấy giá trị đo được từ cảm biến.
4.1.3 Khối nút nhấn
Lưu đồ thuật toán đọc nút nhấn:
Bắt đầu
Đọc giá trị nhiệt độ, độ ẩm từ cảm biến
Ghi vào thanh ghi Holding
Bắt đầu
N Nhấn nút nhấn ?
Y
Thay đổi trạng thái thanh ghi Discrete Input
Khi ấn nút nhấn, thiết bị nhận thấy sự thay đổi bằng cách đọc trạng thái đầu vào trên chân GPIO. Khi thiết bị nhận thấy thay đổi trên trạng thái chân I/O, thiết bị thay đổi trạng thái của vùng thanh ghi Discrete Input (từ mức 0 sang 1 và ngược lại).
4.1.4 Khối LED
Lưu đồ thuật toán cho khối LED:
Giá trị trên vùng thanh ghi Coil thay đổi khi Master thay đổi trạng thái ON/OFF trên cùng thanh ghi coil. Vi điều khiển kiểm tra, nếu thanh ghi Coil có sự thay đổi trạng thái thì điều khiển ON/OFF của LED. Giá trị thanh ghi Coil bằng 0 thì OFF LED và ngược lại giá trị thanh ghi Coil bằng 1 LED OFF.
4.1.5 Khối truyền thông RTU
Khối truyền thông mô tả quá trình request – respond giữa master – slave, quá trình tạo CRC, và quá trình đọc/ghi các vùng thanh ghi.
Trong phần lý thuyết Modbus đã trình bày về PDU và ADU. Giao thức Modbus định nghĩa 3 loại PDU:
Modbus Request PDU, mb_red_pdu Modbus Responde PDU, mb_rsp_pdu
Modbus Exception Response PDU, mb_excep_rsp_pdu Bắt đầu
N
Thanh ghi Coil thay đổi trạng thái Y
mb_red_pdu và mb_rsp_pdu được định nghĩa: mb_red_pdu, mb_rsp_pdu = {function_code, request_data}, trong đó function_code = 1 byte Modbus
function code, request_data = n byte data.
mb_excep_rsp_pdu được định nghĩa bằng {exception_function_code, request_data}, trong đó exception_function_code = 1 byte Modbus function code + 0x80. exception_code = 1 byte Modbus exception code. Chi tiết tham khảo thêm tại [ CITATION mod12 \l 1033 ]
4.1.5.1. Modbus request – respond
Chờ yêu cầu từ master
Kiểm tra function code Nhận lệnh từ
master
ExceptionCode = 1
Kiểm tra địa chỉ
ExceptionCode = 2
Kiểm tra giá trị dữ liệu ExceptionCode = 3
Thực hiện function code
ExceptionCode = 4,5,6
Gửi Modbus Exception Respond
Gửi Modbus respond
Trong các khối so sánh, nếu kiểm tra hợp lệ thì thực hiện bước tiếp theo, nếu kiểm tra không hợp lệ thì trả về một ngoại lệ tương ứng (ExceptionCode từ 1 đển 6). Nếu xảy ra ExceptionCode, gửi thông báo trả về cho master và chờ đợi yêu cầu tiếp theo.
4.1.5.2. Tạo mã CRC
Mã CRC được tạo theo nguyên tắc như sau [ CITATION mod06 \l 1033 ]: 1. Load vào thanh ghi 16 bit giá trị 0xFFFF (mọi bit đều bằng 1). Gọi đây là
thanh ghi CRC.
2. XOR tám bit LSB (byte thấp) của thanh ghi CRC với byte dữ liệu đầu tiên của khung truyền, kết quả thu được đặt vào thanh ghi CRC.
3. Thực hiện phép dịch thanh ghi CRC sang phải 1 bit. Kiểm tra bit LSB vừa được dịch ra.
4. Nếu bit LSB bằng 1, thực hiện phép XOR bit của thanh ghi CRC với đa thức sinh của Modbus RTU CRC-16: (CRC-16 chuẩn ANSI) giá trị tương ứng là của nó là 0x8005, giá trị đảo (reversed) của nó là 0xA001. Thực hiện phép XOR của thanh ghi CRC với 0xA001.
Nếu bit LSB bằng 0, lặp lại thực hiện bước 3.
5. Giá trị CRC được tính xong khi đã hoàn thành đủ 8 lần dịch (vì thanh ghi CRC 16 bit), ở mỗi lần dịch thực hiện phép kiểm tra ở bước 3 và bước 4. 6. Ở các byte tiếp theo của khung truyền, thực hiện lặp lại các bước từ bước
2 đến bước 5.
7. Nội dung cuối cùng của thanh ghi CRC chính là giá trị CRC.
8. Khi CRC được đặt vào message, các byte thấp và byte cao của nó phải được đảo lại.
Trong đó:
N = số bit mang thông tin Bắt đầu 0xFFFF -> CRC16 N = 0 Dịch phải CRC16 Y CRC16 XOR POLY ->CRC16 LSB = 1? N N = N+1 N N > 7 byte tiếp theo Y N Kết thúc khung truyền Y Kết thúc
POLY: đa thức sinh của CRC-16 Modbus = 0x8005 Trong CRC 16, byte được truyền đầu tiên là byte LSB
4.1.5.3. Đọc Coil, Discrete Input, Holding Register, Input Register
Lưu đồ thuật toán:
Bắt đầu
Nhận mb_req_pdu
ExceptionCode = 01 Function Code hợp lệ?
ExceptionCode = 03 Số lượng thanh ghi đọc hợp lệ?
ExceptionCode = 02 Địa chỉ có hợp lệ?
Yêu cầu xử lý
ExceptionCode = 04 Đọc thành công?
Gửi mb_rsp
Trong các khối subroutine, nếu kết quả trả về hợp lệ thì thực hiện các bước tiếp theo, còn không trả về ExceptionCode, gửi master mã exception code và kết thúc.
Về cách thức thì thuật toán đọc các vùng thanh ghi tương tự như nhau, chỉ khác nhau về địa chỉ thanh ghi và dải địa chỉ thanh ghi.
4.1.5.4. Ghi vào một thanh ghi Coil
Bắt đầu
Nhận mb_req_pdu
ExceptionCode = 01 Function Code hợp lệ?
ExceptionCode = 03 Output value =
0x0000/0xFF00
ExceptionCode = 02 Địa chỉ output == OK?
Yêu cầu xử lý WriteSingle Output == OK? ExceptionCode = 04 Gửi mb_rsp Gửi mb_exception_rsp Kết thúc
4.1.5.5. Ghi vào một thanh ghi Holding
Bắt đầu
Nhận mb_req_pdu
ExceptionCode = 01 Function Code hợp lệ?
0x0000 0xFFFF ExceptionCode = 03
ExceptionCode = 02 Địa chỉ thanh ghi == OK?
Yêu cầu xử lý WriteSingle Holding == OK? ExceptionCode = 04 Gửi mb_rsp Gửi mb_exception_rsp Kết thúc
4.1.5.6. Ghi nhiều thanh ghi Coil
Trong đó N = số thanh ghi Coil cần ghi /8 (do giá trị Coil chỉ là một bit ON/OFF), nếu phần dư khác 0 thì N = N +1.
Bắt đầu
Nhận mb_req_pdu
ExceptionCode = 01 Function Code hợp lệ?
Số lượng thanh ghi hợp lệ và Byte Count = N? ExceptionCode = 03 ExceptionCode = 02 Địa chỉ có hợp lệ? Yêu cầu xử lý ExceptionCode = 04 WriteMultiple Coil == OK? Gửi mb_rsp Gửi mb_exception_rsp Kết thúc
4.1.5.7. Ghi nhiều thanh ghi Holding
Bắt đầu
Nhận mb_req_pdu
ExceptionCode = 01 Function Code hợp lệ?
Số lượng thanh ghi hợp lệ và Byte Count = N *2 ExceptionCode = 03 ExceptionCode = 02 Địa chỉ có hợp lệ? Yêu cầu xử lý ExceptionCode = 04 WriteMultiple Holding == OK? Gửi mb_rsp Gửi mb_exception_rsp Kết thúc
4.2 Cấu hình CubeMX
Bản chất khung truyền của Modbus RTU xây dựng trên giao thức truyền thông nối tiếp UART. Do vậy cấu hình cho STM32F103C8 dùng UART truyền không đồng bộ, thêm một chân I/O để thực hiện truyền half – duplex (bán song công). Tốc độ truyền Modbus trong công nghiệp thường là 9600 baud, do vậy cấu hình cho UART tốc độ 9600 bit/s.
Hình 4.36 Cấu hình UART cho vi điều khiển
Tiếp theo, vì không giống như UART có các bit start và stop để nhận biết bắt đầu và kết thúc khung truyền, khung truyền của Modbus không có cờ để nhận biết dữ liệu truyền đến lúc nào kết thúc. Khung truyền của Modbus được quy định như sau:
Hình 4.37 Khung truyền Modbus RTU
Giao thức Modbus quy định thời gian tối thiểu trước mỗi khung truyền là 3.5 character và thời gian kết thúc tối thiểu 3.5 character.
Thời gian truyền một character được tính như sau: Baudrate = 9600 bit/s => Thời gian truyền 1 bit: s
Khung truyền UART: 1 bit start – 8 bit data – 1 bit parity – 1 stop bit, tổng 11 bit. Nghĩa là một character là 11 bit chứ không phải 8 bit, do đó thời gian truyền một character bằng s. Do đó thời gian của 3.5 character bằng
4010us.
Sử dụng Timer của vi điều khiển để tạo ra khoảng thời gian này. Timer đếm từ 0 cho đến khi đủ 4010us thì đặt lại, đếm lại từ 0. Theo Hình 4 .37, thời gian giữa các lần truyền các byte ngắn hơn rất nhiều thời gian 3.5 character. Khi truyền, lúc có ngắt truyền/ngắt nhận UART, bật Timer lên để Timer bắt đầu đếm, nếu lần nhận ngắt tiếp theo chưa phải là ngắt của Timer thì dữ liệu chưa được truyền xong, chưa phải là byte cuối cùng. Ngắt của UART có mức ưu tiên cao hơn để trường hợp mà ngắt UART và ngắt Timer xảy ra đồng thời, dữ liệu vẫn chưa truyền xong nhưng vi điều khiển lại hiểu đấy là tín hiệu kết thúc khung truyền.
Timer sử dụng cho Modbus thường có chu kỳ 50us, nghĩa là tần số f = 20kHz. Để đếm đến 4010us thì counter period của nó bằng = 80,2 80. Vi điều khiển cấu hình cho tần số clock = 72MHz. Để cho = 20kHz, tính như sau:
Cấu hình Timer cho CubeMX như sau:
Hình 4.38 Cấu hình Timer cho vi điều khiển
Sử dụng cách tính tương tự để tạo Timer khác tạo delay với chu kỳ 1us. Ngoài ra trong lúc đọc dữ liệu từ cảm biến DHT22 và DS18B20, sẽ có lúc bị treo do tràn bộ nhớ, code của mình không được tối ưu. Giải pháp đưa ra ở đây là sử dụng Watchdog Timer để reset toàn bộ vi điều khiển sau 1.5s (1.5s do quá trình quan sát thực tiễn, nghĩa là dựa trên kinh nghiệm) để tránh bị tràn bộ nhớ. Tràn bộ nhớ thì dữ liệu không đọc về được, master request thì slave không phản hồi dẫn đến lỗi timeout của Modbus RTU.
Hình 4.39 Cấu hình Watchdog Timer (IDWG)
Cách tính như sau:
với tần số clock là 40kHz (STM32F103 sử dụng thạch anh ngoại cấp clock cho Watchdog Timer), prescale có giá trị bằng 4, 8, 16, 32, 64, 128, 256. Có thể lựa chọn những giá trị này. Prescale càng lớn, time càng lớn. Ở đây chọn prescale = 256, time = 1.5s (sau 1.5s) vi điều khiển tự reset.
Chọn reload value = 234.
4.3 Thiết kế HMI
- Công cụ sử dụng: Phần mềm thiết kế HMI iXDeveloper2 cho Beijier iX T7E.
Yêu cầu thiết kế HMI: Thiết kế HMI với những yêu cầu như sau: Hiển thị số liệu đo được từ tín hiệu đo lường (cảm biến nhiệt độ
DHT22 và cảm biến nhiệt độ DS18B20).
Thể hiện được đặc tính đặc tính đồ thị của tín hiệu đo lường. Thể hiện trạng thái của các tín hiệu DI, DO bằng màu
Hình 4.40 Giao diện HMI Beijier iX T7E
Trong đó:
Hiển thị giá trị đo của cảm biến nhiệt độ độ ẩm DHT22 và cảm biến nhiệt độ DS18B20.
Vẽ đặc tính đồ thị của hai tín hiệu đo lường là cảm biến DHT22 và DS18B20.
Thể hiện trạng thái của nút nhấn và đèn báo.
CHƯƠNG 5. KẾT QUẢ ĐẠT ĐƯỢC 5.1 Thiết bị gateway
Thiết bị gateway được thiết kế sử dụng công cụ Altium ở lớp top (mặt trước) được thể hiện trong Hình 5 .41
Hình 5.41 Top Layer của PCB
Lớp bottom (mặt sau) của PCB được thể hiện trong Hình 5 .42
Hình 5.42 Bottom Layer của PCB
Hình 5.43 PCB trong thực tế - Top Layer
Hình ảnh thực tế PCB lớp bottom layer: