Bước 1: Cho phép chân PWM là ngõ vào: TRISCx=1; //x= 1, 2
Bước 2: Khởi tạo tần số PWM bằng việc định giá trị thanh ghi PR2 của timer 2:
Bước 3: Đặt khối CCP hoạt động ở chế độ PWM
CCPxCON=0bxxxx11xx; //x=0;1
Bước 4: Đặt độ rộng xung của khối PWM bằng việc đặt giá trị cho thanh ghi CCPRxL và 2 bit DCxB<1:0> của thanh ghi CCPxCON
CCPRxL=...; //Có thể điều chỉnh giá trị này trong khi vi điểu khiển hoạt động để thay đổi độ rộng xung khi cần thiết.
DCxB1=...; //Nếu sử dụng PWM 8 bit thì có thể bỏ qua DCxB0=...; //Nếu sử dụng PWM 8 bit thì có thể bỏ qua Bước 5: Khởi tạo và cho phép timer 2 hoạt động:
TMR2IF=0; //Xóa cờ ngắt TMR2IF của thanh ghi PIR1 //Chọn tỉ lệ bộ chia của timer 2:
T2CKPS1=...; //Chọn tỉ lệ bộ chia Prescaler T2CKPS0=...;
TOUTPS3=....; //Chon tỉ lệ bộ chia Postscaler TOUTPS2=....; TOUTPS1=....; TOUTPS0=....; TMR2ON=1; //Cho phép timer 2 hoạt động Bước 6: Cho phép ngõ ra PWM sau khi chu kỳ PWM mới được bắt đầu: while(TMR2IF); // Chờ cho đến khi timer 2 tràn (bit TMR2IF của thanh ghi PIR1 được bật lên 1)
TRISCx = 0; //x = 1, 2.
5.3. BÀI TẬP THỰC HÀNH
Bài 1: Viết chương trình tạo xung PWM có tần số 20KHz ở hai chân: CCP1(RC2) và CCP2(RC1) với độ rộng xung CCP1 là 50% xung, CCP2 là 80% xung.
* Bước 1:Tạo một project mới với tên 04_01_ MSSV
* Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu
…….
#include <htc.h>
__CONFIG(INTIO&WDTDIS &MCLREN &BORDIS &LVPDIS);
void main()
{
//Khởi tạo tần số 20Khz PWM (timer 2)
PR2=…….; //Chọn tần số 20KHz
T2CKPS1=T2CKPS0=…….; //Bộ chia Prescales 1:1 //Bộ chia Postcales1:1
TOUTPS3=TOUTPS2=TOUTPS1=TOUTPS0=…….; //Khởi tạo khối CCP1
TRISC2=…….; //Disable ngõ ra của chân CCP1
CCP1CON=0b00001100; //(---1---)
CCPR1L=…….;//Tạo PWM 50% xung ỡ chân CCP1(---2---)
TMR1IF=…….; //Xóa cờ ngắt của khốiCCP1
// Khởi tạo khối CCP2
TRISC1=…….; // Disable ngõ ra của chân CCP1
CCP2CON=0b00001100;// Khởi tạo module CCP2 chế độ PWM
CCPR2L=…….;//Tạo xung PWM 80% ở chân CCP2(---3---)
TMR2IF=…….; // Xóa cờ ngắt của khối CCP2 //Cho phép timer 2 hoạt động bắt đầu tạo xung PWM
TMR2ON =…….; //Cho phép timer 2 hoạt động
TRISC2 =…….; //Cho phép chân CCP1 là ngõ ra TRISC1 =…….; //Cho phép chân CCP2 là ngõ ra.
while(1);
}
* Bước 3: Nạp chương trình vào kit thí nghiệm, dùng oscillocope đo tín
* Bước 4: Thay đổi dòng (---1---) thành đoạn code sau:
CCP1CON=0b00001111;
Biên dịch chương trình nạp vào kít, dùng oscillocope đo ngõ ra PWM chân CCP1, quan sát xung được tạo ra, nhận xét sự khác nhau giữa xung trước và sau khi thay đổi code, và giải thích sự khác nhau đó. ……… ……… ……… ……… ……… ……… ……… ……… ……… ……… ……… ………
* Bước 5: Tính toán giá trị thanh ghi CCPR1L cho CCP1 tạo ra PWM
90%.
Tính toán giá trị thanh ghi CCPR2L cho CCP2 tạo ra PWM 10%. Thay vào (---2---) và (---3---), biên dịch chương trình, nạp xuống kít thí nghiệm, sử dụng oscillocope đo ngõ ra xung và hoàn thành vào bảng sau:
PWM 90% PWM 10%
CCPR1L CCPR2L
Bài 2: Viết chương trình điều khiển tốc độ động cơ sử dụng IC chuyên dụng L298 theo yêu cầu sau: (Tạo một project mới với tên 04_02_ MSSV)
Nhấn RB0 tốc độ động cơ tăng dần (mỗi lần nhấn tăng 10% độ rộng xung).
Nhấn RB1 tốc độ động cơ giảm dần (mỗi lần nhấn giảm 10% độ rộng xung).
Với PWM tần số 10Khz, độ phân giải 8 bit, thạch anh nội 4MHz. Phần cứng:
* Bước 1: Tạo một project mới với tên 04_02_ MSSV
* Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu
…….
#include <htc.h>
__CONFIG(INTIO&WDTDIS &MCLREN &BORDIS &LVPDIS); void main()
{
ANSEL=ANSELH=…….; //Tắt chức năng xử lý analog
TRISB=…….; //Khởi tạo PORTB là ngõ vào PORTB=…….;
WPUB=…….; //Cho phép điện trở treo tất cả PORTB
RBPU=…….;
IOCB =…….; //Cho phép ngắt on-change cả PORTB
RBIE =…….; //Enable ngắt on-change ở PORTB
RBIF =…….; //Xóa cờ ngắt on-change GIE =…….; //Cho phép ngắt toàn cục
TRISE0=…….;//Khởi tạo chân RE0 là ngõ ra, mức cao
RE0 =…….;
PR2 =…….; //tần số 10KHz
CCP1CON=0x0C; //Khởi tạo chế độ PWM cho module CCP1
CCP2CON=0x0C; //Khởi tạo chế độ PWM cho module CCCP2
CCPR1L=0; CCPR2L=0; TRISC2=….; TRISC1=….; while(1) { } }
void interrupt isr()
{ if(RBIE&&RBIF) { if(!RB0) { CCPR1L+=10; CCPR2L+=10; TMR2ON=1; } if(!RB1) { CCPR1L-=10; CCPR2L-=10; TMR2ON=1; } if(!RB2) {
TRISC2^=1; TRISC1=~TRISC2; TMR2ON=1; } RBIF=0; } }
* Bước 3: Jum header CCP2 (J2), biên dịch chương trình nạp xuống kít
thí nghiệm, kết nối động cơ và cấp nguồn cho L298, tiến hành nhấn nút và quan sát kết quả.
5.4. BÀI TẬP TỰ GIẢI
* Bài 3: Viết chương trình sử dụng chức năng capture đo tần số ở chân CCP1(RC2) và hiển thị giá trị đó lên LCD theo sơ đồ phần cứng sau (Tạo một project mới với tên 04_03_ MSSV)
* Bài 4: Viết chương trình tạo xung PWM 8 bit ở chân CCP2(RC1) với tần số 15 KHz theo yêu cầu sau (Tạo một project mới với tên
04_04_ MSSV)
Nhấn nút nhấn(không giữ) ở chân RB0 lần 1:Độ rộng xung 15%. Nhấn nút nhấn(không giữ) ở chân RB0 lần 2:Độ rộng xung 30%. Nhấn nút nhấn(không giữ) ở chân RB0 lần 3:Độ rộng xung 45%.
Nhấn nút nhấn(không giữ) ở chân RB0 lần 4:Độ rộng xung 60%. Nhấn nút nhấn (không giữ) ở chân RB0 lần 5: Độ rộng xung 75%. Nhấn nút nhấn (không giữ) ở chân RB0 lần 6: Độ rộng xung 90%. Nhấn nút nhấn (không giữ) ở chân RB0 lần 7: Trở lại trạng thái nhấn lần 1.
* Bài 5: Viết chương trình theo yêu cầu sau (Tạo một project mới với
tên 04_05_ MSSV):
Nhấn RB0 động cơ quay cùng chiều kim đồng hồ, PWM 10Khz, độ rộng xung 90%.
Nhấn RB1 động cơ quay ngược chiều kim đồng hồ, PWM 15Khz, độ rộng xung 70%.
Chương VI
GIAO TIẾP NỐI TIẾP BẤT ĐỒNG BỘ
Sau khi học xong chương này, sinh viên đạt được những kiến thức sau: a. Giải thích nguyên lý truyền nhận tín hiệu UART.
b. So sánh được sự khác biệt giữa truyền nhận nối tiếp và truyền nhận song song.
c. Trình bày được khái niệm: baud, start bit, stop bit, frame truyền, parity.
d. Thiết lập được phần cứng cho vi điều khiển hoạt động chế độ UART.
e. Liệt kê được các thanh ghi liên quan truyền nhận UART.
f. Thiết lập các bit cho vi điều khiển truyền nhận dữ liệu qua chuẩn UART ở chế độ 8 bit, và chế độ 9 bit.
6.1. DỤNG CỤ THÍ NGHIỆM Kít thí nghiệm + cáp USB. Kít thí nghiệm + cáp USB. Động cơ DC12V. Oscillocope. Máy tính. Nguồn 12V/1A. 6.2. CƠ SỞ LÝ THUYẾT
Các chân liên quan đến chức năng giao tiếp nối tiếp: