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.. Input Register PxIN: Đây là các thanh ghi 8 bit chứa giá trị đọc được từ các chân PO
Trang 1
ĐẠ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Ý
NHÓM 20.38B
Giáo viên hướng dẫn:
ThS.Trần Văn Líc
Sinh viên thực hiện : Nguyễn Ngọc Huy-106200019
Nguyễn Đình Phúc-106200031 Nguyễn Văn Trọng-106200041
Trang 2
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
1.3 Output Register (PxOUT):
Đâ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 3
Bà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
Hình 1.1 Sơ đồ nguyên lý kết nối LED1 và LED2 với MSP430G2553
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: LED1 nối vào chân 2 của MCU Cổng P1.0
+ LED2 nối vào chân nào của MCU? (Cổng (Port) nào?)
Trả lời: LED2 nối vào chân 14 Cổng P1.6
+ Để điều khiển LED, các chân port phải là input hay output?
Trả lời: Các chân port là Output
+ Để LED sáng, phải xuất giá trị gì ra chân port?
Trả lời: LED sáng phải xuất ra giá trị 1 ra chân port
Trang 4
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 "msp430.h"
int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset P1DIR |= BIT0 +BIT6;
P1OUT &=~BIT0 +BIT6;
P1OUT |= BIT0; // P1.0=1
while(1)
{
int i=10000;
do(i );
while(i!=0);
{
P1OUT^= BIT6 +BIT0; //Toggle Port P1.0 and P1.6
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 SW1 được
nhấn
Trang 5
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: SW1 nối vào 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: SW2 nối vào 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 <msp430.h>
int main(void) {
volatile unsigned int i;
WDTCTL = WDTPW | WDTHOLD;
P1DIR |= BIT0;
P1REN |= BIT3;
P1OUT |= BIT3;
while (1) {
while (P1IN & BIT3);
for( i=0;i<10000;i++);
P1OUT ^= BIT0;
while (!(P1IN & BIT3));
for( i=0; i<10000;i++);
}
Trang 6
}
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
▪ Bit = 1: Một ngắt đang chờ xử lý
▪ Bit = 0: Không có ngắt nào đang chờ
Trang 7Bài 2.1
Yêu cầu: Sinh viên viết chương trình đảo trạng thái LED1 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
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
+ SW2 nối vào chân Port gì của CPU?
Trả lời: SW2 nối vào chân Port 1.3
+ Khi Switch được nhấn, sẽ có chuyển trạng thái như thế nào trên chân PORT?
Trả lời: Switch được nhấn, chuyển trạng thái trên chân Port từ High sang Low
+ Để cho phép ngắt trên chân P1.3, 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.3, 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;
Trang 8P1DIR &= ~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
P1IE |= BIT3;
P1IES |= BIT3;
_BIS_SR(GIE);
} #pragma vector=PORT1_VECTOR
interrupt void Port_1(void){
if((P1IN & BIT3)){ 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 1 đượ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){
if (blink_status == 1) {
// Infinite loop
P2OUT ^= 0x04; // Toggle Port P2.2 i=15000;
do (i‐‐);
while (i !=0);
}
// Delay
if (!(P1IN & 0x01)) {
// Detect S1 pressed
i=1500;
do (i‐‐);
while (i !=0);
// Delay, button debounce
while (!(P1IN&0x01)); // Wait for the release of the
button
do (i‐‐);
while (i !=0);
if (blink_status ==1){ // If led is blinking, stop it P2OUT&= _ 0x04; // 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 )
{
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0; // P1.0 Output
P1OUT &= ~BIT0; //Set P1.0 as input
P1DIR &= ~BIT3; // Set P1.3 as input
P1REN |= BIT3; //Enable pull-up resistor on P1.3
P1OUT |= BIT3; // Set pull-up resistor on P1.3
while(1)
{
if(blink_status == 1)
{
P1OUT ^= BIT0;
delay_cycles(500000);
}
else
{
P1OUT &= ~BIT0;
Trang 10}
if(!(P1IN & BIT3))
{
while (!(P1IN & BIT3));
if(blink_status == 1)
{
blink_status = 0;
}
else
{
blink_status = 1;
}
delay_cycles(100000);
}
}
return 0;
}
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 Swich
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 )
{
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0 ;
P1OUT &= ~BIT0 ;
P1DIR &= ~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
P1IE |= BIT3; // Interrupt Enable
Trang 11P1IES |= BIT3; // Interrupt flag high-to-low
_BIS_SR(GIE); // Low Power Mode with interrupts enabled
while(1)
{
if(blink_status == 1)
{
P1OUT ^= BIT0;
delay_cycles(500000);
}
else
{
P1OUT &= ~BIT0;
}
}
return 0;
}
#pragma vector=PORT1_VECTOR
interrupt void Port_1(void)
{
while(!(P1IN & BIT3));
if(blink_status == 1)
{
P1OUT &= ~BIT0;
blink_status = 0;
}
else
{
blink_status=1;
}
delay_cycles(100000);
P1IFG &= ~BIT3; //Clean P1.0 Interrupt Flag
}
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 1 đượ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> //khai bao thu vien
unsigned char blink_status = 1;
void main(void)
{
volatile unsigned int i;
Trang 12WDTCTL = WDTPW + WDTHOLD;//stop WDT
P1DIR |= BIT0 + BIT6; //khai bao chan P1.0 P1.6 la output
P1OUT &= ~BIT6;
P1OUT |= BIT0;
P1DIR &= ~BIT3;//khai bao chan P1.3 la input
P1REN |= BIT3; // cho phep dien tro keo
while (1)
{
if (blink_status ==1)
{
P1OUT &= ~BIT6; //tat LED2
P1OUT ^= BIT0; //LED1 nhay
delay_cycles(500000);
}
else
{
P1OUT &= ~BIT0; //tat LED1
P1OUT ^= BIT6; //LED2 nhay
delay_cycles(500000);
}
if(!(P1IN&BIT3)) //Neu S2 duoc nhan
{
while((P1IN&BIT3)){} //cho cho den khi da nhan nut xong
if (blink_status ==1)
{
blink_status = 0;
}
else
{
blink_status = 1;
}
}
}
}
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 1 đượ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
Trang 13Viết chương trình vào đây :
#include "msp430g2553.h"
unsigned int blink_status = 1;
int main( void )
{
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0 | BIT6;
P1DIR &= ~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
P1IE |= BIT3;
P1IES |= BIT3;
_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;
}