Giáo trình Hệ thống nhúng (Phần 2)

ADC, USB, Ethernet, CAN .), ST cung cấp cho chúng ta các thư viện trực

tiếp cho mỗi dòng ARM (gọi là CMSIS – Cortex

Microcontroller Software Interface Standard ), nhiệm vụ của chúng ta không thể

dễ dàng hơn: khai báo và sử dụng mà thôi

 Giá rẻ: STM32F1x khoảng 29000 đồng. STM32F1x chạy với tốc đọ

24Mhz.

 Flash 16.128K

 37/51/80 chân I/O

 2 bộ USART

 12 Timers

 16 kênh ADC -12bit

 2 bộ I2C

 2 bộ SPI

 2 bộ Watchdog

 16 bộ ngắt lập trình được

 RTC (đồng hồ thời gian thực tích hợp)

Hình 4.4 so sánh 1 cách trực quan nhất giữa các dòng VXL 8 bit - 16 bit và

Cortex™-M qua hàm "nhân 2 số 16 bit" (Cortex™-M có thể nhân 2 số 32 bit chỉ

bằng 1 lệnh)

Giáo trình Hệ thống nhúng (Phần 2) trang 1

Trang 1

Giáo trình Hệ thống nhúng (Phần 2) trang 2

Trang 2

Giáo trình Hệ thống nhúng (Phần 2) trang 3

Trang 3

Giáo trình Hệ thống nhúng (Phần 2) trang 4

Trang 4

Giáo trình Hệ thống nhúng (Phần 2) trang 5

Trang 5

Giáo trình Hệ thống nhúng (Phần 2) trang 6

Trang 6

Giáo trình Hệ thống nhúng (Phần 2) trang 7

Trang 7

Giáo trình Hệ thống nhúng (Phần 2) trang 8

Trang 8

Giáo trình Hệ thống nhúng (Phần 2) trang 9

Trang 9

Giáo trình Hệ thống nhúng (Phần 2) trang 10

Trang 10

Tải về để xem bản đầy đủ

pdf 39 trang duykhanh 12780
Bạn đang xem 10 trang mẫu của tài liệu "Giáo trình Hệ thống nhúng (Phần 2)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Giáo trình Hệ thống nhúng (Phần 2)

Giáo trình Hệ thống nhúng (Phần 2)
mer.c 
-StartUp: core_cm3.c, startup_stm32f10x_md.s, system_stm32f10x.c 
Trong hàm main.c các bạn cần sử dụng: 
-Hàm SystemInit(): Đây là hàm khởi tạo nguồn Clock cho vi điều khiển (các bạn 
có thể tham khảo thêm nguồn Clock cho STM32 tại đây, trong bài toán này mình 
sử dụng nguồn Clock có tần số 72MHz. 
-Hàm NVIC_Configuration(): Đây là hàm cấu hình ngắt (nằm trong 
File user_nvic thuộc Folder UserSTM32), vì bài toán sử dụng ngắt tràn TIM2 để 
tạo khoảng thời gian 1ms: 
void NVIC_Configuration(void) 
{ 
 NVIC_InitTypeDef NVIC_InitStructure; 
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); 
 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; 
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
 NVIC_Init(&NVIC_InitStructure); 
} 
Chương 4. Lập trình nhúng trên ARM 
 61 
- Hàm GPIO_Configuration(): Đây là hàm khởi tạo và cấu hình chức năng GPIO 
(nằm trong File user_gpio thuộc Folder UserSTM32), đối với bài toàn này, các 
bạn cần cấu hình: 
+ các chân PA0 – PA7 là chân Output Push Pull, tốc độ trung bình 50MHz. 
+ các chân PB12 – PB15 là chân Output Push Pull, tốc độ trung bình 50MHz. 
void GPIO_Configuration(void) 
{ 
 GPIO_InitTypeDef GPIO_InitStructure; 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 
 GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); 
/******************************* PORTA ***********************************/ 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 
/*___________________________ OUTPUT_______________________*/ 
 GPIO_InitStructure.GPIO_Pin = 
GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|G
PIO_Pin_7; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_Init(GPIOA, &GPIO_InitStructure); 
/*___________________________ INPUT ________________________*/ 
/**************************** PORTB *************************/ 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 
/*___________________________ OUTPUT _______________________*/ 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_Init(GPIOB, &GPIO_InitStructure); 
/*___________________________ INPUT _________________________*/ 
} 
-Hàm TIMER2_Configuration(): Đây là hàm cấu hình cho TIM2. Các bạn cấu 
hình cho TIM2 xảy ra ngắt sau thời gian 1ms: 
void TIMER2_Configuration(void) 
{ 
 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 
 TIM_TimeBaseStructure.TIM_Prescaler = 35999; 
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
 TIM_TimeBaseStructure.TIM_Period = 1; 
 TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 
 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); 
 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); 
 TIM_Cmd(TIM2,ENABLE); 
} 
Chương 4. Lập trình nhúng trên ARM 
 62 
- Hàm delay_init(72): Đây là hàm khởi tạo để sử dụng các hàm delay_ms(), 
delay_us() (nằm trong File user_delay thuộc Folder UserStm32), 72 là tần số 
nguồn Clock sử dụng. 
Sau 1 ms, ngắt tràn TIM2 xảy ra, các bạn thực hiện quét Led ở trình phục vụ ngắt 
TIM2 void TIM2_IRQHandler(void) (nằm trong File user_interrupt thuộc 
Folder UserStm32): 
void TIM2_IRQHandler(void) 
{ 
 if(TIM_GetITStatus(TIM2,TIM_IT_Update)) 
 { 
 TIM_ClearITPendingBit(TIM2,TIM_IT_Update); 
 LED7_Display(Value_Display); 
 } 
} 
Trong trình phục vụ ngắt mình sử dụng hàm hiển thị giá trị số lên Led 7 thanh void 
LED7_Display(uint16_t Value) (nằm trong File led7 thuộc Folder User): 
void LED7_Display(uint16_t Value) 
{ 
 LED7_CacuCode(Value); 
 LED7_PowerOff(); 
 LED7_DataOut(Led7_BufferData[Led7_Index]); 
 LED7_PowerOn(Led7_Index); 
 Led7_Index++; 
 if(Led7_Index>=NUMBER_LED7)Led7_Index=0; 
} 
Thực hiện thay đổi giá trị hiển thị lên Led 7 thanh trong vòng while(1): 
while(1) 
{ 
 Value_Display++; 
 if(Value_Display > 9999) Value_Display = 0; 
 delay_ms(500); 
} 
Biên dịch chương trình và nạp chạy demo trên KIT STM32 START 
4.5.4. LCD 16X2 4 bit 
a) Sơ đồ phần cứng 
Chương 4. Lập trình nhúng trên ARM 
 63 
Hình 4.9. Sơ đồ kết nối board với LCD 16x2 
Trong đó, các chân kết nối với STM32F103C8T: 
-Các chân điều khiển LCD16x2 LCD_RS, LCD_RW, LCD_EN kết nối thứ tự 
với các chân PORTB[12 – 14]. 
-Các chân dữ liệu của LCD16x2 LCD_D[4 – 7] kết nối thứ tự với các 
chân PORTA[4 – 7]. 
b) Lập trình phần mềm 
Sau khi khởi tạo thành công Project, các bạn thêm các File.c cần thiết vào các 
Folder, cụ thể: 
-FWlib: stm32f10x_gpio.c, stm32f10x_rcc.c 
-Main: main.c 
-User: lcd16x2.c 
-UserSTM32: user_delay.c, user_gpio.c 
-StartUp: core_cm3.c, startup_stm32f10x_md.s, system_stm32f10x.c 
Trong hàm main.c các bạn cần sử dụng: 
-Hàm SystemInit(): Đây là hàm khởi tạo nguồn Clock cho vi điều khiển, trong 
bài toán này mình sử dụng nguồn Clock có tần số 72MHz. 
-Hàm GPIO_Configuration(): Đây là hàm khởi tạo và cấu hình chức năng GPIO 
(nằm trong File user_gpio thuộc Folder UserSTM32), đối với bài toàn này, các 
bạn cần cấu hình: 
+ các chân PA[4 – 7] là chân Output Push Pull, tốc độ trung bình 50MHz. 
+ các chân PB[12 – 14] là chân Output Push Pull, tốc độ trung bình 50MHz. 
Chương 4. Lập trình nhúng trên ARM 
 64 
void GPIO_Configuration(void) 
{ 
 GPIO_InitTypeDef GPIO_InitStructure; 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 
 GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); 
/***************************** PORTA ***********************/ 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 
/*____________________________ OUTPUT _____________________*/ 
 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_Init(GPIOA, &GPIO_InitStructure); 
/*___________________________ INPUT _________________________*/ 
/**************************** PORTB ***********************************/ 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 
/*___________________________ OUTPUT ________________________*/ 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_Init(GPIOB, &GPIO_InitStructure); 
/*___________________________ INPUT ________________________*/ 
} 
- Hàm delay_init(72): Đây là hàm khởi tạo để sử dụng các hàm delay_ms(), 
delay_us() (nằm trong File user_delay thuộc Folder UserStm32), 72 là tần số 
nguồn Clock sử dụng. 
- Các bạn khởi tạo LCD16x2 và lập trình hiển thị các chuỗi ký tự: 
LCD16X2_Init(); 
LCD16X2_Gotoxy(0,0); 
LCD16X2_Puts((uint8_t*)" MinhHaGroup "); 
LCD16X2_Gotoxy(0,1); 
LCD16X2_Puts((uint8_t*)"KIT STM32 START "); 
while(1) 
{ 
} 
Các hàm Driver cho LCD16x2 các bạn xem ở File lcd16x2 thuộc Folder User. 
Biên dịch chương trình và nạp chạy demo trên KIT STM32 
4.5.5. Lập trình UART giao tiếp PC 
a) Lập trình UART cho ARM STM32 
- Tạo một Project tương tự như với lập trình GPIO , chúng ta thêm driver 
stm32f10x_uart.c trong thư viện CMIS vào để có thể lập trình truyền nhận dữ liệu 
UART 
Chương 4. Lập trình nhúng trên ARM 
 65 
- Viết code cho chương trình chính trong hàm maic.c 
Khai báo IO cho UART: 
 GPIO_Init(GPIOA, &GPIO_InitStructure); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_8; //USART1 RX 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
Cấu hình UART: 
void USART1_Configuration(void) 
{ 
USART_InitTypeDef USART_InitStructure; 
//Kich hoat Clock USART1 
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE); 
//Chon BaudRate 
USART_InitStructure.USART_BaudRate = 115200; 
//Chon do dai khung truyen 
USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
//Chon stop bit 
USART_InitStructure.USART_StopBits = USART_StopBits_1; 
//Chon Parity 
USART_InitStructure.USART_Parity = USART_Parity_No; 
//Chon che do dieu khien 
USART_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_None; 
//Chon phuong thuc truyen nhan 
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 
Chương 4. Lập trình nhúng trên ARM 
 66 
//Cau hinh cac thong so vua lua chon 
USART_Init(USART1, &USART_InitStructure); 
//Kich hoat hoat dong cua USART 
USART_Cmd(USART1, ENABLE); 
} 
Hàm ghi dữ liệu 
Hàm đọc dữ liệu từ cổng UART: 
USART_ReceiveData(USART1); 
Hàm gửi chuỗi dữ liệu ra cổng UART: 
USART_SendString(USART1,"demo") 
b) Lập trình giao diện truyền nhận dữ liệu UART dùng Visual Basic 
- Khởi động chương trình 
- Cửa sổ khởi động chọn StandardEXE để tạo một form mới 
- Giao diện chương trình 
Chương 4. Lập trình nhúng trên ARM 
 67 
- Click chuột vào form1 để đổi tên cho project trong mục caption 
Nhấp chuột vào biểu tượng textbox để lấy textbox ra màn hình 
Trong phần thuộc tính của textbox xóa chữ text1 trong caption đi 
- Tiếp tục chọn label để kéo label vào chương trình, thay đổi tên label trong thuộc 
tính caption 
- Tiếp tục với button 
29 
- Chỉnh sửa và thêm một số thành phần để có form như hình dưới 
Chương 4. Lập trình nhúng trên ARM 
 68 
Như vậy ta đã tạo ra một Form các tham số a,b hiển thị với các textbox1,2. Nút 
truyền là Command1 nút nhận là Command2, nút thoát là Command3 
Form hoạt động như sau : Nhập các thông số trong text1, nhấn nút truyền để gửi 
dữ liệu trong text1 ra cổng COM. Nhấn nút nhận thì dữ liệu nhận được sẽ hiển thị 
lên text2. Phím Exit để thoát khỏi chương trình 
Vì Control để điều khiển cổng COM-MSCOM không phải control cơ bản nên nó 
không hiển thị trên tool, chúng ta phải lấy ra trong thư viện như sau 
- Kéo thả MSCOM vào form 
- Để soạn thảo code cho chương trình VB, ta click chuột vào vị trí bất kỳ trong 
form 
Chương 4. Lập trình nhúng trên ARM 
 69 
- Giao diện chính 
- Khai báo sử dụng cổng COM 
- Để viết mã cho nút truyền ta click vào nút truyền và code như sau. Khai báo 
thêm biến s để chứa giá trị của text 
- Tương tự cho nút nhận 
- Và nút Exit 
- Lưu form vừa tạo, chọn Run để chạy chương trình 
32 
- Kết quả: 
Chương 4. Lập trình nhúng trên ARM 
 70 
- Chọn file – Make tut.exe để tạo file thực thi và chạy như một phần mềm thông 
thường 
4.6. CÂU HỎI VÀ BÀI TẬP 
1. Trình bày các thành phần và mô hình lập trình của vi điều khiển ARM 
2. Trình bày được một số lệnh cơ bản trong tập lệnh của ARM 
3. Hàm và các bước thực hiện khi gọi một hàm 
4. Khái niệm ngắt và chương trình phục vụ ngắt 
5. Các bước thực thi khi thực hiện một ngắt. 
6. Viết CT Quét ma trận bàn phím. Chống dội 
7. Viết CT đếm 00-99 hiển thị trên LCD 16x2 
8. Viết CT hiển thị phút và giây trên Led 7 đoạn 
9. Viết CT điểu khiển 8 led đơn sáng dần sau đó tắt dần 
10. Viết chương trình cho vi điều khiển để giải phương trình bậc một ax + b = 0. 
Trong đó a và b nhập từ port A và B. Kết quả hiển thị trên LCD. 
11. Viết chương trình C cho vi điều khiển để giải phương trình bậc hai ax^2 + bx + c = 0. 
Trong đó, a, b và c nhập vào từ port B, C, và D. Kết quả được hiển thị trên serial LCD. 
Hãy mô phỏng hệ thống bằng phần mềm Proteus. 
12. Cho một hệ thống nhúng sử dụng vi điều khiển được mô tả như sau: 
 Port A (PA0, PA1, PA2) nối với 3 nút nhấn tích cực mức thấp, có tên là UP, 
DOWN, CLEAR 
 Port B (PB0, PB1  PB6) nối với một LED 7 đoạn Anode chung, có các chân A, 
B, C, D, E, F, G. 
 Sau khi RESET, LED 7 đoạn hiển thị số 0 
 Khi nhấn nút UP, số hiển thị sẽ tăng 1 (tối đa tăng đến số 9). 
 Khi nhấn nút DOWN thì số hiển thị sẽ giảm 1 (tối thiểu giảm đến số 0). 
 Khi nhấn nút CLEAR, số hiển thị về 0. 
 Khi không nhấn nút thì số hiển thị giữ nguyên 
a) Hãy vẽ sơ đồ mạch chi tiết cho hệ thống trên 
b) Hãy viết chương trình C để thực hiện chức năng điều khiển hệ thống trên. 
13. Cho một hệ thống nhúng điều khiển khóa cửa sử dụng PIC16F84 được mô tả 
như sau: 
 RB0, RB1, RB2, RB3, RB4: nối với 5 nút nhấn 1, 2, 3, 4, 5 (tích cực mức 
thấp). 
Chương 4. Lập trình nhúng trên ARM 
 71 
 RB5: nối với nút nhấn tích cực mức thấp, có tên là ENTER 
 RB6: điều khiển RELAY tích cực mức cao thông qua transistor. 
 RB7: điều khiển đèn LED cảnh báo tích cực mức cao. 
 Nguyên lý hoạt động: 
o Người đi vào cửa bấm vào mã số (gồm 5 số) và sau đó bấm ENTER 
 Nếu đúng mật mã 54321, RB6 sẽ tích cực mức cao để mở cửa. 
 Nếu sai mật mã, đèn LED cảnh báo sáng. 
o Các nút nhấn có chức năng chống rung phím. 
14. Thiết kế một hệ thống nhúng điều khiển nhiệt độ lò điện đơn giản. Hệ thống 
sử dụng cảm biến nhiệt độ lò LM35, PIC16F877A, led 7 đoạn và relay bật tắt lò. 
Cho điện áp tham khảo của ADC Vref = 5V, độ phân giải của cảm biến LM35 là 
tuyến tính với 10mV/oC. 
 Cảm biến nhiệt độ được nối vào AN0 của PIC 
 Relay bật tắt lò được nối vào chân RE2 của port E 
 Hai led 7 đoạn anode chung nước nối vào 2 port B, C 
 Sau khi RESET, hai led 7 đoạn hiển thị nhiệt độ hiện tại của lò 
 Khi nhiệt độ trong lò nhỏ hơn 80oC thì RE2 được cài đặt bằng 1 để bật lò. 
 Khi nhiệt độ lớn hơn 120oC thì RE2 được cài đặt bằng 0 để tắt lò. 
a) Hãy vẽ sơ đồ mạch chi tiết cho hệ thống trên 
b) Hãy viết chương trình C để thực hiện chức năng điều khiển hệ thống trên. 
15. Hãy viết chương trình điều khiển cho 16F877A để tạo xung ở ngõ ra B0 bao 
gồm xung 10kHz và 1kHz lồng vào nhau mô tả như hình dưới. Chu kỳ nhiệm vụ 
của xung 10kHz và 1kHz là 50%. 
 ___||_||_||_||_||_________________||_||_||_||_||_______________ 
16. Hãy viết chương trình C cho PIC16F877A tạo xung vuông ở 2 ngõ ra RC0 và 
RC1, với tần số xung clock lần lượt là 0.5KHz và 1KHz, duty cycle là 50%. Hãy 
sử dụng ngắt Timer1 với thạch anh 4MHz. 
17. Hãy viết chương trình cho vi điều khiển PIC16F877A sử dụng thạch anh 
20MHz tạo sóng sin có tần số 1 KHz bằng phương pháp có điều chế ở 10 KHz. 
18. Lập trình giao tiếp KIT STM32 với máy tính qua USART, lập trình truyền thông KIT với điện 
thoại Android qua Bluetooth. 
 72 
TÀI LIỆU THAM KHẢO 
[1]. Andrew Sloss, Dominic Symes, Chris Wright, ARM System Developer's 
Guide: Designing and Optimizing System Software, Morgan Kaufmann, 2004 
[2]. RajKamal, Embedded Systems-Architecture, Programming and Design, 
McGraw Hill, 2003 
[3]. Steve Heath, Embedded Systems Design, Second Edition, Newnes, 2002. 
[4]. Tammy Noergaard, Embedded Systems Architecture: A Comprehensive 
Guide for Engineers and Programmers, Newnes, 2005. 
[5]. Đinh Công Đoan, Bài Giảng Hệ Thống Nhúng, Khoa CNTT Đại học SPKT 
TP.HCM 

File đính kèm:

  • pdfgiao_trinh_he_thong_nhung_phan_2.pdf