BỘ GIÁO DỤC & ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA ĐẠI HỌC ĐÀ NẴNG KHOA ĐIỆN TỬ VIỄN THÔNG BÁO CÁO THÍ NGHIỆM KỸ THUẬT VI XỬ LÝ Thành viên NGUYỄN TRÂM ANH – 20DT1 ĐÀM THỊ ÁI NHI – 20DT1 NGUYỄN ĐÌNH TH[.]
Trang 1BỘ GIÁO DỤC & ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA-ĐẠI HỌC ĐÀ NẴNG KHOA ĐIỆN
TỬ-VIỄN THÔNG
BÁO CÁO THÍ NGHIỆM
KỸ THUẬT VI XỬ LÝ
Thành viên : NGUYỄN TRÂM ANH – 20DT1
: ĐÀM THỊ ÁI NHI – 20DT1 : NGUYỄN ĐÌNH THUẬN – 20DT2
Lớp HP : 20N38C
GVHD : ThS TRẦN VĂN LÍC
Đà Nẵng, tháng 3 năm 2023
Trang 2Các bài thí nghiệm
Bài 1: GPIO
1 Các thanh ghi liên quan đến GPIO:
1.1 Direction Register PxDIR (P1DIR, P2DIR):
Đây là các thanh ghi 8 bit điều khiển chiều của 8 chân port P1DIR điều khiển PORT1, P2DIR điều khiển PORT2
Bit = 1: Chân PORT tương ứng được cấu hình thành output
Bit = 0: Chân PORT tương ứng được cấu hình thành input
1.2 Input Register (PxIN):
Đây là các thanh ghi 8 bit chứa giá trị đọc được từ các chân
PORT Bit = 1: Chân PORT tương ứng ở mức cao
Bit = 0: Chân PORT tương ứng ở mức thấp
Đây là thanh ghi điều khiển ngõ ra của các PORT
Bit = 1: Xuất mức cao ra chân PORT tương ứng
Bit = 0: Xuất mức thấp ra chân PORT tương ứng
1.4 Function Select Register:
Đây là thanh ghi chọn chức năng cho chân PORT Mỗi chân PORT có thể cấu hình chọn chức năng Input/Output hay là chức năng đặc biệt khác
Bit = 1: Chọn chức năng đặc biệt
Bit = 0: Chọn chức năng GPIO
2 Các lưu ý khi viết chương trình cho lab này:
2.1 Watchdog Timer:
Trong lab này, chúng ta không cần sử dụng Watchdog timer Để tắt Watchdog timer, ghi giá trị 5A vào 8 bit cao của thanh ghi WDTCTL và set thứ 7 của thanh ghi WDTCTL
WDTCTL = 0x5A00 | 0x0080 Hoặc:
(WDTCTL = WDTPW | WDTHOLD)
2.2 Delay:
Bởi vì trong chương trình chưa định nghĩa clock nên CPU sẽ sử dụng thạch anh 32.768 kHz Để có thời gian delay khoảng 1s, vòng delay sẽ đếm xuống từ 30.000SV có thể dùng câu lệnh dưới đây để tạo delay:
for(int i=30000;i>0;i++);
Trang 3Bài 1.1
Yêu cầu: Sinh viên viết chương trình cho LED1 và LED2 sáng tắt luân phiên Thời gian
giữa 2 lần sáng tắt là khoảng 1s
Câu hỏi 1: Các LED được kết nối với MCU như hình trên Điền vào chỗ trống để trả lời các câu hỏi dưới đây
+ LED1 nối vào chân nào của MCU? (Cổng (Port) nào?) Trả lời: ………
P1.0………
+ LED2 nối vào chân nào của MCU? (Cổng (Port) nào?) Trả lời: ………
P1.6………
+ Để điều khiển LED, các chân port phải là input hay output? Trả lời: ………
Output………
+ Để LED sáng, phải xuất giá trị gì ra chân port? Trả lời: ………P1OUT = BIT 0 + BIT 6………
Câu hỏi 2: Hoàn chỉnh chương trình bằng cách điền vào các chỗ trống:
#include <msp430g2553.h>
int main(void)
{
/ Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0 + BIT6;
P1OUT &=~BIT0 + BIT6;
P1OUT |= BIT0
while(1)
{
int i=10000;
Trang 4while(i!=0);
{
P1OUT^= BIT6 + BIT0;
delay_cycles(1000000);
}
}
}
Bài 1.2
Yêu cầu: Sinh viên viết chương trình để đảo trạng thái LED1 mỗi khi S2 được nhấn.
Câu hỏi 1: Các SW(switch) được kết nối với MCU như hình trên Điền vào chỗ trống để trả lời các câu hỏi dưới đây
+ SW1 nối vào chân nào của MCU? (Cổng (Port) nào?) Trả lời: Chân 16 của MCU, cổng RST/SBWTDIO
+ SW2 nối vào chân nào của MCU? (Cổng (Port) nào?) Trả lời: Chân 5 của MCU, cổng P1.3
+ Để đọc trạng thái switch, các chân port phải là input hay output? Trả lời:
………Input………
Câu hỏi 2: Hoàn chỉnh chương trình bằng cách điền vào các chỗ trống:
#include <msp430g2553.h>
int main(void)
{
/ Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW | WDTHOLD;
P1DIR |= BIT0;
P1REN |= BIT3;
Trang 5P1OUT |= BIT3;
while (1)
{
if (!(P1IN & BIT3)) // kiem tra neu S2 duoc nhan
{
P1OUT ^= BIT0;
delay_cycles(500000);
}
}
}
Bài 2 GPIO & INTERRUPT
MSP430 được thiết kế để làm việc với các ứng dụng công suất thấp Vì vậy CPU thường
ở trạng thái “off” trong phần lớn thời gian Để đưa CPU vào trạng thái “off”, các bit SCG1, SCG0 và CPUOFF trong thanh ghi SR được set
Một ngắt xảy ra sẽ đánh thức CPU Khi đó thanh ghi SR được lưu vào stack và CPU thực thi ISR Khi thoát khỏi ISR, thanh ghi SR được lấy ra từ stack và làm cho CPU tắt trở lại
Đưa CPU vào trạng thái công suất thấp và cho phép ngắt:
Bit GIE trong thanh ghi SR khi được set sẽ cho phép ngắt
Ta đưa CPU vào trạng thái công suất thấp, cho phép ngắt bằng lệnh:
_BIS_SR (LPM3_bits + GIE);
Trong đó:
LPM3_bits = (SCG1+SCG0+CPUOFF)
Định nghĩa chương trình phục vụ ngắt (ISR):
Ta định nghĩa 1 ISR tại vector ngắt ISR_VECTOR bằng cấu trúc sau:
#pragma vector=ISR_VECTOR interrupt void myISR (void)
{
………
}
1.5 Các thanh ghi cấu hình ngắt cho các chân PORT:
Mỗi chân PORT của MSP430 đều có thể dùng để tạo ngắt Các ngắt này được cấu hình thông qua các thanh ghi PxIFG, PxIE, PxIES
1.5.1 Interrupt enable Register (PxIE):
Mỗi bit trong thanh ghi này dùng để cho phép/không cho phép ngắt trên chân PORT tương ứng
Bit = 1: Cho phép ngắt
Bit = 0: Cấm ngắt
1.5.2 Interrupt Edge Select Registers (PxIES):
Dùng để chọn cạnh của tín hiệu ngắt
Bit = 1: Ngắt tại cạnh xuống của tín hiệu
Bit = 0: Ngắt tại cạnh lên của tín hiệu
1.5.3 Interrupt Flag Registers (PxIFG):
Thanh ghi này chứa các cờ ngắt Các cờ này được tự động bật bởi phần cứng, phải được xóa bằng phần mềm Các cờ này có thể được bật bằng phần mềm để cho phép ngắt
Trang 6Bit = 1: Một ngắt đang chờ xử lý.
Bit = 0: Không có ngắt nào đang chờ
Bài 2.1
Yêu cầu: Sinh viên viết chương trình đảo trạng thái LED1 khi Switch 2 được nhấn.
Trong chương trình sử dụng ngắt trên chân port giao tiếp Switch
Trang 7Câu hỏi 1: Các SW(switch) được kết nối với MCU như hình trên Điền vào chỗ trống để trả lời các câu hỏi dưới đây
+ SW2 nối vào chân Port gì của CPU?
Trả lời: ………P1.3………
+ Khi Switch được nhấn, sẽ có chuyển trạng thái như thế nào trên chân PORT?
+ Để cho phép ngắt trên chân P1.0, ta phải ghi P1IE |= BIT3 vào bit 3 của thanh ghi P1IE + Để chọn cạnh xuống cho ngắt trên chân P1.0, ta phải ghi P1IES |= BIT3 vào bit 3 của thanh ghi P1IES
Câu hỏi 2: Hoàn chỉnh chương trình bằng cách điền vào các chỗ trống:
#include "msp430g2553.h"
int main( void )
{
/ Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0;
P1OUT |= BIT0;
P1DIR &= ~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
P1IE |= BIT3;
P1IES |= BIT3;
_BIS_SR(GIE);
Trang 8#pragma vector=PORT1_VECTOR
interrupt void Port_1(void){
while (!(P1IN & BIT3));
delay_cycles(500000);
P1OUT ^= BIT0;
P1IFG &= ~BIT3;
}
Bài 2.2
Yêu cầu: Sinh viên viết chương trình cho phép/không cho phép LED1 nhấp nháy khi
Switch 2 được nhấn
Hướng dẫn:
Để thực hiện bài thí nghiệm này, sinh viên cần thực hiện việc cấu hình cho các cổng I/O, thiết lập các đường ngõ vào để đọc tín hiệu từ các nút nhấn và ngõ ra để điều khiển LED1 Sinh viên có thể sử dụng một số gợi ý sau đây để viết chương trình
Để phát hiện nút nhấn có được nhấn hay không, sử dụng cấu trúc lệnh:
if ( !P1IN & 0x01)
Sau đó khai báo một biến điều khiển chương trình phát hiện LED nhấp nháy hay không, khi nút được nhấn:
Định nghĩa biến chỉ thị khi LED đang
nháy: Unsigned char blink_status = 1;
Thiết lập chương trình hoạt động phụ thuộc vào trạng thái của biến
Trang 9while(1){ // Infinite loop
if (blink_status == 1) {
P2OUT ^= 0x04;
i=15000; // Toggle Port P2.2// Delay
do (i‐‐);
while (i !=0);
}
if (!(P1IN & 0x01)) {
i=1500; // Detect S1 pressed// Delay, button debounce
do (i‐‐);
while (i !=0);
while (!(P1IN &
0x01)); i=1500; button // Delay, button debounce// Wait for the release of the
do (i‐‐);
while (i !=0);
if (blink_status ==1)
{ P2OUT&= _ 0x04; // If led is blinking, stop it
// Turn Led off blink_status=0;
}else
blink_status=1;
Viết chương trình vào đây:
#include "msp430g2553.h"
unsigned int blink_status = 1;
int main( void )
{
/ Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0;
P1OUT |= BIT0;
P1DIR &= ~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
while(1){
if(blink_status == 1){
P1OUT ^= BIT0; // Dao trang thai P1.0
delay_cycles(500000);
}else {
P1OUT &= ~BIT0; // Tat den led 1
}
if(!(P1IN & BIT3)){ // Kiem tra neu S2 duoc nhan
delay_cycles(5000000);
while (!(P1IN & BIT3));
if(blink_status == 1){ // cho phep nhay led 1
P1OUT &= ~BIT0; // Tat den led 1
blink_status = 0;
Trang 10}else {
blink_status = 1;
}
delay_cycles(100000);
}
}
}
Bài 2.3
Yêu cầu: Sinh viên viết chương trình cho phép/không cho phép LED1 nhấp nháy khi
Switch 1 được nhấn Trong chương trình sử dụng ngắt trên chân port giao tiếp Switch
Hướng dẫn: Sinh viên vận dụng kiến thức và các hướng dẫn đã có trong bài 2.1 và 2.2
để viết chương trình
Viết chương trình vào đây:
#include "msp430g2553.h"
unsigned int blink_status = 1;
int main( void )
{
/ Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0 ;
P1OUT &= ~BIT0 ;
P1DIR &= ~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
P1IE |= BIT3;
P1IES |= BIT3;
_BIS_SR(GIE);
while(1){
if(blink_status == 1){ // cho phep nhay led 1
P1OUT ^= BIT0; // Dao trang thai P1.0
delay_cycles(500000);
}else {
P1OUT &= ~BIT0; // Tat den led 1
}
}
}
#pragma vector=PORT1_VECTOR
interrupt void Port_1(void){
while(!(P1IN & BIT3));
if(blink_status == 1){
P1OUT &= ~BIT0;
blink_status = 0;
Trang 11}else {
blink_status=1;
}
delay_cycles(100000);
P1IFG &= ~BIT3;
}
Bài 2.4
Yêu cầu: Sinh viên viết chương trình cho phép LED1 và không cho phép LED2 nhấp
nháy khi Switch 2 được nhấn, không cho phép LED1 và cho phép LED2 nhấp nháy khi Switch 2 được nhấn
Hướng dẫn: Sinh viên vận dụng kiến thức và các hướng dẫn đã có trong bài 2.1 và 2.2
để viết chương trình
Viết chương trình vào đây :
#include "msp430g2553.h"
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
P1DIR |= BIT0 | BIT6; // Set P1.0 and P1.6 as output
P1DIR &= ~BIT3; // Set P1.3 as input
P1REN |= BIT3; // Enable pull-up resistor for P1.3
int blink_led1 = 0; // Flag to enable/disable blinking for
LED1 int blink_led2 = 0; // Flag to enable/disable blinking
for LED2 while(1) {
if (!(P1IN & BIT3)) { // Check if button 1 is pressed
delay_cycles(10000); // Delay for button debounce
if (!(P1IN & BIT3)) { // Check if button 1 is still pressed
if (blink_led1) {
blink_led1 = 0; // Disable blinking for LED1
11
P1OUT &= ~BIT0; // Turn off LED1
blink_led2 = 1; // Enable blinking for LED2
}else {
blink_led1 = 1; // Enable blinking for LED1
blink_led2 = 0; // Disable blinking for LED2
Trang 12}
while (!(P1IN & BIT3)); // Wait for button 1 release
}
if (blink_led1) { // If flag for LED1 is set, blink LED1
P1OUT ^= BIT0; // Toggle P1.0
delay_cycles(100000); // Delay for LED1 blink
}else {
P1OUT &= ~BIT0; // Turn off LED1
}
if (blink_led2) { // If flag for LED2 is set, blink LED2
P1OUT ^= BIT6; // Toggle P1.6
delay_cycles(50000); // Delay for LED2 blink
}else {
P1OUT &= ~BIT6; // Turn off LED2
}
}
}
Bài 2.5
Yêu cầu: Sinh viên viết chương trình cho phép LED1 và không cho phép LED2 nhấp
nháy khi Switch 2 được nhấn, không cho phép LED1 và cho phép LED2 nhấp nháy khi Switch 2 được nhấn Trong chương trình sử dụng ngắt trên chân port giao tiếp Switch
Hướng dẫn: Sinh viên vận dụng kiến thức và các hướng dẫn đã có trong bài 2.1 và 2.2
để viết chương trình
Viết chương trình vào đây:
#include "msp430g2553.h"
unsigned int blink_status = 1;
int main( void )
{
/ Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0 + BIT6;
P1OUT |= BIT0 + BIT6;
/* setup GPIO cho nut nhan P1.3 */
Trang 13P1DIR &= ~BIT3; // P1.3 la input
P1REN |= BIT3; // cho phep dien tro keo
P1OUT |= BIT3; // dien tro keo len nguon
P1IE |= BIT3; // cho phep ngat tai P1.3
P1IES |= BIT3; // chon tin hieu ngat la suon xuong (high-to-low)
_BIS_SR(GIE);
while(1){
if(blink_status == 1){
P1OUT ^= BIT0;
P1OUT |= BIT6;
delay_cycles(500000);
}
else {
P1OUT |= BIT0;
P1OUT ^= BIT6;
delay_cycles(500000);
}
}
}
#pragma vector=PORT1_VECTOR
interrupt void Port_1(void){
while(!(P1IN & BIT3));
if(blink_status == 1){
blink_status = 0;
}
else {
blink_status=1;
}
delay_cycles(100000);
P1IFG &= ~BIT3;
}