- Chuẩn bị sẵn sàng phần cứng
- Hiểu sơ đồ GPIO trên STM8S103F
- Mô tả sơ đồ chân và Mẹo cho Lựa chọn GPIO STM8S103F
- Lập trình STM8S cho Đầu vào và Đầu ra GPIO bằng SPL
- Tải lên và kiểm tra chương trình
Đối với vi điều khiển, chương trình nhấp nháy đèn LED tương đương với chương trình “chào thế giới”. Trong hướng dẫn trước của chúng tôi, chúng tôi đã học cách bắt đầu với Bảng phát triển STM8S103F3 và cách thiết lập IDE và trình biên dịch để lập trình bộ điều khiển STM8S của chúng tôi. Chúng tôi cũng đã học cách sử dụng các thư viện ngoại vi chuẩn cũng như cách biên dịch và tải mã lên bộ vi điều khiển của chúng tôi. Với tất cả những điều cơ bản được đề cập, chúng ta hãy thực sự bắt đầu viết mã. Trong hướng dẫn này, chúng ta sẽ học cách thực hiện các chức năng GPIO chung trên bộ điều khiển STM8S. Bo mạch đã có một đèn LED trên bo mạch được kết nối với chân số 5 của cổng B, chúng ta sẽ học cách nhấp nháy đèn LED này và cũng có thể thêm một đèn LED bên ngoài và điều khiển nó bằng một nút nhấn. Nếu bạn là người mới hoàn toàn, bạn nên đọc hướng dẫn trước đó trước khi tiếp tục.
Chuẩn bị sẵn sàng phần cứng
Trước khi chúng ta đi sâu vào chương trình, hãy chuẩn bị sẵn sàng các kết nối phần cứng. Như đã đề cập ở phần đầu, chúng tôi sẽ sử dụng hai đèn LED ở đây, một là đèn LED trên bo mạch sẽ nhấp nháy liên tục và đèn còn lại là đèn LED bên ngoài sẽ được bật tắt bằng một nút nhấn. Ý tưởng là tìm hiểu tất cả các chức năng GPIO trong một thiết lập đơn giản. Đèn Led trên bo mạch đã được kết nối với PB5 (chân 5 của PORTB), vì vậy tôi vừa kết nối một đèn LED với PA3 và một nút nhấn với PA2, như bạn có thể thấy trong sơ đồ bên dưới.
Nhưng, trong số tất cả các chân đầu ra có sẵn trên điều khiển của chúng tôi, tại sao tôi lại chọn PA3 cho đầu ra và PA2 cho đầu vào? Các câu hỏi là hợp lệ và tôi sẽ giải thích điều đó ở phần sau của bài viết này. Thiết lập phần cứng của tôi cho hướng dẫn này được hiển thị bên dưới. Như bạn có thể thấy, tôi cũng đã kết nối lập trình viên ST-link của mình với các chân lập trình, chân cắm này sẽ không chỉ lập trình bảng mạch của chúng tôi mà còn hoạt động như một nguồn điện.
Hiểu sơ đồ GPIO trên STM8S103F
Bây giờ quay lại câu hỏi, tại sao PA2 cho đầu vào và tại sao PA3 cho đầu ra? Để hiểu điều đó, chúng ta hãy xem xét kỹ hơn sơ đồ chân của bộ vi điều khiển được hiển thị bên dưới.
Theo sơ đồ sơ đồ chân, chúng ta có bốn cổng trên bộ vi điều khiển của mình, đó là PORT A, B, C và D được ký hiệu lần lượt là PA, PB, PC và PD. Mỗi chân GPIO cũng có một số chức năng đặc biệt khác. Ví dụ, PB5 (chân 5 của PORT B) không chỉ có thể hoạt động như một chân GPIO mà còn như một chân SDA cho giao tiếp I2C và như một chân đầu ra của Timer 1. Vì vậy, nếu chúng ta sử dụng chân này cho các mục đích GPIO đơn giản như kết nối đèn LED, thì chúng ta sẽ không thể sử dụng I2C và đèn LED cùng một lúc. Đáng buồn thay, đèn LED trên bo mạch được kết nối với chân này, vì vậy chúng tôi không có nhiều lựa chọn ở đây và trong chương trình này, chúng tôi sẽ không sử dụng I2C, vì vậy nó không có nhiều vấn đề.
Mô tả sơ đồ chân và Mẹo cho Lựa chọn GPIO STM8S103F
Thực sự mà nói, sẽ không hại gì nếu sử dụng PA1 một chân đầu vào và nó sẽ chỉ hoạt động ở chân. Nhưng tôi cố tình đưa ra điều này để tạo cơ hội cho bạn thấy một số bẫy phổ biến mà bạn có thể rơi vào khi chọn các chân GPIO trên vi điều khiển mới. Cách tốt nhất để tránh mắc bẫy là đọc chi tiết về pin và mô tả về pin được cung cấp trong biểu dữ liệu STM8S103F3P6. Đối với chi tiết mô tả chân vi điều khiển STM8S103F3P6 được đề cập trong biểu dữ liệu được hiển thị bên dưới hình ảnh.
Các chân đầu vào trên bộ vi điều khiển của chúng tôi có thể là chân cắm nổi hoặc kéo lên yếu và các chân đầu ra có thể là Mở xả hoặc Kéo đẩy. Sự khác biệt giữa các chân Open Drain và Push-Pull Output đã được thảo luận, do đó chúng tôi sẽ không đi sâu vào chi tiết. Nói một cách đơn giản, chân đầu ra Open Drain có thể làm cho đầu ra chỉ ở mức thấp chứ không phải cao, trong khi chân đầu ra dạng đẩy kéo có thể làm cho đầu ra vừa cao vừa cao.
Ngoài bảng trên, bạn cũng có thể nhận thấy rằng chân đầu ra có thể là đầu ra Nhanh (10 Mhz) hoặc Đầu ra chậm (2 MHz). Điều này quyết định Tốc độ GPIO, nếu bạn muốn chuyển các chân GPIO của mình giữa cao và thấp rất nhanh, thì chúng ta có thể chọn Đầu ra nhanh.
Một số chân GPIO trên bộ điều khiển của chúng tôi hỗ trợ True Open Drain (T) và High Sink Current (HS) như đã đề cập trong hình trên. Một sự khác biệt đáng kể giữa Open Drain và True Open Drain là đầu ra được kết nối với cống mở không thể kéo cao hơn điện áp hoạt động của vi điều khiển (Vdd) trong khi chân đầu ra thoát hở thực sự có thể được kéo cao hơn Vdd. Ghim có khả năng chìm cao có nghĩa là nó có thể chìm nhiều hơn hiện tại. Nguồn và dòng chìm của bất kỳ chân GPIO HS nào là 20mA, trong khi dòng điện có thể tiêu thụ tới 100 mA.
Xem xét kỹ hơn hình trên, bạn sẽ nhận thấy rằng hầu hết tất cả các chân GPIO đều là loại High Sink Current (HS) ngoại trừ PB4 và PB5 là True Open Drain Type (T). Điều này có nghĩa là các chân này không thể được làm cao, chúng sẽ không thể cung cấp 3,3V ngay cả khi chân được làm ở mức cao. Đây là lý do tại sao đèn led trên bo mạch được kết nối với 3.3V và nối đất qua PB5 thay vì cấp nguồn trực tiếp từ chân GPIO.
Tham khảo trang 28 trên biểu dữ liệu để biết mô tả chi tiết về pin. Như đã đề cập trong hình trên, PA1 được tự động cấu hình như một pull-up yếu và không được khuyến khích sử dụng như một chân đầu ra. Dù sao nó cũng có thể được sử dụng như một chân đầu vào cùng với một nút nhấn, nhưng tôi quyết định sử dụng PA2 chỉ để thử kích hoạt tính năng kéo lên từ chương trình. Đây chỉ là một vài điều cơ bản sẽ hữu ích khi chúng ta viết các chương trình phức tạp hơn nhiều. Hiện tại, không sao cả nếu nhiều thứ nảy ra trong đầu bạn, chúng ta sẽ đi sâu vào nó trong các bài hướng dẫn khác.
Lập trình STM8S cho Đầu vào và Đầu ra GPIO bằng SPL
Tạo không gian làm việc và dự án mới như chúng ta đã thảo luận trong hướng dẫn đầu tiên. Bạn có thể thêm tất cả các tệp tiêu đề và nguồn hoặc chỉ thêm các tệp gpio, cấu hình và stm8s. Mở tệp main.c và bắt đầu viết chương trình của bạn.
Đảm bảo rằng bạn đã bao gồm các tệp tiêu đề như được hiển thị trong hình trên. Mở tệp main.c và bắt đầu mã. Bạn có thể tìm thấy mã main.c đầy đủ ở cuối trang này và bạn cũng có thể tải xuống tệp dự án từ đó. Giải thích về mã như sau, bạn cũng có thể tham khảo Hướng dẫn sử dụng SPL hoặc video được liên kết ở cuối trang này nếu bạn không hiểu về phần mã hóa.
Khử khởi tạo cổng yêu cầu
Chúng tôi bắt đầu chương trình của mình bằng cách Khử khởi tạo các cổng cần thiết. Như chúng ta đã thảo luận trước đó, mỗi chân GPIO sẽ có nhiều chức năng khác được liên kết với nó ngoài việc chỉ hoạt động như một Đầu vào và Đầu ra thông thường. Nếu những chân này trước đây đã được sử dụng cho một số ứng dụng khác, thì nó nên được Khử khởi tạo trước khi chúng ta sử dụng chúng. Nó không phải là bắt buộc, tuy nhiên, nó là một thực hành tốt. Hai dòng mã sau được sử dụng để khử khởi tạo cổng A và cổng B. Chỉ cần sử dụng cú pháp GPIO_DeInit (GPIOx); và đề cập đến tên cổng thay cho x.
GPIO_DeInit (GPIOA); // chuẩn bị cho cổng A hoạt động GPIO_DeInit (GPIOB); // chuẩn bị cho cổng B hoạt động
Khai báo GPIO đầu vào và đầu ra
Tiếp theo, chúng ta phải khai báo chân nào sẽ được sử dụng làm đầu vào và chân nào là đầu ra. Trong trường hợp của chúng tôi, chân PA2 sẽ được sử dụng làm đầu vào, chúng tôi cũng sẽ khai báo chân này với Pull-up bên trong để chúng tôi không phải sử dụng một bên ngoài. Cú pháp là GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Trong đó x là tên cổng, y là số pin và z là chế độ Pin GPIO.
// Khai báo PA2 là đầu vào kéo lên chân GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Tiếp theo, chúng ta phải khai báo các chân PA3 và PB5 là đầu ra. Một lần nữa có thể khai báo nhiều kiểu đầu ra nhưng chúng ta sẽ sử dụng “GPIO_MODE_OUT_PP_LOW_SLOW” có nghĩa là chúng ta sẽ khai báo nó như một chân đầu ra của kiểu push-pull với tốc độ chậm. Và theo mặc định, giá trị sẽ thấp. Cú pháp sẽ giống nhau.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Khai báo PB5 dưới dạng push pull Chân đầu ra GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
Ảnh chụp nhanh dưới đây từ hướng dẫn sử dụng SPL đề cập đến tất cả các chế độ GPIO có thể có (z).
Vòng lặp while vô hạn
Sau khi khai báo pin, chúng ta cần tạo một vòng lặp vô hạn bên trong mà chúng ta sẽ tiếp tục nhấp nháy đèn LED mãi mãi và theo dõi trạng thái của nút nhấn để bật tắt đèn LED. Vòng lặp vô hạn có thể tạo với while (1) hoặc với for (;;) . Ở đây tôi đã sử dụng while (1).
trong khi (1) {}
Kiểm tra trạng thái của chân đầu vào
Chúng ta phải kiểm tra trạng thái của chân đầu vào, cú pháp để làm điều đó là GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); trong đó x là tên cổng và y là số pin. Nếu chân cao, chúng ta sẽ nhận được "1" và nếu chân thấp, chúng ta sẽ nhận được "0". Chúng tôi đã sử dụng bên trong vòng lặp if để kiểm tra xem chân cắm cao hay thấp.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // nút if được nhấn
Đặt chân GPIO ở mức cao hoặc thấp
Để đặt chân GPIO Cao hoặc Thấp, chúng ta có thể sử dụng GPIO_WriteHigh (GPIOx, GPIO_PIN_y); và GPIO_WriteLow (GPIOx, GPIO_PIN_y); tương ứng. Ở đây chúng tôi đã làm cho đèn LED bật nếu nút được nhấn và tắt nếu nút không được nhấn.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // nếu nhấn nút GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ON else GPIO_WriteHigh (GPIOA, GPIO_PIN_3); //DẪN RA
Chuyển đổi mã pin GPIO
Để chuyển đổi chân GPIO, chúng ta có GPIO_WriteReverse (GPIOx, GPIO_PIN_y); gọi hàm này sẽ thay đổi trạng thái của chân đầu ra. Nếu chân cao, nó sẽ được chuyển thành thấp, và nếu nó thấp, nó sẽ được chuyển thành cao. Chúng tôi đang sử dụng chức năng này để nhấp nháy đèn LED tích hợp trên PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Chức năng trì hoãn
Không giống như Arduino, trình biên dịch vũ trụ không có chức năng trì hoãn được xác định trước. Vì vậy, chúng tôi phải tạo một cái của riêng mình. Hàm trì hoãn của tôi được đưa ra bên dưới. Giá trị doe độ trễ sẽ được nhận trong biến ms và chúng ta sẽ sử dụng hai vòng lặp for để giữ hoặc thực thi chương trình. Giống như _asm (“nop”) là một lệnh hợp ngữ, viết tắt của không hoạt động. Điều này có nghĩa là bộ điều khiển sẽ lặp vào vòng lặp for mà không thực hiện bất kỳ hoạt động nào, do đó tạo ra độ trễ.
void delay (int ms) // Định nghĩa hàm {int i = 0; int j = 0; for (i = 0; i <= ms; i ++) {for (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Không thực hiện thao tác nào // mã hợp ngữ}}
Tải lên và kiểm tra chương trình
Bây giờ chương trình của chúng tôi đã sẵn sàng, chúng tôi có thể tải lên và kiểm tra nó. Sau khi tải lên, phần cứng của tôi đã hoạt động như mong đợi. Đèn LED màu đỏ trên bo mạch nhấp nháy cứ sau 500 mili giây và đèn LED màu xanh lá cây bên ngoài bật sáng mỗi khi tôi nhấn công tắc.
Hoạt động hoàn chỉnh có thể được tìm thấy trong video được liên kết bên dưới. Khi bạn đã đạt đến điểm này, bạn có thể thử kết nối công tắc và đèn LED với các chân khác nhau và viết lại mã để hiểu khái niệm. Bạn cũng có thể thử thời gian trễ để kiểm tra xem bạn đã hiểu rõ các khái niệm chưa.
Nếu bạn có bất kỳ câu hỏi nào, vui lòng để lại trong phần bình luận bên dưới và đối với các câu hỏi kỹ thuật khác, bạn có thể sử dụng diễn đàn của chúng tôi. Cảm ơn đã theo dõi, hẹn gặp lại trong bài hướng dẫn tiếp theo.