BÁO CÁO BÀI TẬP LỚN Môn: Thiết kế Hệ thống nhúng Đề tài: Lập trình Vi điều khiển STM32 giao tiếp với Modul DS1307 và cảm biến đo dòng ACS712 hiển thị thông số lên LCD , truyền thông số lên máy tính. Cài đặt bộ lập lịch từ máy tính. Yêu cầu cụ thể: Lập trình theo bộ lập lịch kiểu đếm tick và thực hiện các task theo lập lịch đó. Áp dụng FreeRTOS để lập trình. Mục lục Phần 1: Thông tin nhóm......................................................................................... 2 Phần 2: Yêu cầu bài tập lớn.................................................................................... 3 Phần 3: Giới thiệu về phần cứng ............................................................................ 4 3.1 Giới thiệu nguyên lý các Modul phần cứng ................................................... 4 3.2 Các ngoại vi của STM32................................................................................. 9 3.3 Sơ đồ ghép nối giữa STM32 với phần cứng................................................. 23 3.4 Lưu đồ thuật toán giao tiếp giữa STM32 và module phần cứng.................. 23 Phần 4: Thiết kế phần mềm ................................................................................. 25 4.1 Phân tích xử lý đảm bảo tính thời gian thực ............................................... 25 4.2 Thiết kế bộ lập lịch ...................................................................................... 25 4.3 Phân tích lập trình đa nhiệm ....................................................................... 26 Phần 5: Kết quả và đánh giá................................................................................. 30 5.1 Các kết quả đạt được.................................................................................. 30 5.2 Phân tích và đánh giá kết quả ..................................................................... 34 5.3 Thống kê công việc và đánh giá đóng góp................................................... 34
Thông tin nhóm
Danh sách các thành viên trong nhóm:
STT Họ và Tên MSSV
Yêu cầu bài tập lớn
Đề tài: Lập trình Vi điều khiển STM32 giao tiếp với Modul DS1307 và cảm biến đo dòng ACS712 hiển thị thông số lên LCD , truyền thông số lên máy tính Cài đặt bộ lập lịch từ máy tính
Lập trình theo bộ lập lịch kiểu đếm tick và thực hiện các task theo lập lịch đó
Áp dụng FreeRTOS để lập trình
Giới thiệu về phần cứng
Giới thiệu nguyên lý các Modul phần cứng
1 Cảm biến dòng điện ACS-712
Cảm biến dòng điện ACS712 là một IC cảm biến dòng tuyến tính dựa trên hiệu ứng Hall ACS xuất ra 1 tín hiệu analog, Vout biến đổi tuyến tính theo sự thay đổi của dòng điện 𝐼 𝑖𝑛 được lấy mẫu thứ cấp DC (hoặc AC), trong phạm vi đã cho Tụ (Cf theo sơ đồ) được dùng với mục đích chống nhiễu và có giá trị tùy thuộc vào từng mục đích sử dụng
Hiệu ứng Hall là một hiệu ứng vật lý được thực hiện khi áp dụng một từ trường vuông góc lên một bản làm bằng kim loại hay chất bán dẫn hay chất dẫn điện nói chung (thanh Hall) đang có dòng điện chạy qua Lúc đó người ta nhận được hiệu điện thế (hiệu thế Hall) sinh ra tại hai mặt đối diện của thanh Hall Tỷ số giữa hiệu thế Hall và dòng điện chạy qua thanh Hall gọi là điện trở Hall, đặc trưng cho vật liệu làm nên thanh Hall Hiệu ứng này được khám phá bởi Edwin Herbert Hall vào năm 1879
Công thức liên hệ giữa hiệu thế Hall, dòng điện và từ trường là:
Với V H là hiệu thế Hall, I là cường độ dòng điện, B là cường độ từ trường, d là độ dày của thanh Hall, e là điện tích của hạt mang điện chuyển động trong thanh Hall, và n mật độ các hạt này trong thanh Hall
1.2 Sơ đồ chân và các thông số kĩ thuật
Thời gian chuyển đổi ngắn: 5às
Điện trở dây dẫn trong là 1.2mΩ
Nguồn vận hành đơn là 5V
Độ nhạy đầu ra cao từ 63-190mV/A
Điện áp cách ly tối đa: 2100V(RMS)
Tín hiệu Analog đầu ra có độ nhiễu thấp
Dễ dàng kết nối với các vi điều khiển
1.3 Cách sử dụng a Đo dòng điện DC
Khi đo DC phải mắc tải nối tiếp Ip+ và Ip- đúng chiều, dòng điện đi từ Ip+ đến Ip- để Vout ra mức điện thế 2.5 - 5V tương ứng dòng 0 - 5A, nếu mắc ngược Vout sẽ ra điện thế 2.5V đến 0V tương ứng với 0A đến -5A
Cấp nguồn 5v cho module khi chưa có dòng Ip (chưa có tải mắc nối tiếp với domino), thì Vout=2.5v Khi dòng Ip( dòng của tải) bằng 5A thì Vout=5v, Vout sẽ tuyến tính với dòng Ip , trong khoản 2.5V đến 5V tương ứng với dòng 0 đến 5A b Đo dòng điện AC
Khi đo dòng điện AC, do dòng điện AC không có chiều nên không cần quan tâm chiều
Cấp nguồn 5v cho module khi chưa có dòng Ip (chưa có tải mắc nối tiếp với domino) , thì Vout=2.5v khi có dòng xoay chiều Ip(dòng AC) do dòng xoay chiều độ lớn thay đổi liên tục theo hàm sin, nên điện thế Vout sẽ là điện thế xoay chiều hình sin có độ lớn tuyến tính với dòng điện AC , 0 đến 5V(thế xoay chiều xoay chiều) tương ứng với -5A đến 5A (dòng xoay chiều)
2 Modul thời gian thực DS1307
IC thời gian thực (RTC) DS1307 có chức năng cung cấp thông tin thời gian hiện tại (thời gian thực): giờ, phút, giây, thứ, ngày tháng, năm một cách chính xác ngay cả khi thiết bị đã bị tắt (ngắt điện ngoài) Giao tiếp với vi điều khiển thông qua chuẩn I2C, và đóng vai trò là slave khi kết nối đến bus I2C này Có thể đếm thời gian theo định dạng 24 giờ hoặc 12 giờ với chỉ thị AM/PM Ngoài ra bên trong chíp có bộ dò phát hiện mất nguồn và tự động chuyển sang sử dụng nguồn pin dự phòng Một số tính năng nổi bật của IC RTC DS1307 được đề cập dưới đây
Lưu trữ và cung cấp các thông tin thời gian thực: ngày, tháng, năm, giờ, phút, giây,…
Khả năng thiết lập ngày đến năm 2100
Tiêu thụ điện năng thấp: dòng tiêu thụ dưới 500nA khi hoạt động bằng pin
Tự động chuyển sang nguồn pin trong trường hợp mất điện
Đồng hồ 24 giờ hoặc 12 giờ với chỉ báo AM/PM
Sử dụng chuẩn giao tiếp I2C
RTC DS1307 có sẵn dưới dạng module, bao gồm tất cả các thành phần cần thiết như pin, đầu nối, điện trở kéo lên và tinh thể thạch anh
2.2 Sơ đồ chân và các thông số kĩ thuật:
1 X1 Đây là các chân kết nối với thạch anh tần số 32.768 KHz để kích hoạt bộ dao động nội
3 V BAT Chân này được kết với cực dương pin Lithium 3V để cấp nguồn nuôi dự phòng
5 SDA Chân dữ liệu nối tiếp (Serial Data) Đây là chân dữ liệu vào/ra của giao thức I2C Chân này cần đưa lên nguồn 5V thông qua điện trở 10kΩ
6 SCL Chân đầu vào xung đồng hồ nối tiếp (Serial Clock) Đây là chân ngõ vào xung nhịp của giao thức I2C Chân này cũng phải được kéo đến 5V thông qua một điện trở 10kΩ
7 SQW/OUT Ngõ xuất ra xung vuông, tần số có thể lập trình để thay đổi từ
1Hz, 4Khz, 8Khz, 32Khz Nếu không được sử dụng, chân này có thể được thả nổi
Chân cấp nguồn chính, khoảng 5VDC Nếu V CC không có mà
V BAT có thì DS1307 vẫn hoạt động bình thường nhưng không ghi và đọc được dữ liệu
IC chính: RTC DS1307 + EEPROM AT24C32
Lưu trữ và cung cấp các thông tin thời gian thực: ngày, tháng, năm, giờ, phút, giây,
Có pin backup duy trì thời gian trong trường hợp không cấp nguồn
Có ngõ ra tần số 1Hz
Khối hiển thị LCD 2x16 (2 dòng, 16 cột)
Chức năng của từng chân LCD 1602:
- Chân số 1 - VSS : chân nối đất cho LCD được nối với GND của mạch điều khiển
- Chân số 2 - VDD : chân cấp nguồn cho LCD, được nối với VCC=5V của mạch điều khiển
- Chân số 3 - VEE : điều chỉnh độ tương phản của LCD, sử dụng một biến trở 10K
- Chân số 4 - RS : chân chọn thanh ghi, được nối với logic "0" hoặc logic "1": + Logic “0”: Bus DB0 - DB7 sẽ nối với thanh ghi lệnh IR của LCD (ở chế độ
“ghi” - write) hoặc nối với bộ đếm địa chỉ của LCD (ở chế độ “đọc” - read)
+ Logic “1”: Bus DB0 - DB7 sẽ nối với thanh ghi dữ liệu DR bên trong LCD
- Chân số 5 - R/W : chân chọn chế độ đọc/ghi (Read/Write), được nối với logic “0” để ghi hoặc nối với logic “1” đọc
- Chân số 6 - E : chân cho phép (Enable) Sau khi các tín hiệu được đặt lên bus DB0-DB7, các lệnh chỉ được chấp nhận khi có 1 xung cho phép của chân này như sau:
+ Ở chế độ ghi: Dữ liệu ở bus sẽ được LCD chuyển vào thanh ghi bên trong khi phát hiện một xung (high-to-low transition) của tín hiệu chân E
+ Ở chế độ đọc: Dữ liệu sẽ được LCD xuất ra DB0-DB7 khi phát hiện cạnh lên (low-to-high transition) ở chân E và được LCD giữ ở bus đến khi nào chân E xuống mức thấp
- Chân số 7 đến 14 - D0 đến D7: 8 đường của bus dữ liệu dùng để trao đổi thông tin với MCU Có 2 chế độ sử dụng 8 đường bus này là: Chế độ 8 bit (dữ liệu được truyền trên cả 8 đường, với bit MSB là bit DB7) và Chế độ 4 bit (dữ liệu được truyền trên 4 đường từ DB4 tới DB7, bit MSB là DB7)
- Chân số 15 - A : nguồn dương cho đèn nền
- Chân số 16 - K : nguồn âm cho đèn nền
Chỉ dùng LCD để hiển thị (Write) nên chân RW được nối mass.Các ngoại vi của STM32 cần sử dụng.
Các ngoại vi của STM32
ADC – Analog to digital Converter là bộ chuyển đổi tín hiệu tương tự sang tín hiệu số.Đây là một phần rất quan trọng trong các vi điều khiển – hệ thống nhúng ADC được ứng dụng rất nhiều như đo nhiệt độ, đọc giá trị điện áp, cường độ dòng
10 điện, đọc phím nhấn, đọc giá trị biến trở, bảo vệ động cơ… Khi tìm hiểu về ADC chúng ta cần tìm hiểu bộ ADC đó là bao nhiêu bit, các phương pháp chuyển đổi ADC có số bit càng cao tức là độ phân giải của bộ ADC càng lớn
Có 2 tham số quan trọng của bộ ADC cần lưu ý:
Tốc độ lấy mẫu (sampling) được tính theo số chu kì chuyển đổi dùng để chỉ thời gian giữa 2 lần số hóa của bộ chuyển đổi.
Độ phân giải: dùng để chỉ số bit cần thiết để chứa hết các mức giá trị số (digital) sau quá trình chuyển đổi ở ngõ ra, tính theo Bit bộ ADC có độ phân giải 10 Bit sẽ có 2^10 = 1024 giá trị
ADC trong STM32F103 là bộ ADC có 12 bit tức là giá trị đọc về nằm trong khoảng 0 ->2^12= 4096 Giá trị điện áp đầu vào bộ ADC được cung cấp trên chân VDDA và thường lấy bằng giá trị cấp nguồn cho vi điều khiển VDD(+3V3)
STM32F103C8 có 2 kênh ADC đó là ADC1 và ADC2, mỗi kênh có tối đa là 9 channel với nhiều mode hoạt động như: single, continuous,scan hoặc discontinuous Kết quả chuyển đổi được lưu trữ trong thanh ghi 16 bit
Một số tính năng của ADC trong STM32:
Độ phân giải 12 bit tương ứng với giá trị maximum là 4095
Có các ngắt hỗ trợ như End conversion, End of Injected Conversion and Analog Watchdog Event
Single mode hay Continuous mode
Có cơ chế cân chỉnh tay
Có thể kích hoạt bằng xung bên ngoài
Tự động calib và có thể điều khiển hoạt động ADC bằng xung Trigger
Thời gian chuyển đổi nhanh : 1us tại tần số 65Mhz và có thể được cài đặt
Điện áp cung cấp cho bộ ADC là 2.4V -> 3.6V Nên điện áp Input của thiết bị có ADC 2.4V ≤ VIN ≤ 3.6V
Có bộ DMA giúp tăng tốc độ xử lí
Sơ đồ khối của bộ ADC trong STM32F103:
Cơ chế để tạo ADC như sau:
1 Enable bộ clock cho ADC, ghi hệ số chia cho ADC prescaler
2 Chọn các kênh cần chuyển đổi
3 Chọn chế độ chuyển đổi Sinlge, Continuous, Scan, Discontinuous
4 Chọn thời gian lấy mẫu (Sampling Time)
7 Kiểm tra cờ EOC hoặc trong ngắt đọc dữ liệu từ thanh ghi DR về 1.3 Một số thanh ghi quan trọng
ADC_DR – ADC regular data register
Thanh ghi này chứa giá trị ADC đọc về, nó là thanh ghi 32 bit với 16 bit data của bộ ADC1 và 16 bit data của bộ ADC2
ADC_SR – ADC status register
Thanh ghi này chứa các cờ báo trạng thái như:
STRT : báo channel đã bắt đầu chuyển đổi giá trị ADC hay chưa
JSTRT : báo channel đã bắt đầu chuyển đổi khi có tín hiệu bên ngoài điều khiển hay chưa
JEOC: báo kết thúc quá trình chuyển đổi khi có tín hiệu bên ngoài điều khiển hay chưa
EOC: báo kết thúc quá trình chuyển đổi ADC
AWD: báo có sự kiện Analog Watchdog có xảy ra hay không
ADC_CR2 – ADC Control register 2
Thanh ghi này điều khiển các quá trình chuyển đổi ADC như:
TSVREFE: bật hay tắt cảm biến nhiệt độ và Vrefint
SWSTART : bật hay reset trạng thái bộ chuyển đổi liên tục
JSWSTART: bật hay reset trạng thái bộ chuyển đổi liên tục được điều khiển từ bên ngoài bộ ADC
EXTTRIG: cho phép hay không cho phép bắt đầu bộ chuyển đổi liên tục từ xung trigger bên ngoài
EXTSEL[2:0] : bit chọn lựa xung trigger bên ngoài từ nguồn nào
ALIGN : sắp xếp thanh ghi data theo chiều từ lớn đến bé hoặc ngược lại
DMA: có sử dụng bộ DMA hay không
RSTCAL: reset lại thanh ghi calib hay không
CAL: cho phép hay báo là đã calib xong
CONT: lựa chọn mode chuyển đổi liên tục hay chuyển đổi đơn
ADON: bật hay tắt bộ chuyển đổi ADC
ADC_SMPR2 – ADC sample time register
Thanh ghi này thiết lập thời gian lấy mẫu nhanh hay chậm và được cài đặt bởi lập trình.SMPx[2:0] tương ứng giá trị nhị phân từ 0->7 sẽ tương ứng với thời gian lấy mầu là: 1.5 - 7.5 - 13.5 - 28.5 - 41.5 - 55.5 - 71.5 - 239.5 cycles Cách tính thời gian dựa theo hình sau:
2.1 Cơ sở lý thuyết a Giới thiệu
I2C là một giao thức giao tiếp được phát triển bởi Philips Semiconductors để truyền dữ liệu giữa một bộ xử lý trung tâm với nhiều IC trên cùng một board mạch chỉ sử dụng hai đường truyền tín hiệu.
Do tính đơn giản của nó nên loại giao thức này được sử dụng rộng rãi cho giao tiếp giữa vi điều khiển và mảng cảm biến.Đây là một loại giao thức giao tiếp nối tiếp đồng bộ Nó có nghĩa là các bit dữ liệu được truyền từng bit một theo các khoảng thời gian đều đặn được thiết lập bởi một tín hiệu đồng hồ tham chiếu Đặc điểm:
Thường sử dụng onboard với đường truyền ngắn
Nối được nhiều thiết bị trên cùng một bus
Giao tiếp đồng bộ, sử dụng Clock từ master
Sử dụng 7 bit hoặc 10 bit địa chỉ
Chỉ sử dụng 2 chân tín hiệu SDA, SCL
Có 2 tốc độ tiêu chuẩn là Standard mode (100 kb/s)và Low mode (10 kbit/s) b Kết nối vật lý
Giống như giao tiếp UART, I2C chỉ sử dụng hai dây để truyền dữ liệu giữa các thiết bị:
SDA (Serial Data) - đường truyền cho master và slave để gửi và nhận dữ liệu
SCL (Serial Clock) - đường mang tín hiệu xung nhịp
I2C là một giao thức truyền thông nối tiếp, vì vậy dữ liệu được truyền từng bit dọc theo một đường duy nhất (đường SDA), các bit được đồng bộ hóa với việc lấy mẫu các bit bởi một tín hiệu xung nhịp được chia sẻ giữa master và slave Tín hiệu xung nhịp luôn được điều khiển bởi master
Mỗi Bus I2C sẽ có 3 chế độ chính:
Một Master, một Slave c Cách thức truyền dữ liệu
Dữ liệu được truyền đi trên dây SDA được thực hiện như sau:
Master thực hiện điều kiện bắt đầu I2C (Start Condition)
Gửi địa chỉ 7 bit + 1bit Đọc/Ghi (R/W) để giao tiếp muốn đọc hoặc ghi dữ liệu tại Slave có địa chỉ trên
Nhận phải hồi từ Bus, nếu có một bit ACK (Kéo SDA xuống thấp) Master sẽ gửi dữ liệu
Nếu là đọc dữ liệu R/W bit = 1, chân SDA của master sẽ là input, đọc dữ liệu từ Slave gửi về Nếu là ghi dữ liệu R/W = 0, chân SDA sẽ là output ghi dữ liệu vào Slave
Truyền điều khiện kết thúc (Stop Condition)
Mỗi lần giao tiếp có cấu trúc khung truyền như sau:
STM32F4 có 2 bộ chuyển đổi I2C với tốc độ tối đa lên đến 400Kh ở mode Fm và 100khz ở mode sm Các bộ I2C còn được hỗ trợ chức năng DMA giúp đẩy nhanh tốc độ giao tiếp với ngoại vi Một số tính năng được tóm tắt như sau:
Có thể lập trình là Master hay Slave
Đối với Master: tạo ra xung clock và tạo ra tín hiệu start, stop
Đối với Slave : lập trình được địa chỉ của thiết bị I2C, chế độ kiểm tra bit stop
Số địa chỉ được sinh ra cũng như được kiểm tra là 7 bit hoặc 10 bit
Hỗ trợ 2 chuẩn tốc độ là 100khz và 400 Khz
Có bộ lọc nhiễu Analog
Có các cờ báo trạng thái : nhận, truyền, kết thúc chuyển đổi, báo lỗi…
Có các ngắt như: ngắt buffer truyền, nhận; ngắt sự kiện, ngắt báo lỗi
Quá trình truyền data tùy thuộc vào mode cấu hình của I2C là master hoặc là slave, ở chế độ 10 bit địa chỉ hay 7 bit địa chỉ, truyền theo cách 1 hay cách 2 Dưới đây là ví dụ về cấu hình I2C ở mode master, truyền 7 bit địa chỉ và truyền theo cách 1:
2.3 Một số thanh ghi quan trọng
ACK : cho phép nhận hoặc không nhận tín hiệu ACK return từ thiết bị được truyền
STOP : sinh ra tín hiệu stop kết thúc quá trình giao tiếp
START : sinh ra tín hiệu start để bắt đầu quá trình giao tiếp
PE: peripheral enable - bit này được bật lên bằng 1 khi quá trình giao tiếp I2C đang được thực hiện và kết thúc khi có tín hiện end communication
ITBUFEN : cho phép hoặc không cho phép xảy ra ngắt khi có data trong truyền/nhận
ITEVTEN : cho phép ngắt khi xảy ra các sự kiện sau trên các bit sau: SB, ADDR, ADD10, STOPF, BTF , TxE, RxE
ITERREN : cho phép hoặc không cho phép xảy ra ngắt khi có lỗi xảy ra
FREQ[5:0] : bộ chia clock tần số được tính từ nhánh clock hệ thống chia cho bộ I2C
ADDMODE : cài đặt số bit địa chỉ của slave là 7 hay 10 bit
ADD[9:8] : chỉ sử dụng khi mode địa chỉ là 10 bit
ADD[7:1] : bit địa chỉ của thiết bị slave
ADD0 : chỉ sử dụng khi mode địa chỉ là 10 bit
Thanh ghi này gồm 8 bit, chứa data của quá trình truyền hoặc nhận
Thanh ghi này chứa các cờ báo trạng thái của quá trình giao tiếp I2C:
TIME OUT: báo hết thời gian đợi quá trình truyền nhận data
PECERR: chấp nhận lỗi PCE và phản hồi lại quá trình tín hiệu lỗi
OVR : báo quá trình overrun/ underrun
AF: báo tín hiệu ACK bị lỗi hay không
TxE : báo buffer truyền có trống hay không
RxE : báo buffer nhận có trống hay không
STOPF : cờ báo có kiểm tra quá trình stop hay không
BTF: báo truyền byte dữ liệu đã xong hay chưa
ADDR: báo địa chỉ đã được gửi(mode master) hay không tương thích (mode slave)
SB: Có sử dụng bit start hay không
F/S : sử dụng mode Fast(400khz) hay slow(100Khz)
DUTY: chỉ sử dụng cho mode fast với 2 chế độ
CCR[11:0] : thanh ghi chứa clock control cho bộ , công thức chia tham khảo thêm trong reference manual
UART hay bộ thu-phát không đồng bộ đa năng là một trong những hình thức giao tiếp kỹ thuật số giữa thiết bị với thiết bị đơn giản và lâu đời nhất Bạn có thể tìm thấy các thiết bị UART trong một phần của mạch tích hợp (IC) hoặc dưới dạng các thành phần riêng lẻ Các UART giao tiếp giữa hai nút riêng biệt bằng cách sử dụng một cặp dẫn và một nối đất chung
UART tiếng anh là Universal Asynchronous Reciver/Transmister một chuẩn giao tiếp không đồng bộ cho MCU và các thiết bị ngoại vi
Chuẩn UART là chuẩn giao tiếp điểm và điểm, nghĩa là trong mạng chỉ có hai thiết bị đóng vai trò là transmister hoặc reciver
Cách hoạt động của giao thức UART
UART là giao thức truyền thông không đồng bộ, nghĩa là không có xung Clock, các thiết bị có thể hiểu được nhau nếu các Setting giống nhau
UART là truyền thông song công(Full duplex) nghĩa là tại một thời điểm có thể truyền và nhận đồng thời Định dạng gói tin như sau:
Start – Bit: Để bắt đầu truyền dữ liệu, truyền UART kéo đường dữ liệu từ mức điện áp cao (1) xuống mức điện áp thấp (0)
Stop – Bit: Bit dừng được đặt ở phần cuối của gói dữ liệu Thông thường, bit này dài 2 bit nhưng thường chỉ sử dụng 1 bit Để dừng sóng, UART giữ đường dữ liệu ở mức điện áp cao
Partity Bit: Bit chẵn lẻ cho phép người nhận đảm bảo liệu dữ liệu được thu thập có đúng hay không Trên thực tế, bit này không được sử dụng rộng rãi nên không bắt buộc
Lưu đồ thuật toán giao tiếp giữa STM32 và module phần cứng
STM32 giao tiếp với Modul DS-1307
STM 32 giao tiếp với ACS-712
STM32 giao tiếp với LCD
Thiết kế phần mềm
Phân tích xử lý đảm bảo tính thời gian thực
Để đảm bảo tính thời gian thực của mỗi Task, các Task cần đảm bảo thời gian thực thi trong một giới hạn nhất định
Căn cứ vào thông số của các Modun phần cứng và yêu cầu về tính chất của phép đo, nhóm đã lựa chọn các thông số về chu kì, deadline cho các Task như sau:
Task 1: (Đo đòng điện ACS712 + hiển thị lên LCD) Việc đo dòng điện và xử lý tín hiệu ADC mất nhiều thời gian hơn nên chọn chu kì 𝑇 2 có thời gian lớn hơn
Task 2: (Đo thời gian thực DS1307 + Hiển thị LCD) Việc đo thời gian thực cần được thực hiện liên tục nên chọn chu kì T ngắn
Task 3: (Truyền tin UART) Chu kì truyền tin được xác định thỏa mãn điều kiện là dữ liệu của 2 Task còn lại đã được xử lý và gửi đến Task3 và thời gian không cần thiết phải quá nhỏ
Task 4: Xử lý dữ liệu ngắt khi cài đặt bộ lập lịch mới
T là chu kì thực hiện một task
C là thời gian thực thi chương trình của từng task
D là deadline muộn nhất để thực hiện 1 task
Các thông số có đơn vị là mili giây (ms).
Thiết kế bộ lập lịch
Dựa vào các thông số của các Task như trên, nhóm chúng em đã tính toán và thiết kế bộ lập lịch như sau:
P là bội số của f vàP là BCNN của các T của các task => Tính được P = 200
Các task bắt đầu và kết thúc trong 1 frame: f≥ Ci với mọi task i
Giữa thời gian bắt đầu và deadline của mỗi task ít nhất là 1 frame:
2f – ƯCLN(Ti,f) ≤Di với mọi task i
Mỗi task thực hiện nhiều nhất là trong 1 frame f: F≤Ti với mọi task i
Phân tích lập trình đa nhiệm
Tạo các Task và cài đặt mức ưu tiên cho từng Task:
/* USER CODE BEGIN RTOS_THREADS */ xTaskCreate(DS1307Task, "Task1", 526, NULL,2, &DS1307Handle); xTaskCreate(ADCTask, "Task2", 128, NULL, 3, &ADCHandle); xTaskCreate(DisplayTask, "Task3", 526, NULL, 1, &DisplayHandle);l
/* USER CODE END RTOS_THREADS */
Trong đó Task 1 (ADC) có mức ưu tiên cao nhất, sau đó là Task2 (ADC) và cuối cùng là Task3 (UART)
Nhiệm vụ: đọc dữ liệu từ Modul thời gian thực rồi hiển thị lên LCD Dữ liệu được đưa vào hàng đợi (Task3) để truyền UART lên máy tính void DS1307Task(void*Param)
{ osMutexWait(myMutex01Handle, osWaitForever); time = DS1307_GetTime(&ds1307); sprintf (ptr, "%02d:%02d:%02d",time.hour,time.minute,time.second); lcd_put_cur(0, 0); lcd_send_string (ptr); sprintf (ptr, "%02d-%02d-%04d",time.date,time.month,time.year); lcd_put_cur(1, 0); lcd_send_string (ptr); osMutexRelease(myMutex01Handle); osDelay(10);
Nhiệm vụ: Nhận dữ liệu từ cảm biến đo dòng, xử lý tín hiệu ADC và hiển thị kết quả lên LCD Dữ liệu được đưa vào hàng đợi (Task3) để truyền UART lên máy tính void ADCTask(void* Param)
{ uint32_t ADC_data = 356 ; uint32_t var =0; float amlpe ; char ptr[5]; while(1)
HAL_ADC_Start(&hadc1); var = HAL_ADC_GetValue(&hadc1); amlpe = (0.012*var - 25); sprintf (ptr, "%10d mA",var); lcd_put_cur(0, 9); lcd_send_string (ptr); xQueueSend(DataADCqueneHandle, &ADC_data, portMAX_DELAY);
HAL_ADC_Stop(&hadc1); osMutexRelease(myMutex01Handle); osDelay(20);
Nhiệm vụ: Truyền dữ liệu từ hàng đợi lên máy tính thông qua UART void DisplayTask(void* Param)
DS1307_TIME* data_time ; uint32_t adc_data = 0;; while(1)
{ data_time = &time ; xQueueReceive(DataDS1307queneHandle, &data_time, portMAX_DELAY); xQueueReceive(DataADCqueneHandle, &adc_data, portMAX_DELAY); printf("\r\nThoi gian hien tai : %d:%d:%d | %d/%d/%d\r",data_time-
>hour,data_time->minute,data_time->second,data_time->date,data_time->month,data_time-
>year); printf("\n Dong dien tieu thu la %d\n",adc_data) ; osDelay(200);
Nhiện vụ: Xử lý dữ liệu ngắt khi cài đặt bộ lập lịch mới
Lập trình cơ chế Mutex:
Do Task1, Task2 cùng sử dụng chung 1 đường bus I2C để giao tiếp với STM32 và để các Task này được thực thi không bị gián đoạn thì ta sử dụng cơ chế Mutex để chiếm quyền cho các Task đó osMutexDef(myMutex01); myMutex01Handle = osMutexCreate(osMutex(myMutex01));
Lập trình hàng đợi Queue:
Task3 (UART) được sử dụng để truyền tin lên máy tính gồm dữ liệu đo từ Task1 và Task2 nên ta sử dụng cơ chế hàng đợi để truyền tin nhằm tránh xung đột đường truyền do chỉ có 1 cổng UART
* USER CODE BEGIN RTOS_QUEUES */
DataDS1307queneHandle = xQueueCreate(2,sizeof(DS1307_TIME));
/* USER CODE END RTOS_QUEUES */
Trong quá trình hoạt động sẽ xuất hiện các khoảng thời gian mà STM32 không thực hiện bất kì Task nào Vì vậy, nhóm em lập trình cho vi điều khiển vào chế độ ngủ để tiếc kiệm năng lượng trong những khoảng thời gian đó
Kết quả và đánh giá
Các kết quả đạt được
Kết quả của bộ lập lịch
Sử dụng phần mềm SEGGER để theo dõi hoạt động các Task
Quá trình hoạt động của các Task
ADCTask với mức ưu tiên cao nhất nên được thực thi trước
Tiếp theo lần lượt là DS1307 và DisplayTask
Quá trình hoạt động Mutex
ADCTask và DS1307Task đều dùng chung bus I2C Trong quá trình hoạt động của DS1307Task, ADCTask đến chu kì hoạt động nhưng nhờ có Mutex, ADCTask dù có mức ưu tiên cao hơn nhưng không ngắt được DS1307Task Do đó, DS1307Task được hoạt động liền mạch
Dòng điện tiêu thụ trong các trạng thái:
Chế độ hoạt động bình thường Chế độ Sleep
Phân tích và đánh giá kết quả
Các kết quả đạt được về cơ bản đã thực hiện được với mục tiêu đề ra:
Các module hoạt động ổn định, giao tiếp tương đối tốt với STM32
Về phần đa nhiệm, các Task hoạt động với khá ổn định với thời gian mà bộ lập lịch đã đặt ra
Cơ chế Mutex và hàng đợi Queue đã thực hiện tốt vai trò đối với hoạt động của cả chương trình
Chế độ Sleep đã hoạt động tốt Dòng tiêu thụ có giảm so với chế độ hoạt động bình thường