Báo cáo Đồ án Mẫu Đọc nhiệt độ hiển thị lên LCD

M ỤC L ỤC Lời nói đầu Lời cảm ơn Nhận xét của giáo viên hướng dẫn Trang 4 Chương 1 - Chương dẫn nhập Trang 6 Chương 2 - Giới thiệu các linh kiện Trang 7 Chương 3 – Tập lệnh chương trinh Trang 58 Chương 4 – Thiết kế và thi công mạch Trang 83 Chương 5 – Kết quả thực hiện đề tài Trang 91 Tài liệu tham khảo Trang 91

doc86 trang | Chia sẻ: lvcdongnoi | Lượt xem: 2474 | Lượt tải: 2download
Bạn đang xem trước 20 trang tài liệu Báo cáo Đồ án Mẫu Đọc nhiệt độ hiển thị lên LCD, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
caler không có tác dụng hoặc tỉ lệ 1 :1). Nếu thanh ghi TMR0 được ghi một giá trị mới, giá trị trong thanh ghi này sẽ không tăng trong 2 chu kỳ lệnh kế tiếp.Vì vậy để khắc phục hiện tượng này chúng ta có thể hiệu chỉnh giá trị nhập vào thanh ghi TMR0. Chế độ đếm được lựa chọn bằng cách set bit T0CS (OPTION_REG ). Trong chế độ đếm, thanh ghi TMR0 sẽ tăng lên khi có cạnh lên hoặc cạnh xuống xuất hiện trên chân T0CKL (cạnh lên hoặc cạnh xuống được lựa chọn bởi bit T0SE (OPTION_REG, xóa bit T0SE sẽ lựa chọn cạnh lên). Ngắt Timer 0 Ngắt Timer 0 được tạo ra khi thanh ghi TMR0 tràn từ 0FFh đến 00h. Khi xảy ra tràn, cờ T0IF(INTCON) được bật lên. Ngắt có thể được ngăn chặn bằng cách xóa bit T0IE (INTCON). Cờ ngắt T0IF phải được xóa bằng phần mềm truớc khi thoát khỏi chương trình ngắt trở về chương trình chính. Lưu ý : Ngắt Timer 0 không làm Vi Điều Khiển thoát khỏi trạng thái ngủ. Sử dụng Timer 0 với nguồn xung Clock bên ngoài Khi bộ tiền định tỉ lệ không được sử dụng, ngõ vào xung clock ngoại cũng giống như ngõ ra bộ tiền định tỉ lệ. Nguồn xung clock ngoại sẽ được đồng bộ với xung clock nội bằng cách: nó sẽ được lấy mẫu tại chu kỳ Q2 và Q4 của xung clock nội. Do đó,T0CKI phải ở mức cao ít nhất 2 Tosc và ở mức thấp ít nhất cũng là 2 Tosc. Bộ tiền định tỉ lệ 8 bit của Timer 0 Bộ đếm 8 bit được sử dụng như bộ tiền định tỉ lệ cho Timer 0 hoặc bộ hậu định tỉ lệ cho WDT. Bit PSA (OPTION_REG) sẽ lựa chọn bộ đếm này sẽ sử dụng cho Timer0 hay WDT, các bit PS2, PS1, PS0 sẽ xác định tỉ lệ của bộ đếm. Các thanh ghi điều khiển liên quan đến Timer 0 TMR0 (địa chỉ 01h, 101h) : chứa giá tri đếm Timer0. INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép ngắt hoạt động (GIE và PEIE). OPTION_REG (địa chỉ 81h, 181h): điều khiển prescaler. 2.1.4.2) Bộ định thời Timer 1: Timer1 là một bộ định thời 16 bit bao gồm hai thanh ghi 8 bit (TMR1H và TMR1L), có khả năng đọc được và ghi được. Cặp thanh ghi TMR1H và TMR1L sẽ tăng từ 0000h lên FFFFh rồi sau đó tràn về 0000h. Nếu được cho phép (bit TMR1IE được set), ngắt sẽ xảy ra khi giá trị TMR1 tràn từ FFFFh về 0000h, lúc đó cờ ngắt TMR1IF sẽ bật lên. Thanh ghi điều khiển Timer 1 Hình 2.22 T1CON Register Bit 7,6 Không sử dụng, đọc là 0. Bit 5,4 T1CKPS1 : T1CKPS0 : Các bit chọn tỉ lệ xung ngõ vào cho Timer1. 11 1 : 8 10 1 : 4 01 1 : 2 00 1 : 1 Bit 3 T10SCEN : Bit cho phép bộ dao động Timer 1 Oscillator 1 : Cho phép dao động 0 : Không cho phép dao động Bit 2 T1SYNC : Bit lựa chọn đồng bộ hóa xung clock ngoài của Timer 1 (Chú ý: Bit này chỉ có tác dụng khi bit TMR1CS = 1) 1: Không đồng bộ hóa xung clock ngoại 0: Đồng bộ hóa xung clock ngoại. Bit 1 TMR1CS : Bit chọn nguồn xung clock cho Timer 1 1: Chọn xung clock ngoài qua chân T1OSC/T1CKI ( tác động cạnh lên) 0: Chọn xung clock nội (Fosc/4) Bit 0 TMR1ON: Bit cho phép ngoặc ngưng Timer 1 1: Cho phép 0: Không cho phép. Chế độ định thời trong hoạt động cuả Timer 1 Chế độ định thời được lựa chọn bằng cách xóa bit TMR1CS (T1CON). Trong chế độ này, xung clock cung cấp cho Timer 1 là Fosc/4, bit đồng bộ T1SYNC (T1CON) không có tác dụng vì xung clock nội đã luôn luôn được đồng bộ. Chế độ đếm Timer 1 có thể hoạt động ở cả chế độ đồng bộ hoặc bất đồng bộ tùy thuộc vào việc cài đặt bit TMR1CS (T1CON). - Đếm Đồng Bộ Chế độ này được lựa chọn bằng cách set bit TMR1CS và xóa bit T1SYNC. Trong chế độ này giá trị của Timer 1 sẽ tăng khi có xung cạnh lên trên chân T1OSI/RC1 ( nếu bit T1OSCEN được set) hoặc chên trân T1OSO (nếu bit T1OSCEN được xóa). Xung clock ngoại sẽ được đồng bộ với xung clock nội, hoạt động đồng bộ được thực hiện ngay sau bộ tiền định tỉ lệ xung (prescaler). Trong chế độ ngủ hoạt động đồng bộ sẽ bị tắt cho dù có xung clock ngoài thì Timer 1 cũng không tăng. Điều này có nghĩa là chế độ đếm đồng bộ sẽ không hoạt động được trong chế độ ngủ (SLEEP). Khi chế độ sử dụng xung clock ngoài được lựa chọn cho Timer 1 ở chế độ đếm đồng bộ, chúng ta phải đảm bảo xung clock ngoài đã được đồng bộ với xung clock nội. - Đếm bất đồng bộ : Nếu bit T1SYNC được set, xung clock ngoài sẽ không được đồng bộ hóa. Bộ định thời sẽ tiếp tục đếm trong suốt quá trình Sleep của VĐK và có khả năng tạo ra một ngắt khi bộ định thời tràn và làm VĐK thoát khỏi trạng thái ngủ. * Một số đặc điềm lưu ý khi đọc ghi vào Timer : Việc đọc thanh ghi TMR1H hoặc TMR1L trong khi bộ định thời đang chạy từ một nguồn xung clock ngoài không đồng bộ sẽ cho giá trị tức thời (không phải ngưng Timer lại). Tuy nhiên, phải chú ý rằng việc đọc Timer 1 sẽ phải bao gồm 2 lần đọc giá trị 8 bit, do đó có thể phát sinh vấn đề là Timer có thể bị tràn giữa 2 lần đọc. Để ghi vào Timer tốt nhất chúng ta nên dừng Timer lại và ghi giá trị chúng ta mong muốn. Chúng ta có thể ghi giá trị váo khi Timer đang chạy nhưng việc đó có thể tạo ra một giá trị không như ta mong muốn. Dao động riêng của Timer 1 Chúng ta có thể tạo một bộ dao động độc lập cho Timer 1 bằng cách sử dụng thạch anh có tần số tối đa 200Khz. Với bộ dao động này Timer có thể đếm ngay cả khi VĐK rơi vào trạng thái ngủ. Ngắt Timer 1 Khi ngắt được cho phép, nó sẽ xảy ra khi Timer tràn từ giá trị FFFFh xuống 0000h. Khi xảy ra tràn, cờ báo ngắt TMR1IF sẽ bật lên. Ngắt có thể ngăn chặn bằng cách xóa bit TMR1IE, cờ TMR1IF phải được xóa bằng phần mềm trước khi thoát khỏi chương trình phục vụ ngắt trở về chương trình chính. Lưu ý : Ngắt của Timer 1 ở chế độ định thời và chế độ đếm đồng bộ không làm cho VĐK thoát khỏi trạng thái ngủ, chỉ có ngắt ở chế độ đếm bất đồng bộ mới làm cho VĐK thoát khỏi trạng thái ngủ. Các thanh ghi liên quan đến Timer 1 INTCON (ñòa chæ 0Bh, 8Bh, 10Bh, 18Bh): cho pheùp ngaét hoaït ñoäng (GIE vaø PEIE). PIR1 (địa chỉ 0Ch): chứa cờ ngắt Timer1 (TMR1IF). PIE1(địa chỉ 8Ch): cho phép ngắt Timer1 (TMR1IE). MR1L (địa chỉ 0Eh): chứa 8bit thấp vào bộ Timer1. TMR1H (địa chỉ 0Eh): chứa 8bit cao vào Timer1. T1CON (địa chỉ 10h): xác lập các tham số cho Timer1. 2.1.4.3) Bộ định thời Timer 2: Timer2 là một bộ định thời 8 bit bao gồm một bộ tiền định tỉ lệ và một bộ hậu định tỉ lệ, Timer2 cung cấp thời gian hoạt động cho chế độ PWM nếu module CCP được chọn. Thanh ghi TMR2 là một thanh ghi có thể đọc và ghi được, nó bị xóa bởi bất cứ tác đông reset nào. Xung clock ngõ vào (Fosc/4) có các tùy chọn tỉ lệ là 1:1, 1:4, 1:16, được lựa chọn bằng các bit điều khiển T2CKPS1 : T2CKPS0 (T2CON). Timer 2 có một thanh ghi khoảng thời gian 8 bit PR2, đây là một thanh ghi có khả năng đọc được và ghi được. Timer 2 sẽ tăng từ 00h đến khi bằng giá trị ở thanh ghi PR2 nó sẽ reset về 00h ở chu kỳ tăng tiếp theo. Thanh ghi điều khiển Timer 2 T2CON Hình 2.24 T2CON Register Bit 7: không sử dụng Bit 6:3 TOUTPS3:TOUTPS0: Bit chọn tỉ lệ ngõ ra của Timer 2 0000: 1:1 0001: 1:2 0010: 1:3 …. 1111: 1:16 Tỷ lệ ngõ ra Bit 2 TMR2ON: Bit cho phép hoạt động của Timer 2 1: Cho phép 0: Không cho phép. Bit 1:0 T2CKPS1:T2CKPS0: Bit chọn tỉ lệ ngõ vào của Timer 2 00 : Prescaler 1 01 : Prescaler 4 1x : Prescaler 16 Xóa các bộ tỉ lệ Hai bộ đếm prescaler và postcaler sẽ bị xóa bởi một trong các nguyên nhân sau đây: - Ghi một giá trị vào thanh ghi TMR2 - Ghi một giá trị vào thanh ghi TCON2 - Bất cứ một reset thiết bị nào. Nhận xét: Timer0 và Timer2 là bộ đếm 8 bit (giá trị đếm tối đa là FFh), trong khi Timer1 là bộ đếm 16 bit (giá trị đếm tối đa là FFFFh). Timer0, Timer1 và Timer2 đều có hai chế độ hoạt động là timer và counter. Xung clock có tần số bằng ¼ tần số của oscillator. Xung tác động lên Timer0 được hỗ trợ bởi prescaler và có thể được thiết lập ở nhiều chế độ khác nhau (tần số tác động, cạnh tác động) trong khi các thông số của xung tác động lên Timer1 là cố định. Timer2 được hỗ trợ bởi hai bộ chia tần số prescaler và postcaler độc lập, tuy nhiên cạnh tác động vẫn được cố định là cạnh lên. Timer1 có quan hệ với khối CCP, trong khi Timer2 được kết nối với khối SSP. Một vài so sánh sẽ giúp ta dễ dàng lựa chọn được Timer thích hợp cho ứng dụng. 2.1.5) Module CCP: Chế độ điều chế xung PWM: Trong chế độ điều chế độ rộng xung PWM, chân CCP tạo ra một tín hiệu có độ phân giải 10 bit. Chân CCP phải được mặc định là ngõ ra. Việc xóa thanh ghi CCPxCON sẽ đẩy chân ngõ ra CCPx xuống mức mặc định thấp. Hình 2.25:PWM Output Hình 2.26: Sơ đồ khối module PWM I. Chu kỳ PWM Chu kỳ PWM được chỉ định trong thanh ghi PR2. Chu kỳ có thể được tính bằng công thức: Chu kỳ PWM = [(PR2 + 1)*4*Tosc*giá trị tỉ lệ TMR2) Tần số PWM = 1/ chu kỳ PWM. Khi giá trị trong hai thanh ghi TMR2 và PR2 bằng nhau, ba tác vụ sau đây sẽ diễn ra: - Thanh ghi TMR2 bị xóa - Chân CCPx được set lên mức 1 - Giá trị Duty cycle ( Chu kỳ nhiệm vụ) từ thanh ghi CCPRxL sẽ chuyển sang thanh ghi CCPRxH. Lưu ý: Bộ postcaler của Timer 2 không có tác dụng trong việc quyết định tần số PWM. Bộ prescaler được kết hợp với thanh ghi TMR2 để tạo ra bộ đếm 10 bit tương ứng. II. Giá trị chu kỳ nhiệm vụ PWM Giá trị chu kỳ nhiệm vụ của PWM được quy định bằng 10 bit : 8 bit trong thanh ghi CCPRxL và 2 bit trong thanh ghi CCPxCON (DCxB1, DCxB0). Chu kỳ nhiệm vụ PWM có thể được tính theo công thức sau: Ton PWM = ( Giá trị của DCxB9:DcxB0) * Tosc * giá trị tỉ lệ tiền định TMR2 Giá trị DCxB9:DcxB0 có thể thay đổi tùy ý nhưng giá trị này sẽ không được tải vào trong thanh ghi CCPRxH cho đến khi trạng thái cân bằng xảy ra giữa 2 thanh ghi PR2 và TMR2. Trong chế độ PWM thanh ghi CCPRxH là thanh ghi chỉ đọc. III Cài đặt hoạt động cho PWM Để cài đặt hoạt động cho chế độ PWM ta tiến hành các bước sau: - Định chân CCPx là ngõ ra. - Thiết lập chu kỳ PWM bằng việc ghi vào thanh ghi PR2 - Thiết lập chu kỳ nhiệm vụ PWM bằng việc ghi giá trị vào các bit DCxB9:DCxB0. - Cài đặt giá trị tỉ lệ cho Timer 2 và cho phép Timer 2 hoạt động bằng cách ghi vào thanh ghi T2CON. - Cấu hình cho module CCP hoạt động trong chế độ PWM. Hình 2.27:ví dụ về tần số PWM 2.1.6) Module ADC: 2.1.6.1) Giới thiệu Module ADC 10 bit: ADC (Analog to Digital Converter) là bộ chuyển đổi tín hiệu giữa hai dạng tương tự và số. PIC16F877A có 8 ngõ vào analog (RA4:RA0 và RE2:RE0). Hiệu điện thế chuẩn VREF có thể được lựa chọn là VDD, VSS hay hiệu điện thể chuẩn được xác lập trên hai chân RA2 và RA3. Kết quả chuyển đổi từ tín tiệu tương tự sang tín hiệu số là 10 bit số tương ứng và được lưu trong hai thanh ghi ADRESH:ADRESL. Khi không sử dụng bộ chuyển đổi ADC, các thanh ghi này có thể được sử dụng như các thanh ghi thông thường khác. Khi quá trình chuyển đổi hoàn tất, kết quả sẽ được lưu vào hai thanh ghi ADRESH:ADRESL, bit (ADCON0) được xóa về 0 và cờ ngắt ADIF được set Module ADC bao gồm 4 thanh ghi: -Thanh ghi chứa byte cao của kết quả ADRESH -Thanh ghi chứa byte thấp của kết quả ADRESL -Thanh ghi chứa các bit điều khiển ADCON0 -Thanh ghi chứa các bit điều khiển ADCON1. 2.1.6.2) Các thanh ghi điều khiển Thanh ghi điều khiển ADCON0 Hình 2.28: ADCON0 Register Bit 7:6 ADCS1:ADCS0: Các bit lựa chọn tần số chuyển đổi A/D 00 =FOSC/2 01 =FOSC/4 10 =FOSC/32 11 =FRC (xung clock được lấy từ dao đông nội RC) Bit 5:3 CHS2:CHS0: Các bit lựa chọn kênh Analog 000: Kênh 0, (AN0) 001: Kênh 1, (AN1) 010: Kênh 2, (AN2) 011: Kênh 3, (AN3) 100: Kênh 4, (AN4) 101: Kênh 5, (AN5) 110: Kênh 6, (AN6) 111: Kênh 7, (AN7) Bit 2 GO/ DONE: Bit báo trạng thái chuyển đổi A/D Khi bit ADON = 1 1: Quá trình A/D đang thực hiện (Khi chúng ta set bit này lên thì quá trình chuyển đổi sẽ xảy ra, khi quá trình kết thúc nó sẽ tự động được xóa bằng phần mềm). 0: Quá trình A/D không xảy ra hoặc đã hoàn tất. Bit 1 Không sử dụng, giá trị là 0 Bit 0 ADON : Bit cho phép module A/D hoạt động. 1: Nguồn được cung cấp cho A/D 0: Ngưng cung cấp nguồn cho A/D. Thanh ghi điều khiển ADCON1: Hình 2.29 ADCON1 Register Bit 7 ADFM: Bit lựa chọn định dạng kết quả A/D 1: Canh phải, 6 bit cao nhất của thanh ghi ADRESH có giá trị 0 0: Canh trái, 6 bit thấp nhất của thanh ghi ADRESL có giá trị 0 Bit 6 ADCS2: Bit lựa chọn clock chuyển đổi A/D Hình 2.30 lựa chọn Clock chuyển đổi ADC Bit 5,4 không sử dụng Bit 3:0 PCFG3:PCFG0: Các bit điều khiển cấu hình các chân ADC. Hình 2.31Các bit điều khiển cấu hình chân ADC 2.1.6.3) Hoạt động của Module ADC: Hai thanh ghi ADRESH và ADRESL chứa giá trị 10 bit của kết quả ADC. Khi quá trình chuyển đổi hoàn tất, kết quả ADC sẽ được lưu lại trong cặp thanh ghi này. Bit GO/DONE bị xóa và cờ ngắt ADIF được bật lên. Sau khi module ADC đã được cấu hình như mong muốn, chúng ta phải lựa chọn kênh chuyển đổi A/D trước khi chuyển đổi ADC xảy ra. Các chân Analog phải được chọn là ngõ vào bằng cách set các bit trong thanh ghi TRIS tương ứng. Để tiến hành chuyển đổi ADC, tiến hành theo các bước sau: Bước 1: Cấu hình cho module ADC: - Cấu hình cho các chân ngõ vào/ điện thế chuẩn và I/O số (ADCON1) - Lựa chọn kênh ngõ vào A/D (ADCON0) - Lựa chọn tần số chuyển đổi (ADCON0) - Cấp nguồn cho module ADC (ADCON0) Bước 2: Cấu hình các ngắt ADC (nếu cần): - Xóa cờ ngắt ADIF - Set bit GIE (Cho phép ngắt toàn cục) - Set bit ADIE (Cho phép ngắt chuyển đổi ADC) Bước 3: Đợi thời gian Acquisition (lấy mẫu) cần thiết Bước 4: Bắt đầu quá trình chuyển đổi ADC Set bit GO/ DONE (ADCON0) Bước 5: Đợi quá trình ADC hoàn tất: Chạy vòng lập đợi bit GO/DONE bị xóa hoặc cờ ngắt ADIF bật lên Bước 6 : Đọc kết quả trong 2 thanh ghi ADRESH và ADRESL, xóa bit ADIF ( nếu cần thiết) Bước 7: Nếu muốn tiếp tục thực hiện chuyển đổi ADC trong chu kỳ kế tiếp thì quay lại bước 1 hoặc bước 2. Sơ đồ khối của bộ biến đổi ADC 10 bit: Hình 2.32: sơ đồ khối bộ biến đổi ADC 10bit. 2.1.6.4) Thời gian lấy mẫu: Thời gian lấy mẫu bao gồm hai giai đoạn: Thời gian acquition: Là thời gian cần để tụ điện của bộ sample and hold (tạm dịch là bộ lấy mẫu và giữ) nạp điện để có giá trị điện thế bằng với giá trị của nguồn analog cần lấy mẫu.Thời gian chuyển đổi từ tương tự sang số: Vào khoảng 12 chu kỳ của bộ ADC. Tổng 2 thời gian đó ta được thời gian lấy mẫu Cách tính thời gian acquition: TACQ = Thời gian ổn định của phần cứng khuếch đại + Thời gian nạp của tụ + hệ số nhiệt độ TACQ = TAMP + TC + TCOFF = 2µs + TC +[(Nhiệt độ - 250C)(0.05/0C)] = 19.72 µs Hình 2.33 sơ đồ thời gian lấy mẫu 2.1.6.5) Lựa chọn xung Clock cho biến đổi ADC: Thời gian chuyển đổi 1 bit được định nghĩa là chu kỳ TAD. Để biến đổi 10 bit chúng ta cần thời gian xấp xỉ 12TAD . Nguồn xung clock cung cấp cho ADC được lựa chọn bằng phần mềm. Có 4 giá trị để lựa chọn: - 2 Tosc - 8 Tosc - 32 Tosc - Dao động nội RC của module ADC (2-6µs) Để đảm bảo quá trình ADC chính xác thì xung clock ADC (TAD) phải được lựa chọn để đảm bảo rằng giá trị tối thiểu của TAD là 1.6µs. Bảng sau đây chỉ ra môi liên hệ giữa TAD và tần số của thiết bị: Hình 2.34 Mối liên hệ giữa TAD và tần số của thiết bị 2.1.6.6) Cấu hình các chân Analog: Các thanh ghi ADCON1 và TRIS điều khiển hoạt động của các chân ADC. Đối với các chân cần được quy định là ngõ vào Analog thì các bit tương ứng trong thanh ghi TRIS phải được set, nếu các bit trong thanh ghi TRIS bị xóa (output) thì các ngõ ra số (VOH hoặc VOL) sẽ được chuyển đổi. Hoạt động của bộ ADC sẽ phụ thuộc vào trạng thái của các bit CHS2:CHS0 và các bit trong thanh ghi TRIS. 2.1.6.7) Chuyển đổi ADC: Việc xóa bit GO/DONE trong quá trình chuyển đổi sẽ bỏ qua chuyển đổi hiện tại. Cặp thanh ghi kết quả chuyển đổi ADC sẽ không được cập nhật những mẫu chuyển đổi ADC đã hoàn tất. Do đó, cặp thanh ghi ADRESH và ADRESL sẽ chứa giá trị của lần chuyền đổi hoàn tất cuối cùng ( hoặc giá trị được ghi cuối cùng vào 2 thanh ghi này). Sau khi một chuyển đổi ADC bị bỏ qua, việc lấy mẫu tiếp theo dựa trên kênh ADC đã chọn sẽ tự động diễn ra. Sau đó bit GO/DONE có thể được set để bắt đầu chuyển đổi ADC. Chú ý: Bit GO/DONE không nên được set trong cùng một lệnh với lệnh mở module ADC. Cặp thanh ghi ADRESH và ADRESL dùng để lưu kết quả ADC 10 bit. Module ADC cho phép ta lựa chọn việc canh trái hay canh phải kết quả 10 bit trong thanh ghi kết quả bằng cách xóa hoặc set bit ADFM. Các bit còn lại mang giá trị là 0. Hình 2.35:ADRESH và ADRESL Register 2.1.6.8) Hoạt động của Module ADC trong chế độ ngủ: Module ADC có thể hoạt động trong chế độ ngủ (Sleep). Điều này yêu cầu nguồn xung clock cung cấp cho ADC phải từ dao động RC (ADCS1:ADCS0 = 11). Khi xung clock RC được chọn, module ADC sẽ đợi một chu kỳ máy trước khi bắt đầu tiến hành chuyển đổi ADC. Điều này cho phép lệnh SLEEP có thể được thực thi mà không gây nhiễu đến quá trình ADC. Khi chuyển đổi ADC hoàn tất, bit GO/DONE sẽ bị xóa và kết quả được lưu vào cặp thanh ghi ADRESH, ADRESL. Nếu ngắt ADC được cho phép, nó sẽ làm VĐK thoát khỏi chế độ ngủ. Nếu ngắt không được cho phép, module ADC sau đó sẽ bị tắt mặc dù bit ADCON vẫn còn ở mức cao. Khi nguồn xung clock khác được chọn chứ không phải RC, lệnh SLEEP sẽ làm cho chuyển đổi ADC hiện tại bị bỏ qua và module ADC sẽ bị tắt dù bit ADCON vẫn còn đang ở mức 1. 2.1.6.9) Ảnh hưởng của Reset: Một reset thiết bị sẽ buộc tất cả các thanh ghi rơi vào trạng thái Reset của chúng.Điều này buộc module ADC bị tắt và bất kỳ chuyển đổi ADC nào cũng bị bỏ qua. Tất cả các chân ngõ vào A/D sẽ được cấu hình là các ngõ vào Analog. Giá trị trong cặp thanh ghi ADRESH:ADRESL không bị thay đổi trong một Reset Power-on. Cặp thanh ghi này sẽ chứa một giá trị không biết trước sau reset Power-on. 2.1.7) Các ngắt của Pic 16F877a. Pic 16F877a có 14 nguồn ngắt, thanh ghi INTCON là thanh ghi điều khiển các ngắt, mỗi ngắt có một bít cờ ngắt và một bít cho phép hoặc cấm ngắt. Bit GIE (INTCON) điều khiển chung cho 14 ngắt khi bít này set thì các ngắt mới có tác dụng, khi bit GIE bị xóa thì các ngắt bị cấm. Bit GIE bị xóa khi reset. Khi bít cờ ngắt thiết lập, bit GIE thiết lập và bit PEIE thiết lập với ngắt ngoại vi. Đồng thời bít cho phép ngắt của ngắt đó cho phép thì ngắt đó xảy ra. Khi một ngắt xảy ra thì bộ đếm chương trình PC được nạp giá trị 0004h và bit GIE bị xóa để cấm sự chồng ngắt, khi chỉ lệnh RETFIE thực hiện trả lại địa chỉ cho PC nơi xảy ra ngắt, đồng thời thiết lặp lại GIE Khi xảy ra ngắt PC luôn được nạp giá trị 0004h vì ngắt được phân biệt bởi bit cờ ngắt của ngắt đó. Ngắt ngoài từ chân RB0/INT, và ngắt từ sự thay đổi trang thái của chân RB4:RB7 có thể đánh thức bộ xử lý từ chế độ SLEEP. Các thanh ghi PIE1, PIR1, PIE2, PIR2 điều khiển các ngắt ngoại vi Sơ đồ bit điều khiển ngắt: Khi một ngắt xảy ra chỉ có PC được lưu trong stack. Do đó, người sử dụng phải lưu vào các thanh ghi W, STATUS, PCLATH khi xảy ra ngắt. 2.2) GIỚI THIỆU CÁC LINH KIỆN KHÁC: 2.2.1) Liquid crystal display ( LCD ) : 2.2.1.a) Cấu tạo Chức năng các chân của Module LCD 16x2: Chân số Ký hiệu Mức logic I/O Chức năng 1 Vss - - Nguồn cung cấp(GND) 2 Vdd - - Nguồn cung cấp(+5V) 3 Vee - I Điện áp để điều chỉnh độ tương phản 4 RS 0/1 I Lựa chọn thanh ghi 0= thanh ghi lệnh 1=thanh ghi dữ liệu 5 R/W 0/1 I 0=ghi vào LCD module 1=đọc từ LCD module 6 E 1,1=>0 I Tín hiệu cho phép 7 DB1 0/1 I/O Data bus line 0(LSB) 8 DB2 0/1 I/O Data bus line1 9 DB3 0/1 I/O Data bus line2 10 DB4 0/1 I/O Data bus line3 11 DB5 0/1 I/O Data bus line4 12 DB6 0/1 I/O Data bus line5 13 DB7 0/1 I/O Data bus line6 14 DB8 0/1 I/O Data bus line7(MSB) 15 Vcc - - Nguồn cung cấp 16 GND - - mass 2.2.1.b) Sơ đồ nguyên lý 2.2.1.c) Nguyên tắc hiển thị ký tự trên LCD: Một chương trình hiển thị ký tự trên LCD sẽ đi theo bốn bước sau: Xóa toàn bộ màn hình. Đặt chế độ hiển thị. Đặt vị trí con trỏ (nơi bắt đầu của ký tự hiển thị). Hiển thị ký tự. Chú ý: +Các bước 3, 4 có thể lặp lại nhiều lần nếu cần hiển thị nhiều ký tự. + Mỗi khi thực hiện ghi lệnh hoặc ghi dữ liệu hiển thị lên LCD cần phải kiểm tra cờ bận trước. Vì vậy, cần phải chủ động phân phối thời gian khi ra lệnh cho LCD( ví dụ sau khi xóa màn hình sau khoảng 2ms mới ra lệnh khác vì thời gian để LCD xóa màn hình là 1,64ms).+chế độ hiển thị mặc định sẽ là hiển thị dịch, vị trí con trỏ mặc định sẽ là đầu dòng thứ nhất. 2.2.1.d). Mã lệnh của LCD HD4480 Lệnh Mã lệnh Mô tả Thời gian thi hành RS R/W DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 Xóa màn hình 0 0 0 0 0 0 0 0 0 1 Xóa màn hình đưa con trỏ về vị trí đầu 1.64ms Đưa con trỏ về vị trí đầu 0 0 0 0 0 0 0 0 1 x Đưa con trỏ về vị trí đầu 1.64ms Thiết lập chế độ 0 0 0 0 0 0 0 1 I/D S Thiết lập hướng dịch chuyển con trỏ(I/D), dịch hiển thị(S) 40us Bật tắt hiển thị 0 0 0 0 0 0 1 D C B Bật tắt hiển thị, con trỏ; bật tắt chế độ nhấp nháy con trỏ 40us Dịch con trỏ hiển thị 0 0 0 0 0 1 S/C R/L * * Thiết lập chiều dịch chuyển của con trỏ và hiển thị 40us Thiết lập chức năng 0 0 0 0 1 DL N F * * Thiết lập độ dài của dữ liệu, số dòng và font chữ 40us Thiết lập địa chỉ CGRAM 0 0 0 1 CGRAM address Thiết lập địa chỉ CGRAM 40us Thiết lập địa chỉ DDRAM 0 0 1 DDRAM address Thiết lập địa chỉ DDRAM 40us Đọc cờ báo bận và địa chỉ CGRAM/ DDRAM 0 1 BF CGRAM/ DDRAM address Đọc cờ báo bận và địa chỉ của CGRAM hoặc DDRAM( tùy vào lệnh trước đó) 40us Ghi CGRAM/ DDRAM 1 0 Write data Ghi dữ liệu vào CGRAM hoặc DDRAM. 40us Đọc CGRAM/ DDRAM 1 1 Read data Đọc dữ liệu từ CGRAM hoặc DDRAM 40us 2.2.1.e) Các bit viết tắt trong mã lệnh. Tên bit Mô tả I/D 0=không dịch chuyển vị trí con trỏ 1=dịch chuyển vị trí con trỏ S =0 không dịch chuyển hiển thị =1 dịch chuyển hiển thị D 0=tắt hiển thị =1 bật hiển thị C 0=tắt con trỏ =1 bật con trỏ B 0=con trỏ không nhấp nháy =1 con trỏ nhấp nháy S/C 0=di chuyển con trỏ =1 dịch chuyển hiển thị R/L 0= dịch trái =1 dịch phải DL 0=chế độ 4bit dữ liệu =1 chế độ 8bit dữ liệu N 0=1 dòng 1= 2 dòng F 0= font 5x7 1= font 5x10 BF 0= không bận 1= đang bận 2.2.2) Cảm biến nhiệt độ LM35: LM35DZ là loại cảm biến nhiệt độ được sử dụng rộng rãi trong công nghiệp,bởi giá thành thấp và cách vận hành đơn giản.LM35DZ có mức điện áp thay đổi trực tiếp theo độ C (10mV/*C). Sơ đồ chân của LM35DZ: Chân +Vs là chân cung cấp điện áp cho LM35DZ hoạt động (4—20V). Chân Vout là chân điện áp ngõ ra của LM35DZ,được đưa vào chân Analog của các bộ ADC. Chân GND là chân nối mass,lưu ý cần nối mass chân này để trành làm hỏng cảm biến cũng như làm giảm sai số trong quá trình đo. CHƯƠNG 3 : TẬP LỆNH CHƯƠNG TRÌNH 3.1 Nhóm lệnh hợp ngữ 3.1.1. NHÓM LỆNH DI CHUYỂN 3.1.1.1. Lệnh MOVLW Cú pháp: MOVLW k (0≤ k≤255) Tác dụng: Đem giá trị k vào thanh ghi W 3.1.1.2. Lệnh MOVWF Cú pháp: MOVWF f (0≤ k≤255) Tác dụng: Đem giá trị của thanh ghi W vào thanh ghi f Để gián cho thanh ghi một giá trị cụ thể, đầu tiên đưa giá trị cần gián cho thanh ghi W, sau đó ta thực hiên lệnh MOVWF để di chuyển giá trị trong thanh ghi W sang thanh ghi cần gián. Tuy nhiên, còn có cách khác thông qua thanh ghi “con trỏ” FSR, khi thanh ghi “con trỏ” FSR trỏ đến byte có địa chỉ nào thì nội dung của thanh ghi đó di chuyển vào thanh ghi INDF. Để hiểu một cách đơn giản ta hiểu thanh ghi FSR chứa địa chỉ còn thanh ghi INDF chứa nội dung. 3.1.1.3. Lệnh MOVF Cú pháp: MOVF f,W Tác dụng: Đem giá trị của thanh ghi f vào thanh ghi W Để di chuyển giá trị ở thanh ghi COUNT1 sang thanh ghi COUNT2 thì ta bắt buộc qua thanh ghi “trung gian” W thông qua lệnh MOVF. 3.1.2. NHÓM LỆNH SỐ HỌC 3.1.2.1 Lệnh ADDLW Cú pháp: ADDLW k (0≤ k≤255) Tác dụng: Cộng giá trị k vào thanh ghi W,kết quả được chứa trong thanh ghi W. Bit trạng thái: C, DC, Z 3.1.2.2.Lệnh ADDWF Cú pháp: ADDWF f,d (0≤f≤255, d ∈[0,1]). Tác dụng: Cộng giá trị hai thanh ghi W và thanh ghi f. Kết quả được chứa trong thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d =1. Bit trạng thái: C, DC, Z 3.1.2.3. Lệnh SUBLW Cú pháp: SUBLW k Tác dụng: Lấy giá trị k trừ giá trị trong thanh ghi W. Kết quả được chứa trong thanh ghi W. Bit trạng thái: C, DC, Z 3.1.2.4. Lệnh SUBWF Cú pháp: SUBWF f,d (0≤f≤127, d ∈ [0,1]) Tác dụng: Lấy giá trị trong thanh ghi f đem trừ cho thanh ghi W. Kết quả được lưu trong thanh ghi W nếu d=0 hoặc thanh ghi f nếu d=1. Bit trạng thái: C, DC, Z 3.1.2.5. Lệnh INCF Cú pháp: INCF f,d (0≤f≤127, d ∈ [0,1]) Tác dụng: Tăng giá trị thanh ghi f lên 1 đơn vị. Kết quả được đưa vào thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d = 1. Bit trạng thái: Z 3.1.2.6. Lệnh DECF Cú pháp: DECF f,d (0≤f≤127, d ∈[0,1]). Tác dụng: Giá trị thanh ghi f được giảm đi 1 đơn vị. Kết quả được đưa vào thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d = 1. Bit trạng thái: Z 3.1.3. NHÓM LỆNH LOGIC 3.1.3.1. Lệnh BCF Cú pháp: BCF f,b (0≤b≤7) Tác dụng: Xóa bit b trong thanh ghi f về giá trị 0. Bit trạng thái: không có. 3.1.3.2. Lệnh BSF Cú pháp: BSF f,b (0≤b≤7) Tác dụng: Set bit b trong thanh ghi f. Bit trạng thái: không có 3.1.3.3. Lệnh CLRW Cú pháp CLRW Tác dụng: Xóa thanh ghi W và bit Z được set. Bit trạng thái: Z 3.1.3.4. Lệnh CLRF Cú pháp CLRF f (0≤f≤127) Tác dụng: Xóa thanh ghi f và bit Z được set. Bit trạng thái: Z 3.1.3.5. Lệnh CLRWDT Cú pháp: CLRWDT Tác dụng: Reset Watchdog Timer, đồng thời prescaler cũng được reset, các bit và được set lên 1. 3.1.3.6. Lệnh ANDLW Cú pháp: ANDLW k (0≤k≤255) Tác dụng: Thực hiện phép toán AND giữa thanh ghi và giá trị k, kết quả được chứa trong thanh ghi W. Bit trạng thái: Z Chú ý: And các bit tương ứng 3.1.3.7. Lệnh ANDWF Cú pháp: ANDWF f,d (0≤f≤127, d ∈[0,1]). Tác dụng: Thực hiện phép toán AND giữa các giá trị chứa trong hai thanh ghi W và f. Kết quả được đưa vào thanh ghi W nếu d=0 hoặc thanh ghi f nếu d = 1. Bit trạng thái: Z 3.1.3.8. Lệnh IORLW Cú pháp: IORLW k (0≤k≤255) Tác dụng: Thực hiện phép toán OR giữa thanh ghi W và giá trị k. Kết quả được chứa trong thanh ghi W. Bit trạng thái: Z 3.1.3.9. Lệnh IORWF Cú pháp: IORWF f,d (0≤f≤127, d∈[0,1]) Tác dụng: Thực hiện phép toán OR giữa hai thanh ghi W và f. Kết quả được đưa vào thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d=1. Bit trạng thái: Z 3.1.3.10. Lệnh XORLW Cú pháp: XORLW k (0≤k≤255) Tác dụng: Thực hiện phép toán XOR giữa giá trị k và giá trị trong thanh ghi W. Kết quả được lưu trong thanh ghi W. Bit trạng thái: Z 3.1.3.11. Lệnh XORWF Cú pháp: XORWF f,d Tác dụng: Thực hiện phép toán XOR giữa hai giá trị chứa trong thanh ghi W và thanh ghi f. Kết quả được lưu vào trong thanh ghi W nếu d=0 hoặc thanh ghi f nếu d=1. Bit trạng thái: Z 3.1.3.12. Lệnh SWAPF Cú pháp: SWAPF f,d (0≤f≤127, d∈[0,1]) Tác dụng: Đảo 4 bit thấp với 4 bit cao trong thanh ghi f. Kết quả được chứa trong thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d = 1. Bit trạng thái: không có 3.1.3.13. Lệnh RLF Cú pháp: RLF f,d (0≤f≤127, d∈[0,1]) Tác dụng: Dịch trái các bit trong thanh ghi f qua cờ carry. Kết quả được lưu trong thanh ghi W nếu d=0 hoặc thanh ghi f nếu d=1. Bit trạng thái: C 3.1.3.14. Lệnh RRF Cú pháp: RRF f,d (0≤f≤127, d∈[0,1]) Tác dụng: Dịch phải các bit trong thanh ghi f qua cờ carry. Kết quả được lưu trong thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d = 1. Bit trạng thái: C 3.1.3.15. Lệnh COMF Cú pháp: COMF f,d (0≤f≤127, d∈[0,1]). Tác dụng: Đảo các bit trong thanh ghi f. Kết quả được đưa vào thanh ghi W nếu d =0 hoặc thanh ghi f nếu d=1. Bit trạng thái: Z 3.1.4.NHÓM LỆNH RẼ NHÁNH 3.1.4.1. Lệnh BTFSS Cú pháp: BTFSS f,b (0≤f≤127, 0≤b≤7) Tác dụng: Kiểm tra bit b trong thanh ghi f. Nếu bit b bằng 0, lệnh tiếp theo được thực thi. Nếu bit b bằng 1, lệnh tiếp theo được bỏ qua và thay vào đó là lệnh NOP. Bit trạng thái: không có 3.1.4.2. Lệnh BTFSC Cú pháp: BTFSC f,b (0≤f≤127, 0≤b≤7) Tác dụng: kiểm tra bit b trong thanh ghi f. Nếu bit b bằng 1, lệnh tiếp theo được thực thi. Nếu bit b bằng 0, lệnh tiếp theo được bỏ qua và thay vào đó là lệnh NOP. Bit trạng thái: không có 3.1.4.3. Lệnh DECFSZ Cú pháp: DECFSZ f,d (0≤f≤127, d∈ [0,1]) Tác dụng: gía trị thanh ghi f được giảm 1 đơn vị. Nếu kết quả sau khi giảm khác 0, lệnh tiếp theo được thực thi, nếu kết quả bằng 0, lệnh tiếp theo không được thực thi và thay vào đó là lệnh NOP. Kết quả được đưa vào thanh ghi W nếu d = 0 hoặc thanh ghi f nếu d = 1. Bit trạng thái: không có 3.1.4.4. Lệnh INCFSZ Cú pháp: INCFSZ f,d (0≤f≤127, d∈ [0,1]) Tác dụng: tăng giá trị thanh ghi f lên 1 đơn vị. Nếu kết quả khác 0, lệnh tiếp theo được thực thi, nếu kết quả bằng 0, lệnh tiếp theo được thay bằng lệnh NOP. Kết quả sẽ được đưa vào thanh ghi f nếu d=1 hoặc thanh ghi W nếu d = 0. Bit trạng thái: không có. 3.1.4.5. Lệnh GOTO Cú pháp: GOTO k (0≤k≤047) Tác dụng: nhảy tới một label được định nghĩa bởi tham số k và 2 bit PCLATH . Bit trạng thái: không có. 3.1.4.6. Lệnh CALL Cú pháp: CALL k (0≤k≤2047) Tác dụng: gọi một chương trình con. Trước hết địa chỉ quay trở về từ chương trình con (PC+1) được cất vào trong Stack, giá trị địa chỉ mới được đưa vào bộ đếm gồm 11 bit của biến k và 2 bit PCLATH. Bit trạng thái: không có 3.1.4.7. Lệnh RETURN Cú pháp: RETURN Tác dụng: quay trở về chương trình chính từ một chương trình con Bit trạng thái:không có 3.1.4.8. Lệnh #DIFINE Cú pháp: #DEFINE Tác dụng: thay thế một chuỗi kí tự này bằng một chuỗi kí tự khác, có nghĩa là mỗi khi chuỗi kí tự text1 xuất hiện trong chương trình, trình biên dịch sẽ tự động thay thế chuỗi kí tự đó bằng chuỗi kí tự . 3.1.4.9. Lệnh INCLUDE Cú pháp: #INCLUDE hoặc #INCLUDE "filename" Tác dụng: đính kèm một file khác vào chương trình, tương tự như việc ta copy file đó vào vị trí xuất hiện lệnh INCLUDE. Nếu dùng cú pháp thì file đình kèm là file hệ thống (sýtem file), nếu dùng cú pháp "filename" thì file đính kèm là file của người sử dụng. Thông thường chương trình được đính kèm theo một "header file" chứa các thông tin định nghịa các biến (thanh ghi W, thanh ghi F,..) và các địa chỉ cảu các thanh ghi chức năng đặc biệt trong bộ nhớ dữ liệu. Nếu không có header file, chương trình sẽ khó đọc và khó hiểu hơn. 3.1.4.10 .Lệnh CONSTANT Cú pháp: CONSTANT = Tác dụng: Khai báo một hằng số, có nghĩa là khi phát hiện chuỗi kí tự "name" trong chương trình, trình biên dịch sẽ tự động thay bằng chuỗi kí tự bằng giá trị "value" đã được định nghĩa trước đó. 3.1.4.11. Lệnh VARIABLE Cú pháp: VARIABLE = Tác dụng: Tương tự như lệnh CONSTANT, chỉ có điểm khác biệt duy nhất là giá trị "value" khi dùng lệnh VARIABLE có thể thay đổi được trong quá trình thưc thi chương trình còn lệnh CONSTANT thì không. 3.1.4.12. Lệnh SET Cú pháp: SET Tác dụng: Gán giá trị cho một tên biến. Tên của biến có thể thay đổi được trong quá trình thực thi chương trình. 3.1.4.13. Lệnh EQU Cú pháp: EQU Tác dụng: Gán giá trị cho tên của tên của hằng số. Tên của hằng số không thay đổi trong quá trình thực thi chương trình. 3.1.4.15. Lệnh ORG Cú pháp: ORG Tác dụng: Định nghĩa một địa chỉ chứa chương trình trong bộ nhớ chương trình của vi điều khiển. 3.1.4.16. Lệnh END Cú pháp: END Tác dụng: Đánh dấu kết thúc chương trình. 3.1.4.17. Lệnh __CONFIG Tác dụng: Thiết lập các bit điều khiển các khối chức năng của vi điều khiển được chứa trong bộ nhớ chương trình (Configuration bit). 3.1.4.18. Lệnh PROCESSOR Cú pháp: PROCESSOR Tác dụng: Định nghĩa vi điều khiển nào sử dụng chương trình. 3.2- Nhóm lệnh CCS CCS là trình biên dịch dùng ngôn ngữ C lập trình cho vi điều khiển. Đây là ngôn ngữ lập trình đầy sức mạnh, giúp bạn viết chương trình nhanh và dễ dàng hơn ngôn ngữ Assembly. Mã lệnh được tối ưu khi biên dịch. Tuy nhiên, C không phải vạn năng. Trong một số trường hợp, nó có thể sinh mã chạy sai. CCS chứa rất nhiều hàm phục vụ cho mọi mục đích và có rất nhiều cách lập trình mã cho cùng 1 vấn đề dẫn đến khác nhau tốc độ thực thi lệnh, độ dài chương trình. CCS cho phép bạn phối hợp với Assembly cùng với C. CCS cung cấp các công cụ tiện ích giám sát hoạt động chương trình như: C/ASM list cho phép xem mã ASM của file biên dịch. SYMBOL hiển thị bộ nhớ cấp phát cho từng biến, giúp quản lý bộ nhớ các biến chương trình. …. 3.2.1 Các mệnh đề lựa chọn (hay điều kiện) Có 3 loại mệnh đề lựa chọn: hai loại dùng từ khóa if và một loại dùng từ khóa switch. Đó là: 3.2.1.1 Dạng dùng từ khóa if: if () if () else Trong dạng này, nếu phần trong ngoặc đơn có giá trị khác 0 hay có giá trị "đúng" (true) thì dòng điều khiển sẽ chuyển vào để thực thi . Nếu trong câu lệnh if có thêm từ khóa else thì sẽ được thực thi một khi có giá trị 0 hay giá trị "sai". Nhắc lại: như trên thì vị trí mỗi mệnh đề đều có thể thay bằng một khối mã. Trong cách viết mã lồng nhau phức tạp bao gồm nhiều mệnh đề if thì từ khóa else sẽ được gán vào mệnh đề if phía trên gần nhất nào chưa được ghép. Để tránh sự nhầm lẫn cách tốt nhất là lồng chúng vào trong các dấu { và }. 3.2.1.2 Dạng dùng từ khóa switch Mệnh đề switch sẽ gây ra việc chuyển dòng điều khiển sang một trong những mệnh đề con kế tiếp tùy theo giá trị của một biểu thức X (biểu thức này phải có kiểu nguyên). Các mệnh đề con này thường là các mệnh đề phức hợp. Đứng trước mỗi mệnh đề con sẽ là một từ khóa case, sau đó là một biểu thức hằng Hi, và dấu hai chấm : gắn liền tiếp theo đó là mệnh đề con Mi. Khi giá trị của X trùng với một giá trị Hi được nêu ở đâu thì mệnh đề con đi gắn liền vói hằng tại đó (tức là Mi) sẽ được thực thi. Nếu X không bằng với bất kì giá trị Hi nào thì người lập trình có thể dùng thêm từ khóa default, sau đó là dấu hai chấm : và tiếp theo là một mệnh đề con Mdefault. Mệnh đề con này sẽ được thực thi khi mà giá trị của X khác với mọi giá trị hằng Hi. Lưu ý: Trong câu lệnh switch thì không cho phép có hai giá trị hằng bằng nhau. Nghĩa là khi X được đánh giá thì chỉ có tối đa một mệnh đề con được thực thi. Các câu lệnh switch có thể được dùng trong dạng lồng vào nhau (nest), một từ khóa case hay default sẽ thuộc vào câu lệnh switch bên trong nhất (hay nhỏ nhất) chứa nó. Một khi dòng điều khiển hoàn tất câu lệnh con Mi thì nó sẽ tiếp tục thi hành các câu lệnh con Mi+1 theo sau cho đến khi nó bị yêu cầu ngưng bởi câu lệnh nhảy (mà thường dược dùng nhiều nhất là câu lệnh break) Trong dạng thí dụ dưới đây, nếu có giá trị bằng thì mệnh đề các biểu thức ,, và sẽ lần lần lượt được thực thi theo thứ tự nếu như trong chúng không có câu lệnh break. Nhưng vì trong mã thí dụ có câu lệnh break nên dòng điều khiển sẽ ngưng và kết thúc câu lệnh switch khi thi hành lệnh break này. switch () { case : case : break; case : default : 3.2.2 Các mệnh đề tái lặp (hay vòng lặp) -C có 3 dạng câu lệnh vòng lặp: 3.2.2.1 Vòng lặp do do while (); Trong mệnh đề này thì mệnh đề được thực thi lặp lại cho tới khi nào được đánh giá (hay có giá trị) là true. Một khi không còn có giá trị true nữa thì vòng lặp sẽ bị kết thúc. 3.2.2.2 Vòng lặp while while () chỉ được thực thi hay thực thi lặp lại khi có giá trị là true. Nếu có giá trị false thì câu lệnh sẽ bị kết thúc ngay lập tức. 3.2.2.3 Vòng lặp for Dạng C89 của vòng lặp for là: for ( ; ; ) Nó đã được tổng quát hóa trong CCS thành: for ( ; ) Khi cả ba biểu thức đều hiện diện trong một câu lệnh for, thì mệnh đề: for (e1; e2; e3) s; sẽ tương đương với e1; while (e2) { s; e3; } Bất kì biểu thức nào trong vòng lặp for có thể được loại bỏ. Một biểu thức bị mất (e2 chẳng hạn) có thể làm cho vòng lặp biến thành vòng lặp vô hạn. Thí dụ: vòng lặp for sau đây 3 biểu thức ở dạng phức hợp và ngăn cách nhau bởi dấu chấm phẩy ;: for (x=10,y=1;((x>4) && (y<8)); x--,y+=2) printf("x = %d, y = %d \n", x,y); Kết quả thực thi màn hình sẽ hiển thị như sau: x = 10, y = 1 x = 9, y = 3 x = 8, y = 5 x = 7, y = 7 Vòng lặp kết thúc vì điều kiện trong biểu thức thứ nhì ((x>4) && (y<8)) không còn đúng nữa. 3.2.3 Các mệnh đề nhảy (hay bước nhảy) Các lệnh nhảy sẽ thay đổi dòng điều khiển một cách vô điều kiện. có 4 kiểu mệnh đề nhảy trong C là goto, continue, break, và return. 3.2.3.1 goto câu lệnh goto sẽ có dạng: goto ; nhãn phải có mặt trong hàm có chứa câu lệnh goto. Khi đọc đến lệnh này, dòng điều khiển sẽ chuyển đến mệnh đề nhãn. 3.2.3.2 Continue Mệnh đề continue chỉ có thể xuất hiện trong một vòng lặp và có tác dụng làm cho dòng điều khiển chuyển sang chu kì mới của vòng lặp trong cùng nhất (có chứa câu lệnh). Các dạng sử dụng bao gồm while (expression) { /* ... */ cont: ; } do { /* ... */ cont: ; } while (expression); for (optional-expr; optexp2; optexp3) { /* ... */ cont: ; } 3.2.3.3 break Mệnh đề break dùng để kết thúc một câu lệnh vòng lặp hay câu lệnh switch ngay lập tức và chuyển tiếp đến câu lệnh tiếp theo sau của vòng lặp đó. 3.2.3.4 Return Một hàm trả dòng điều khiển về nơi gọi nó bằng câu lệnh return. Khi lệnh return được theo sau bởi một biểu thức thì biểu thức đó sẽ được đánh giá và giá trị này sẽ được trả về cho nơi đã gọi hàm. Khi return được gọi mà không có biểu thức đi kèm thì giá trị trả về là không xác định. 3.2.4 Các phép toán Phép toán trong C và C++ Để tham khảo, sau đây là bảng thứ tự ưu tiên của các phép toán theo C89: Phép toán Mô tả Hướng tiến hành () [] . -> ngoặc đơn (nhóm) phần chỉ số của mảng sự lựa chọn phần tử, nhận dạng sự lựa chọn phần tử, con trỏ từ trái sang phải ++ và -- + và - ! và ~ (cast) * & sizeof tiền tố tăng/giảm dấu dương/âm phép toán Bool NOT/phần bù 0 kiểu bit đổi kiểu tham chiếu ngược tham chiếu độ lớn từ phải sang trái *, /, và % nhân/chia/mô dun từ trái sang phải + và - cộng/trừ > phép toán bit left shift/right shift < và <= > và >= quan hệ nhỏ hơn/nhỏ hơn hay bằng quan hệ lớn hơn/lớn hơn hay bằng == và != bằng với/khác với & phép toán bit AND ^ phép toán bít XOR | phép toán bit OR && phép toán bool AND || phép toán bool OR ?: điều kiện tam phân từ phải sang trái = += và -= *=, /=, và %= >= &=, ^=, va |= phép gán giá trị trực tiếp phép gán giá trị cộng thêm/trừ bớt phép gán giá trị nhân/chia/mô dul bởi phép gán bit shift phép gán bit AND/XOR/OR , toán tử , từ trái sang phải 3.2.5 Khai báo dữ liệu 3.2.5.1 Các kiểu dữ liệu cơ bản Nhiều ngôn ngữ lập trình kể cả C, biểu thị các số trong hai dạng: nguyên và thực (hay không nguyên). Sự khác nhau này hình thành từ khía cạnh kỹ thuật của các cách thức xử lý và lưu trữ các giá trị trong bộ nhớ. Kiểu nguyên viết dưới dạng int được dùng để biểu thị các số nguyên. Kiểu nguyên có trong nhiều kích cỡ khác nhau tùy theo phân lượng bộ nhớ được dùng và độ lớn cao nhất1. Các từ khóa, có tên là các định tính, được dùng thêm vào để điều chỉnh lại kích cỡ là: short, long và long long2. Kiểu kí tự mà từ khóa của nó là char, biểu thị đơn vị nhỏ nhất có thể địa chỉ hóa được (bởi kiến trúc máy tính) thường là một byte với 8 bit. Dạng thực được dùng để biểu thị các số thập phân hay các bộ phận hữu tỉ. Mặc dù vậy chúng không hoàn toàn chính xác mà chỉ là các biểu thị gần đúng. Có 3 kiểu giá trị thực bao gồm: loại có độ chính xác đơn (có đặc tả là float), loại có độ chính xác kép (có đặc tả là double), và loại có độ chính xác kép mở rộng (có đặc tả là long double). Mỗi loại dùng để biểu thị các giá trị không nguyên trong một dạng khác nhau. Các kiểu nguyên có thể hoặc là có dấu (signed) hay không dấu (unsigned). Nếu không chỉ rõ khi khai báo thì mặc định (hiểu ngầm) sẽ là loại có dấu. Một ngoại lệ là các kiểu char, signed char và unsigned char đều khác nhau, và kiểu char có thể là loại có dấu hay không có dấu. Đối với loại có dấu, thì bit có nghĩa cao nhất được dùng để biểu thị dấu (dương hay âm). Thí dụ một số nguyên 16-bit loại có dấu thì chỉ dùng 15 bit để biểu thị giá trị (tuyệt đối) của nó còn bit có nghĩa cao nhất lại được dùng để cho biết đó là số dương hay âm. Đối với loại không dấu thì bit này lại được dùng thêm vào để biểu thị giá trị. 3.2.5.2 Các hằng số xác định các giá trị biên Tập tin tiêu đề chuẩn limits.h sẽ xác định các giá trị nhỏ nhất và lớn nhất của các kiểu nguyên cơ bản cũng như là xác định các giới hạn khác. Tập tin tiêu đề chuẩn float.h sẽ xác định các giá trị nhỏ nhất và lớn nhất của các kiểu float, double, và long double. Nó cũng xác định các giới hạn khác liên quan tới việc xử lý các giá trị của dấu chấm động (floating-point) có độ chính xác đơn hay có độ chính xác kép như là chúng được định nghĩa trong chuẩn IEEE 754. Bản hằng số xác định các biên của những kiểu nguyên thông thường Đặc tả hiểu ngầm Đặc tả viết rõ ra Giá trị nhỏ nhất Giá trị lớn nhất char viết y hệt CHAR_MIN CHAR_MAX signed char viết y hệt SCHAR_MIN SCHAR_MAX unsigned char viết y hệt 0 UCHAR_MAX short signed short int SHRT_MIN SHRT_MAX unsigned short unsigned short int 0 USHRT_MAX không viết gì hết, signed, hay int signed int INT_MIN INT_MAX unsigned unsigned int 0 UINT_MAX long signed long int LONG_MIN LONG_MAX unsigned long unsigned long int 0 ULONG_MAX long long1 signed long long int1 LLONG_MIN2 LLONG_MAX2 unsigned long long1 unsigned long long int1 0 ULLONG_MAX2 1— Định tính long long chỉ được hỗ trợ trong các trình dịch thỏa mãn chuẩn C99. 2— Các hằng LLONG_MIN, LLONG_MAX, và ULLONG_MAX chỉ được định nghĩa trong limits.h nếu trình dịch tương ứng thỏa mãn chuẩn C99. 3.2.5.3 Các giá trị biên điển hình Sau đây là danh sách kích cỡ và các biên điển hình của các kiểu nguyên. Các giá trị này có thể khác nhau tùy theo kiến trúc (máy và trình dịch). ISO C cung cấp tiêu đề inttypes.h, trong đó, có xác định các kiểu nguyên có dấu và không có dấu nhưng điều chắc chắn là kích cỡ đều nằm trong khoảng 8 đến 64 bit. Kích cỡ và biên điển hình của các kiểu nguyên Đặc tả hiểu ngầm Đặc tả viết rõ ra Số bit Số byte Giá trị nhỏ nhất Giá trị lớn nhất Char viết y hệt 8 1 -128 or 0 127 hay 255 signed char viết y hệt 8 1 -128 127 unsigned char viết y hệt 8 1 0 255 Short signed short int 16 2 -32 768 32 767 unsigned short unsigned short int 16 2 0 65 535 Long signed long int 32 4 -2 147 483 648 2 147 483 647 unsigned long unsigned long int 32 4 0 4 294 967 295 long long1 signed long long int1 64 8 -9 223 372 036 854 775 808 9 223 372 036 854 775 807 unsigned long long1 unsigned long long int1 64 8 0 18 446 744 073 709 551 615 1— Định tính long long chỉ được hỗ trợ trong các trình dịch thỏa mãn chuẩn C99. Kích cỡ và giới hạn của kiểu cơ bản int (mà không có các định tính short, long, hay long long) có thể thay đổi khác nhau (nhiều hơn các kiểu nguyên khác) tùy theo sư thiết lập (của trình dịch hay của kiến trúc máy). Cho nên, một thao tác thông thường là định nghĩa nó như là một đồng nghĩa của size_t — trong tập tin sys/types.h — và do đó, đủ sức để thích ứng với giá trị lớn nhất khả dĩ của con trỏ mà có thể được cấp phát bởi hệ thống. Đặc tả UNIX đơn chỉ ra rằng kiểu int phải có ít nhất 32 bit, mặc dù chuẩn ISO C chỉ yêu cầu có 16 bit. 3.2.6 Các mảng 3.2.6.1Khai báo mảng tĩnh Trong C, mảng được dùng để biểu thị một cấu trúc của một dãy nhiều giá trị có cùng một kiểu được xếp thứ tự. Một mảng gọi là tĩnh nếu độ dài của dãy mảng này cố định. Sự khai báo của mảng tĩnh có cú pháp sau: int array[n]; Trong đó, tên của mảng là array sẽ có thể chứa được n giá trị của kiểu cơ bản int. Trong thực hành, phần bộ nhớ cho n giá trị nguyên này được để dành riêng và được gán cho mảng này (mặc dù giá trị của các phần tử trong mảng chưa được xác định). Biến array thực chất là một kiểu tham chiếu của kiểu nguyên; nó khởi thủy sẽ chỉ tới địa chỉ của giá trị đầu tiên trong mảng. 3.2.6.2 Truy cập các phần tử Các giá trị của một mảng được gọi là các phần tử trong mảng. Một cách để truy cập đến các phần tử này là dùng đến cặp kí tự ngoặc vuông dạng [k]. Trong đó k là chỉ số (hay vị trí thứ tự đếm từ 0). Như vậy, phần tử thứ k trong mảng array sẽ có cú pháp array[k] Giá trị trả về của array[k] chính là giá trị mà nó chứa ở vị trí k. Thoạt nhìn thì cú pháp của việc truy cập này trông giống như cú pháp khi mảng array được khai báo nhưng về chức năng thì hoàn toàn khác nhau. Chỉ số bắt đầu của một mảng là 0. Như vậy, chỉ số lớn nhất của một mảng bằng tổng số các phần tử trong mảng trừ đi 1. Thí dụ mảng A có 10 phần tử thì giá trị của phần tử đầu tiên của A là A[0] và của phần tử cuối dùng là A[9]. Một cách truy cập khác là dùng con trỏ số học để tham chiếu đến giá trị của các phần tử trong mảng. Bảng sau đây sẽ minh họa cách dùng của cả hai phương pháp: Array Chỉ số và con trỏ số học Phần tử vị trí 0 1 2 n Kiểu dùng cơ bản array[0] array[1] array[2] array[n] Dùng con trỏ *array *(array + 1) *(array + 2) *(array + n) 3.2.6.3 Các mảng động C không cung cấp phương tiện để kiểm tra biên cho các mảng. Nghĩa là nó không thể bắt được các lỗi khi gán cho một mảng chỉ số âm hay chỉ số vượt quá độ đài của mảng đó. Và hơn thế nữa các chỉ số trong một mảng có thể vượt khỏi độ dài sẵn có của mảng đó. Vì các mảng là thuần nhất, tức là nó chỉ chứa các dữ liệu có chung một kiểu nên hai thành phần thông tin cần nhớ là địa chỉ của phần tử đầu tiên và kiểu của dữ liệu. Nhắc lại về cú pháp để khai báo một mảng tĩnh, tức là tạo ra một biến tham chiếu nguyên và cấp phát một vùng nhớ tương ứng cho nó: int array[n]; Cách biểu hiện này có thể được tái lập với sự giúp đỡ của thư viện chuẩn C. Hàm calloc cung cấp một cách đơn giản để cấp phát một vùng nhớ. Hai tham số dùng đến sẽ là số lượng các phần tử và kích cỡ (độ lớn) của mỗi phần tử. Khi việc cấp phát bộ nhớ hoàn thành, calloc trả về một con trỏ chỉ tới phần tử đầu tiên và gán cho mọi phần tử giá trị khởi động là 0. Nếu sự cấp phát vùng nhớ không thành công (vì bộ nhớ không đủ chỗ trống hạn) thì calloc trả về con trỏ rỗng. Thí dụ: đoạn mã sau đây có chức năng tương đương với việc khai báo một mảng tĩnh của n phần tử có kiểu int: int *array; array = calloc(n, sizeof(int)); Tuy nhiên, điểm vượt trội của cách khai báo này là việc sử dụng cấp phát vùng nhớ động . Kích cỡ của mảng (tức là lượng không gian nhớ được cấp phát một cách an toàn cho mảng) lại có thể được thay đổi sau khi đã khai báo. Một khi việc cấp phát vùng nhớ động không còn cần thiết nữa thì phần bộ nhớ đó nên được trả về cho hệ điều hành. Thao tác này có thể tiến hành bằng hàm free. Nó cần một tham số: tên của con trỏ mà trước đây đã xin cấp phát vùng nhớ. Một cách an toàn hơn là sau khi đã trả vùng nhớ về cho hệ điều hành, người lập trình cũng nên cài (hay gán) cho con trỏ liên đới giá trị NULL để hủy bỏ địa chỉ mà nó đang chỉ tới (nhằm tránh gây ra các hiệu ứng phụ do việc tham chiếu của con trỏ này có thể gây ra). free(array); array = NULL; 3.2.6.4Các mảng đa chiều C có hỗ trợ việc dùng mảng đa chiều. Việc định nghĩa chúng giống như là tạo ra mảng của các mảng , mặc dù vậy trong thực tế nó không hoàn toàn đúng. Cú pháp sau: int array2D[số_hàng][số_cột]; Sẽ định nghĩa một mảng hai chiều; chiều thứ nhất có số_hàng phần tử. Chiều thứ hai sẽ có số_hàng * số_cột các phần tử -- một tập hợp của số_cột các phần tử mà mỗi phần tử là một chiều thứ nhất. Các mảng đa chiều hoàn toàn có thể được xem như là dãy của các con trỏ. Trong thí dụ trên, array2D (nếu số_hàng là 1) sẽ là một tham chiếu giá trị nguyên mà nó chỉ tới một mảng của số_cột các phần tử. 3.2.6.5 Dãy kí tự Dãy kí tự có thể được thay đổi nội dung của nó mà không cần đến thư viện chuẩn. Tuy nhiên, thư viện này có nhiều hàm có thể dùng cho cả dãy kí tự có kết thúc 0 và mảng không có kí tự kết thúc kiểu char. Trong phần này từ "dãy" được để chỉ dãy kí tự. Các hàm thường dùng là: strcat(dest, source) - nối một dãy kí tự source tiếp vào vị trí cuối của dãy kí tự dest strchr(source, c) - tìm vị trí sự xuất hiện đầu tiên của c trong dãy kí tự source và trả về con trỏ chỉ tới vị trí đó hay con trỏ trống nếu c không tìm thấy trong source strcmp(a, b) - so sánh hai dãy kí tự a và b (theo thứ tự từ điển); trả về số âm nếu a nhỏ hơn b, 0 nếu chúng bằng nhau, dương nếu a lớn hơn strcpy(dest, source) - chép và thay các kí tự của dãy dest vào dãy dest strlen(st) - trả về độ dài của st strncat(dest, source, n) - nối tối đa n kí tự từ dãy source tiếp vào vị trí cuối của dãy dest; các kí tự sau dấu kết thúc null sẽ không được chép vào strncmp(a, b, n) - so sánh từ kí tự đầu cho đến tối đa n kí tự từ hai dãy a và b (theo thứ tự từ điển); hàm trả về số âm nếu phần so sánh của a nhỏ hơn b, 0 nếu bằng nhau, và dương nếu lớn hơn strncpy(dest, source, n) - chép từ đầu đến tối đa n kí tự từ dãy source vào dãy dest strrchr(source, c) - tìm vị trí hiện lần cuối cùng của kí tự c trong dãy source và trả về một con trỏ chỉ vào vị trí đó hay con trỏ trống nếu không tìm thấy c trong đó Các hàm ít dùng tới hơn là: strcoll(s1, s2) - so sánh hai dãy theo một trình tự địa phương đặc thù strcspn(s1, s2) - trả về chỉ số của kí tự đầu tiên trong s1 trùng với kí tự bất kì nào trong s2 strerror(err) - trả về một dãy kí tự dưới dạng một thông báo lỗi ứng với mã (câu viết) trong err strpbrk(s1, s2) - trả về một con trỏ chỉ vào kí tự đầu tiên nào trong s1 mà trùng với kí tự bất kì trong s2 hay một con trỏ trống nếu không tìm thấy strspn(s1, s2) - trả về chỉ số của kí tự đầu tiên trong s1 mà nó không xuất hiện trong s2 strstr(source, subst) - trả về một con trỏ chỉ tới vị trí của dãy subst trong dãy source hay trả về một con trỏ rỗng nếu không tồn tại một dãy như vậy bên trong source strtok(s1, s2) - trả về một con trỏ chỉ đến một token bên trong s1 mà được phân chia ra bởi các kí tự trong s2 strxfrm(s1, s2, n) - chuyển đổi s2 thành s1 dùng các quy tắc địa phương đặc thù CHƯƠNG 4 : THIẾT KẾ VÀ THI CÔNG MẠCH 4.1- THI CÔNG 4.1.1- MẠCH NGUỒN Hình 4.1:Sơ đồ mạch khối nguồn Nguồn cung cấp cho tất cả các khối là 5VDC. Điện áp xoay chiều sau khi qua cầu diode sẽ được nắn tương đối phẳng. Tụ C1 có nhiện vụ làm phẳng điện áp, tụ C2 và C3 sẽ triệt tiêu các xung gai có tần số cao và thấp. IC ổn áp 7805 có nhiệm vụ ổn định điện áp chuẩn là 5VDC. R1=150 ohm hạn dòng cho led đơn. Ta có: Vled=2V; Iled=20(mA ). ð VR=VCC-Vled=5-2=3V. IR=Iled=20(mA). ð R=VR/IR=3/20=150(ohm). 4.2.2.2- Khối xử lý, hiển thị và giải mã : Hình 4.2: SỜ ĐỒ KHỐI XỬ LÝ VÀ GIẢI MÃ Hình 4.3: KHỐI HIỂN THỊ 4.3 – CODE CHƯƠNG TRÌNH HIỂN THỊ NHIỆT ĐỘ LÊN LCD: CHƯƠNG 5 :KẾT QUẢ THỰC HIỆN Mạch chạy tốt và hiển thị được nhiệt độ lên LCD. TÀI LIỆU THAM KHẢO www.cdvt.com www.datasheet.4u.com www.dientuvietnam.com.vn Giáo trình vi điều khiển pic 16F877A – Biên soạn Nguyễn Trọng Khanh www.google.com www.picvietnam.com ……………………………………………………………………………………

Các file đính kèm theo tài liệu này:

  • docMẫu báo cáo đồ án Đọc nhiệt độ hiển thị lên LCD.doc