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)
Trang 1
Trang 2
Trang 3
Trang 4
Trang 5
Trang 6
Trang 7
Trang 8
Trang 9
Trang 10
Tải về để xem bản đầy đủ
Tóm tắt nội dung tài liệu: 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:
- giao_trinh_he_thong_nhung_phan_2.pdf