Professional Documents
Culture Documents
THỰC HÀNH
HỆ THỐNG NHÚNG
Ấn bản 2016
MỤC LỤC I
MỤC LỤC
MỤC LỤC .................................................................................................................. 1
HƯỚNG DẪN ............................................................................................................. 2
HƯỚNG DẪN
MÔ TẢ MÔN HỌC
Thực hành Hệ thống nhúng là môn học hỗ trợ cho môn Hệ thống nhúng. Môn học
này thực hiện các mạch phần cứng và viết chương trình phần mềm để thực hiện một
hệ thống nhúng.
− Điểm quá trình: 30%. Hình thức và nội dung do Giáo viên quyết định, phù hợp với
quy chế đào tạo và tình hình thực tế tại nơi tổ chức học tập.
− Điểm thi: 70%. Hình thức thực hành trên board thí nghiệm và nộp báo cáo thí
nghiệm.
BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
1
1.1 Qsys
Trong bài này, Qsys dùng để tạo ra hệ thống bao gồm một bộ xử lý Nios II/e và một
khối bộ nhớ. Bộ vi xử lý Nios II/e xử lý dữ liệu. Khối bộ nhớ lưu trữ chương trình và dữ
liệu.
Click vào biểu tượng Qsys hay chọn menu Tools > Qsys để tạo hệ thống Nios II.
2 BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
Click File > Save và đặt tên là de2_blinker. Nhấn chuột phải vào clk_0, chọn
Rename và đổi tên thành clock_main.
Sử dụng Qsys để tạo ra hệ thống niosii_sys, bao gồm các thành phần sau:
Bộ xử lý Nios II/e
− Click Add. Xuất hiện hộp thoại cấu hình thông số cho Nios II.
− Chọn Finish.
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 4 errors.
On-chip memory – RAM: Bộ nhớ trên chip, chế độ RAM với kích thước bộ nhớ
là 30 KB và độ rộng dữ liệu là 32 bits.
4 BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
− Trong hộp thoại Total memory size, gõ vào 32K. Sau đó nhấn Finish.
BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
5
− Đổi tên onchip_memory2_0 thành onchip_memory.
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 6 errors và 1 warning.
Các PIO:
− Thêm vào PIO thứ hai với các thông số Width = 2, Direction là Output và đổi
tên thành led.
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 12 errors và 6 warnings.
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 7 errors và 6 warnings.
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 2 errors và 6 warnings.
Onchip_memory > s1
Switcher > s1
Led > s1
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 8 errors và 2 warnings.
Onchip_memory > s1
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 10 errors và 2 warnings.
Ghi chú: phía dưới cửa sổ lúc này sẽ có thông báo 2 errors và 2 warnings.
− Click Finish.
Tạo hệ thống.
− Click Exit. Quay trở lại giao diện thiết kế của Quartus.
10 BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
− Nhấn vào nút ... và chọn file de2_blinker trong thư mục
..\de2_blinker\synthesis.
− Nhấn Add. Sau đó thực hiện Add tất cả các file trong thư mục submodules. Nhấn
OK.
− Chọn menu Processing > Start Compilation hay nhấn vào nút Start
Compilation
− Trên hàng clk_clk, double click vào cột Location và nhập vào PIN_N2.
− Đóng cửa sổ Pin Planner và thực hiện biên dịch lại (chọn menu Processing >
Start Compilation).
BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
13
− Chọn menu Tools > Programmer, bấm vào nút Hardware Setup ở góc trên bên
trái và chọn USB-Blaster.
14 BÀI 1: HỆ THỐNG NHÚNG ĐƠN GIẢN
− Trong cửa sổ Programmer phải có tên file .sof (nếu chưa có thì nhấn vào nút
Add File để thêm vào).
− Gạt nút RUN / PROG trên kit DE2 (nằm bên trái LCD) sang RUN và nhấn vào
Start để cấu hình cho DE2.
− Trong Eclipse, chọn menu File > New > Nios II Application and BSP from
Template.
− Từ Project Explorer (bên trái), click chuột phải vào app_to_board, chọn New
> Source File.
#include "io.h"
#include "system.h"
− Nhấn chuột phải vào app_to_board, chọn Run As > Run Configurations.
− Trong Tab Target Connection, nhấn vào Refresh Connection (bên phải)
− Click chọn vào các check box Ignore mismatched system ID và Ignore
mismatched system timestamp.
− Dùng các công tắc SW0 và SW1 để kiểm tra LEDR0 và LEDR1.
- Chọn menu File > New, sau đó chọn Block Diagram/Schematic File.
- Nhấn chuột phải vào file de2_blinker.bdf và chọn Set as Top-Level Entity.
- Tiếp tục quá trình nạp xuống phần cứng như 1.2 và nạp phần mềm như 1.3.
Bài 1.1: Viết lại đoạn mã để LEDR0 sáng khi SW0 on và SW2 on, LEDR1 sáng khi
SW0 on và SW1 on.
Bài 1.2: Sửa lại phần cứng để điều khiển LEDG0 và LEDG1.
Bài 1.3: Sửa lại phần cứng để điều khiển cho 8 Led LEDR0 – LEDR7.
BÀI 2: ĐIỀU KHIỂN XUẤT/NHẬP
19
− Bộ xử lý Nios II/e với JTAG Debug Module Level 1 và các tùy chọn: Embedded
Multipliers for Hardware Multiply, Hardware Divide.
− PIO ngõ vào 8 bit (đặt tên là new_number), gán cho 8 công tắc SW0 – SW7.
− PIO ngõ ra 8 bit (đặt tên là LED_green), gán cho LEDG0 – LEDG7.
− PIO ngõ ra 16 bit (đặt tên là LED_red), gán cho LEDR0 – LEDR15.
− Dùng Nios II Software Buile Tools for Eclipse để viết phần mềm cho Nios II
như sau:
#include "io.h"
#include "system.h"
void main() {
unsigned char sw = 0x00;
while (1) {
sw = IORD(NEW_NUMBER_BASE, 0);
IOWR(LED_GREEN_BASE, 0, sw);
}
}
Bài 2.2: Thêm vào phần cứng PIO với các thông số Width = 1, Direction là Input,
click chọn Synchnously capture và chọn Edge Type là FALLING (đặt tên PIO là accept
và gán cho phím KEY0). Viết chương trình nhận giá trị trên các SW0 – SW7, hiển thị
20 BÀI 2: ĐIỀU KHIỂN XUẤT/NHẬP
trên các LED xanh, nếu có nhấn phím KEY0 thì cộng giá trị hiện tại trên LED đỏ và
giá trị vừa nhập, sau đó hiện giá trị tổng trên LED đỏ.
− Dùng Nios II Software Buile Tools for Eclipse để viết phần mềm cho Nios II
như sau:
#include "io.h"
#include "system.h"
void main() {
unsigned char sw = 0x00;
unsigned char accept = 0xFF;
unsigned int red = 0;
while (1) {
sw = IORD(NEW_NUMBER_BASE, 0);
IOWR(LED_GREEN_BASE, 0, sw);
accept = IORD(ACCEPT_BASE,0);
if (!accept)
{
red = red + (unsigned int)sw;
while (!accept)
accept = IORD(ACCEPT_BASE,0);
}
IOWR(LED_RED_BASE,0,red);
}
Xóa đoạn in đậm và thực thi lại để so sánh.
Bài 2.3: Thêm vào phần cứng 6 LED 7 đoạn (HEX0 – HEX5) và hiện giá trị hex của
SW0 – SW7 trên HEX5 – HEX4, giá trị tổng hiện trên HEX3 – HEX0.
Bài 2.4: Thực hiện tương tự bài 2.3 nhưng hiện giá trị dạng thập phân. Nếu giá trị
vượt quá 99 hay 9999 thì hiện EE hay EEEE.
BÀI 3: HỎI VÒNG VÀ NGẮT
21
− Bộ xử lý Nios II/e với JTAG Debug Module Level 1 và các tùy chọn: Embedded
Multipliers for Hardware Multiply, Hardware Divide.
− PIO ngõ vào 8 bit (đặt tên là switches), gán cho 8 công tắc SW0 – SW7.
− PIO ngõ ra 8 bit (đặt tên là LED_green), gán cho LEDG0 – LEDG7.
− PIO ngõ vào 4 bit (đặt tên là keys), gán cho KEY0 – KEY3, chọn thông số như hình:
Bài 3.1: Viết chương trình kiểm tra 4 công tắc KEY0 – KEY3, nếu có 1 phím được
nhấn thì đọc nội dung của các công tắc SW0 – SW7, hiển thị giá trị tương ứng trên
các LED xanh.
#include "io.h"
#include "system.h"
void main() {
int * switches_ptr = (int *)SWITCHES_BASE;
int * led_ptr = (int *)LEDS_BASE;
int * keys_ptr = (int *)KEYS_BASE;
while (1) {
if (*(keys_ptr+3) > 0)
{
*(led_ptr)=*(switches_ptr);
22 BÀI 3: HỎI VÒNG VÀ NGẮT
*(keys_ptr+3)=0;
}
}
}
Bài 3.2: Sửa chương trình trên để kiểm tra các công tắc như sau:
- Nhấn KEY1: hiện giá trị của SW1 – SW0 lên LEDG1 – LEDG0.
- Nhấn đồng thời KEY1 và KEY0: hiện giá trị của SW7 – SW0 lên LEDG7 – LEDG0.
3.2 Ngắt
Các bước thực hiện cho phép ngắt trên Nios II:
- Cấu hình PIO để kiểm tra xung cạnh lên / xuống và tạo yêu cầu ngắt (thiết kế
trong Qsys).
Thực hiện phần cứng như trên nhưng thêm phần ngắt cho keys.
BÀI 3: HỎI VÒNG VÀ NGẮT
23
Bài 3.3: Viết chương trình như bài 3.1 nhưng sử dụng ngắt (file ex.h sẽ đươc cung
cấp):
#include "io.h"
#include "system.h"
#include "ex.h"
void main(void) {
int * switches = (int *)SWITCHES_BASE;
int * led_ptr = (int *)LEDS_BASE;
int * keys_ptr = (int *)KEYS_BASE;
*(keys_ptr+2) = 0x0F; // cho phép ngắt tại 4 công tắc
__builtin_wrctl(3,1); // cho phép ngắt tại IRQ0
__builtin_wrctl(0,1); // đặt bit PIE = 1 để cho phép ngắt
while (1);
}
void interrupt_handler(void)
{
int ipending;
ipending = __builtin_rdctl(4); //Đọc thanh ghi ipending
if (ipending & 0x01) // Nếu IRQ0 = 1
keys_isr();
}
void keys_isr(void)
{
int * led_ptr = (int *) LEDS_BASE;
int * keys_ptr = (int *) KEYS_BASE;
int * switches = (int *) SWITCHES_BASE;
*(led_ptr) = *(switches);
*(keys_ptr + 3) = 0; //xóa cờ
}
Bài 3.4: Sửa chương trình trên để kiểm tra các công tắc như sau:
BÀI 4: LCD
− Bộ xử lý Nios II/e với JTAG Debug Module Level 1 và các tùy chọn: Embedded
Multipliers for Hardware Multiply, Hardware Divide.
− LCD.
int main()
{
while (1);
return 0;
BÀI 4: LCD
25
}
void lcd_init(void)
{
*(LCD_display_ptr) = 0x38;
usleep(4000);
*(LCD_display_ptr) = 0x0C;
usleep(100);
*(LCD_display_ptr) = 0x06;
usleep(100);
*(LCD_display_ptr) = 0x01;
usleep(2000);
*(LCD_display_ptr) = 0x02;
usleep(2000);
}
void lcd_printf(void)
{
int i;
char message[] = "DH CN TPHCM \0";
char done[] = "KHOA CDDT \0";
for(i = 0; message[i] != 0; i++)
{
*(LCD_display_ptr+1) = message[i];
usleep(100);
}
*(LCD_display_ptr) = 0xC0;
usleep(1000);