Giáo trình Lập trình nhúng
Sức đẩy của công nghệ đưa công nghệ vi điện tử, công nghệ vi cơ điện, công nghệ sinh học hội tụ tạo nên các chip của công nghệ nano, là nền tảng cho những thay đổi cơ bản trong lĩnh vực công nghệ cao “3C, sức kéo của thị trường đòi hỏi các thiết bị phải có nhiều chức năng thân thiện với người dùng, có mức độ thông minh ngày càng cải thiện đưa đến vai trò và tầm quan trọng của các hệ thống nhúng ngày càng cao trong nền kinh tế quốc dân.
Phát triển các hệ nhúng và phần mềm nhúng là quốc sách của nhiều quốc gia trên thế giới, nhất là giai đoạn hậu PC hiện nay. Ở nước ta đáng tiếc lĩnh vực này lâu nay đã bị lãng quên, do vậy cần có những điều chỉnh phù hợp trong chiến lược phát triển để có thể theo kịp, rút ngắn khoảng cách tụt hậu đối với các nước trong khu vực và trên thế giới trong quá trình hội nhập nền kinh tế toàn cầu không thể tránh khỏi hiện nay.
Tóm tắt nội dung tài liệu: Giáo trình Lập trình nhúng
TRƯỜNG ĐẠI HỌC VĂN HIẾN TPHCM KHOA KỸ THUẬT – CÔNG NGHỆ BỘ MÔN ĐIỆN TỬ - VIỄN THÔNG LẬP TRÌNH NHÚNG TÀI LIỆU LƯU HÀNH NỘI MỤC LỤC Chương 1 Tổng quan.1 1.1 Mở đầu...1 1.2 Khái niệm về hệ nhúng.......1 1.3 Vai trò của hệ thống nhúng trong sự phát triển của lĩnh vực công nghệ cao..3 1.4 Đặc tính, phương pháp thiết kế và xu thế phát triển của các hệ nhúng.....4 1.5 Môi trường thông minh.6 1.6 Các hệ điều hành nhúng và phần mềm nhúng..6 1.6.1 Hệ điều hành nhúng...6 1.6.2 Phần mềm nhúng...7 Chương 2 Lý thuyết thiết kế hệ thống nhúng.8 2.1 Quy trình thiết kế Top-Down8 2.1.1 Pha phân tích......8 2.1.2 Pha thiết kế nguyên lý..10 2.1.3 Pha thiết kế kỹ thuật.....11 2.1.4 Pha xây dựng hệ thống.....11 2.1.5 Pha kiểm tra.....12 2.2 Quy trình thiết kế Bottom-Up.12 2.3 Đặc tả hệ thống....14 2.3.1 Khái niệm đặc tả (specification)......14 2.3.2 Tại sao cần đặc tả......14 2.3.3 Phân loại các kỹ thuật đặc tả..15 2.3.4 Ứng dụng và ưu việt khỉ sử dụng đặc tả...15 2.3.5 Phương pháp đặc tả sử dụng “Máy trạng thái hữu hạn FSM”...16 2.4 Các phương pháp biểu diễn thuật toán..17 2.4.1 Ngôn ngữ tự nhiên....18 2.4.2 Dùng lưu đồ.18 2.4.3 Mã giả...21 Chương 3 Cấu trúc phần cứng.23 3.1 Cấu trúc tổng quát của hệ thống nhúng..23 3.1.1 Kiến trúc cơ bản.....23 3.1.2 Cấu trúc phần cứng......23 3.2 Một số nền tảng phần cứng thông dụng....24 3.2.1 Vi điều khiển Atmega8....24 3.2.2 Kit Arduino Uno R3....29 3.2.3 Vi điều khiển MSP430G2553...33 3.2.4 Kit MSP430 Launchpad....36 3.2.5 Vi điều khiển PIC18F2550...38 3.2.6 Kit PIC18F2550 Pinguino.....40 Chương 4 Phần mềm nhúng.....43 4.1 Đặc điểm phần mềm nhúng.43 4.2 Lập trình nhúng với ngôn ngữ Arduino..43 4.2.1 Cấu trúc....43 4.2.1.1 setup()..43 4.2.1.2 loop()....44 4.2.1.3 Cú pháp mở rộng..45 4.2.1.4 Toán tử số học..48 4.2.1.5 Toán tử so sánh....50 4.2.1.6 Toán tử logic....50 4.2.1.7 Toán tử hợp nhất......50 4.2.1.8 Cấu trúc điều khiển......51 4.2.2 Giá trị...59 4.2.2.1 Hằng số....59 4.2.2.2 Kiểu dữ liệu......65 4.2.2.3 Chuyển đổi kiểu dữ liệu...73 4.2.2.4 Phạm vi của biến và phân loại biến..74 4.2.2.5 Hàm hỗ trợ sizeoff().....78 4.2.3 Hàm và thủ tục.....79 4.2.3.1 Nhập xuất Digital...79 4.2.3.2 Nhập xuất Analog......81 4.2.3.3 Hàm thời gian....85 4.2.3.4 Hàm toán học.....88 4.2.3.5 Hàm lượng giác......93 4.2.3.6 Sinh số ngẫu nhiên.....93 4.2.3.7 Nhập xuất nâng cao....96 4.2.3.8 Bits và Bytes..99 4.2.3.9 Ngắt.....102 Chương I: Tổng quan Bài giảng lập trình nhúng 1 Chương 1: TỔNG QUAN 1.1 Mở đầu Trong sự phát triển mạnh mẽ của khoa học kĩ thuật với nền kinh tế trí thức và xu hướng hội nhập toàn cầu như hiện nay, thế giới và Việt Nam đang thực hiện việc kết hợp giữa các ngành thuộc lĩnh vực công nghệ cao trong một Khoa hoặc cơ sở đào tạo. Đó là lĩnh vực khoa học dưới 3 ngọn cờ: Máy tính, Điện tử- Viễn thông và Điều khiển tự động mà ta thường gọi là “3 C” (Computer – Communication - Control). Có thể nói, các quá trình sản xuất và quản lí hiện nay như: các hệ thống đo lường điều khiển tự động trong sản xuất công nghiệp; các hệ thống di động và không dây tiên tiến, các hệ thống thông tin vệ tinh, các hệ thống thông tin dựa trên Web, chính phủ điện tử, thương mại điện tử, các cơ sở dữ liệu của nhiều ngành kinh tế và của Quốc gia, các hệ thống thiết bị Y tế hiện đại, các thiết bị điện tử dân dụng, ... đều là sản phẩm của sự kết hợp giữa các lĩnh vực khoa học trên. Hiện nay chúng ta đang ở thời đại hậu PC sau giai đoạn phát triển của máy tính lớn (Mainframe) 1960-1980, và sự phát triển của PC-Internet giai đoạn 1980-2000. Giai đoạn hậu PC-Internet này được dự đoán từ năm 2000 đến 2020 là giai đoạn của môi trường thông minh mà hệ thống nhúng là cốt lõi và đang làm nên làn sóng đổi mới trong công nghệ thông tin nói riêng và lĩnh vực công nghệ cao “3C”, nói chung. Một thực tế khách quan là thị trường của các hệ thống nhúng lớn gấp khoảng 100 lần thị trường PC, trong khi đó chúng ta mới nhìn thấy bề nổi của công nghệ thông tin là PC và Internet còn phần chìm của công nghệ thông tin chiếm 99% số processor trên toàn cầu này nằm trong các hệ nhúng thì còn ít được biết đến. Sức đẩy của công nghệ đưa công nghệ vi điện tử, công nghệ vi cơ điện, công nghệ sinh học hội tụ tạo nên các chip của công nghệ nano, là nền tảng cho những thay đổi cơ bản trong lĩnh vực công nghệ cao “3C, sức kéo của thị trường đòi hỏi các thiết bị phải có nhiều chức năng thân thiện với người dùng, có mức độ thông minh ngày càng cải thiện đưa đến vai trò và tầm quan trọng của các hệ thống nhúng ngày càng cao trong nền kinh tế quốc dân. Phát triển các hệ nhúng và phần mềm nhúng là quốc sách của nhiều quốc gia trên thế giới, nhất là giai đoạn hậu PC hiện nay. Ở nước ta đáng tiếc lĩnh vực này lâu nay đã bị lãng quên, do vậy cần có những điều chỉnh phù hợp trong chiến lược phát triển để có thể theo kịp, rút ngắn khoảng cách tụt hậu đối với các nước trong khu vực và trên thế giới trong quá trình hội nhập nền kinh tế toàn cầu không thể tránh khỏi hiện nay. 1.2 Khái niệm về hệ nhúng Hệ thống nhúng (tiếng Anh: Embedded system) là một thuật ngữ để chỉ một thống có khả năng tự trị được nhúng vào trong một môi trường hay một hệ thống mẹ. Hệ thống nhúng có vai trò đảm nhận một phần công việc cụ thể của hệ thống mẹ. Hệ thống nhúng có thể là một hệ thống phần cứng và cũng có thể là một hệ thống phần mềm. (Wikipedia, 2010) Chương I: Tổng quan Bài giảng lập trình nhúng 2 Ví dụ quanh ta có rất nhiều sản phẩm nhúng như lò vi sóng, nồi cơm điện, điều hòa, điện thoại di động, ô tô, máy bay, tàu thủy, các đầu đo, cơ cấu chấp hành thông minh v.v... ta có thể thấy hiện nay hệ thống nhúng có mặt ở mọi lúc mọi nơi trong cuộc sống của chúng ta. Hình 1.1 Một số ví dụ về các thống nhúng thông dụng Các nhà thống kê trên thế giới đã thống kê được rằng số chip vi xử lý ở trong các máy PC và các server, các mạng LAN, WAN, Internet chỉ chiếm khoảng 1% tổng số chip vi xử lý có trên thế giới, 99% số vi xử lý còn lại nằm trong các hệ thống nhúng. Như vậy công nghệ thông tin không chỉ đơn thuần là PC, mạng LAN, WAN, Internet phần mềm quản lý ... như nhiều người thường nghĩ. Đó chỉ là bề nổi của một tảng băng chìm. Phần chìm của công nghệ thông tin chính là các ứng dụng của các hệ nhúng có mặt trong mọi ngành nghề của đời sống xã hội hiện nay. Các hệ nhúng được tích hợp trong các thiết bị đo lường điều khiển tạo nên đầu não và linh hồn của sản phẩm. Trong các hệ nhúng, hệ thống điều khiển nhúng đóng một vai trò hết sức quan trọng. Hệ điều khiển nhúng là hệ thống mà máy tính được nhúng vào vòng điều khiển của sản phẩm nhằm điều khiển một đối tượng, điều khiển một quá trình công nghệ đáp ứng các yêu cầu đặt ra. Hệ thống điều khiển nhúng lấy thông tin từ các cảm biến, xử lý tính toán các thuật điều khiển và phát tín hiệu điều khiển cho các cơ cấu chấp hành. Khác với các hệ thống điều khiển cổ điển theo nguyên lý thủy lực, khí nén, rơle, mạch tương tự, hệ điều khiển nhúng là hệ thống điều khiển số được hình thành từ những năm 1960 đến nay. Trước đây các hệ điều khiển số thường do các máy tính lớn đảm nhiệm, ngày nay chức năng điều khiển số này do các chíp vi xử lý, các hệ nhúng đã thay thế. Phần mềm điều khiển ngày càng tinh sảo tạo nên độ thông minh của thiết bị và ngày càng chiếm tỉ trọng lớn trong giá thành của thiết bị. Chương I: Tổng quan Bài giảng lập trình nhúng 3 Điểm qua về chức năng xử lý tin ở PC và ở các thiết bị nhúng có những nét khác biệt. Đối với PC và mạng internet chức năng xử lý đang được phát triển mạnh ở các lĩnh vực quản lý và dịch vụ như thương mại điện tử, ngân hàng điện tử, chính phủ điện tử, thư viện điện tử, đào tạo từ xa, báo điện tử ... các ứng dụng này thường sử dụng máy PC để bàn, mạng WAN, LAN hoạt động trong thế giới ảo. Còn đối với các hệ nhúng thì chức năng xử lý tính toán được ứng dụng cụ thể cho các thiết bị vật lý (thế giới thật) như mobile phone, quần áo thông minh, các thiết bị điện tử cầm tay, thiết bị y tế, xe ô tô, tầu tốc hành, phương tiện vận tải thông minh, máy đo, đầu đo, cơ cấu chấp hành thông minh, các hệ thống điều khiển, nhà thông minh, thiết bị gia dụng thông minh v.v... 1.3 Vai trò của hệ thống nhúng trong sự phát triển của lĩnh vực công nghệ cao “3C“. Các hệ thống tự động đã được chế tạo trên nhiều công nghệ khác nhau như các thiết bị máy móc tự động bằng các cam chốt cơ khí, các hệ thống tự động hoạt động bằng nguyên lý khí nén, thủy lực, rơle cơ điện, mạch điện tử số ... các thiết bị, hệ thống này có chức năng xử lý và mức độ tự động thấp so với các hệ thống tự động hiện đại được xây dựng trên nền tảng của các hệ thống nhúng. Trong khi các hệ thống tin học sử dụng máy tính để hỗ trợ và tự động hóa quá trình quản lý, thì các hệ thống điều khiển tự động dùng máy tính để điều khiển và tự động hóa quá trình công nghệ. Chính vì vậy các thành tựu của công nghệ phần cứng và công nghệ phần mềm của máy tính điện tử được áp dụng và phát triển một cách có chọn lọc và hiệu quả cho các hệ thống điều khiển tự động. Và sự phát triển như vũ bão của công nghệ thông tin kéo theo sự phát triển không ngừng của lĩnh vực tự động hóa. Ta có thể thấy quá trình các hệ nhúng thâm nhập vào từng phần tử, thiết bị thuộc lĩnh vực tự động hóa như đầu đo, cơ cấu chấp hành, thiết bị giao diện với người vận hành thậm chí vào các rơle, contactor, nút bấm mà trước kia hoàn toàn làm bằng cơ khí. Trước khi đầu đo gồm phần tử biến đổi từ tham số đo sang tín hiệu điện, mạch khuyếch đại, mạch lọc và mạch biến đổi sang chuẩn 4-20mA để truyền tín hiệu đo về trung tâm xử lý. Hiện nay đầu đo đã tích hợp cả chip vi xử lý, biến đổi ADC, bộ truyền dữ liệu số với phần mềm đo đạc, lọc số, tính toán và truyền kết quả trên mạng số về thẳng máy tính trung tâm. Như vậy đầu đo đã được số hóa và ngày càng thông minh do các chức năng xử lý từ máy tính trung tâm trước kia nay đã được chuyển xuống xử lý tại chỗ bằng chương trình nhúng trong đầu đo. Tương tự như vậy cơ cấu chấp hành như môtơ đã được chế tạo gắn kết hữu cơ với cả bộ servo với các thuật toán điều chỉnh PID tại chỗ và khả năng nối mạng số tới máy tính chủ. Các tủ rơle điều khiển chiếm diện tích lớn trong các phòng điều khiển nay được co gọn trong các PLC(programble Logic Controller). Các bàn điều khiển với hàng loạt các đồng hồ chỉ báo, các phím, núm điều khiển, các bộ tự ghi trên giấy cồng kềnh nay được thay thế bằng một vài PC. Chương I: Tổng quan Bài giảng lập trình nhúng 4 Hệ thống cáp truyền tín hiệu analog 4-20mA, ± 10V từ các đầu đo, cơ cấu chấp hành về trung tâm điều khiển nhằng nhịt trước đây đã được thay thế bằng vài cáp đồng trục hoặc cáp quang truyền dữ liệu số Ta có thể nói các hệ nhúng đã “thay thế và chiếm phần ngày càng nhiều” trong các phần tử, hệ thống thuộc lĩnh vực công nghệ cao “3C”. Vào những năm 30 các hệ thống tự động bằng cam chốt cơ khí thường hoạt động đơn lẻ với một chức năng xử lý. Các hệ thống tự động dùng rơle điện từ xuất hiện vào những năm 40 có mức xử lý khoảng 10 chức năng. Các hệ thống tự động dùng bán dẫn hoạt động theo nguyên lý tương tự (Analog) của thập kỷ 60 có mức xử lý khoảng 30 chức năng. Vào những năm 70 các thiết bị điều khiển khả trình PLC ra đời với mức độ xử lý lên hàng trăm và vào những năm 80 với sự tham gia của các máy tính điện tử main frame mini đã hình thành các hệ thống điều khiển phân cấp với số chức năng xử lý lên tới hàng chục vạn (105). Sang thập kỷ 90 với sự phát triển của công nghệ phần cứng cũng như phần mềm, các hệ thống điều khiển phân tán ra đời(DCS) cho mức xử lý lên tới hàng trục triệu (107). Và sang thế kỷ 21, những hệ thống tự động có tính tự tổ chức, có tư duy hợp tác sẽ có mức xử lý lên tới hàng tỷ(109). Tuy nhiên để đạt được độ thông minh như những sinh vật sống còn cần nhiều thời gian hơn và các hệ thống tự động còn cần tích hợp trong nó nhiều công nghệ cao khác như công nghệ cảm biến, công nghệ vật liệu mới, công nghệ quang và laser v.v... Đây cũng là xu thế phát triển của các hệ thống tự động là ngày càng sử dụng nhiều công nghệ mới hơn trong cấu trúc và hoạt động của mình. Trong điều khiển quá trình công nghệ, việc áp dụng các hệ nhúng đã tạo ra khả năng tự động hóa toàn bộ dây chuyền sản xuất. Kiến trúc hệ thống điều khiển trước kia tập trung về xử lý tại một máy tính thì nay các đầu đo, cơ cấu chấp hành, giao diện với người vận hành đều được thông minh hóa có nhiều chức năng xử lý tại chỗ và khả năng nối mạng nhanh tạo thành hệ thống mạng máy điều khiển hoạt động theo chế độ thời gian thực. Ngoài các chức năng điều khiển và giám sát dây chuyền sản xuất hệ thống còn có nhiều cơ sở dữ liệu, khả năng tự xác định và khắc phục hỏng hóc, khả năng thống kê, báo cáo và kết hợp hệ thống mạng máy tính quản lý, lập kế hoạch, thiết kế và kinh doanh tạo thành hệ thống tự động hóa sản xuất toàn cục. Trong lĩnh vực rôbôt, với sự áp dụng các thành tựu của các hệ nhúng, rôbôt đã có thị giác và xúc giác. Việc áp dụng trí khôn nhân tạo vào rôbôt đã đưa rôbôt từ ứng dụng chủ yếu trong công nghiệp sang các lĩnh vực dịch vụ và y tế. Kết hợp với các thành tựu của cơ điện tử, rôbôt ngày càng uyển chuyển và thông minh hơn. Trong tương lai rôbôt không chỉ thay thế hoạt động cơ bắp của con người mà còn có thể thay thể các công việc đòi hỏi họat động trí não của con người. Lúc này hệ thống điều khiển của rôbôt không chỉ là các vi xử lý mạnh mà còn có sự hỗ trợ của các máy tính mạng nơron nhân tạo, xử lý song song nhúng trong rôbôt. Các nghiên cứu phát triển này hiện nay còn ở giai đoạn ban đầu. 1.4 Đặc tính, phương pháp thiết kế và xu thế phát triển của các hệ nhúng Các hệ nhúng là những hệ kết hợp phần cứng và phần mềm một cách tối ưu. Các Chương I: Tổng quan Bài giảng lập trình nhúng 5 hệ nhúng là những hệ chuyên dụng, thường hoạt động trong chế độ thời gian thực, bị hạn chế về bộ nhớ, giá thành phải rẻ nhưng lại phải hoạt động tin cậy và tiêu tốn ít năng lượng. Các hệ nhúng rất đa dạng và có nhiều kích cỡ, khả năng tính toán khác nhau. Ngoài ra các hệ nhúng thường phải hoạt động trong môi trường khắc nghiệt có độ nóng ẩm, rung xóc cao. Ví dụ như các điều khiển các máy diesel cho tàu biển, các thiết bị cảnh báo cháy nổ trong hầm lò. Các hệ thống nhúng lớn thường là các hệ nối mạng. Ở máy bay, tàu vũ trụ thường có nhiều mạng nhúng kết nối để kiểm soát hoạt động và điều khiển.Trong ô tô hiện đại có đến trên 80 nút mạng kết nối các đầu đo cơ cấu chấp hành để bảo đảm ô tô hoạt động an toàn và thoải mái cho người sử dụng. Thiết kế các hệ thống nhúng là thiết kế phần cứng và phần mềm phối hợp. Cách thiết kế cổ điển là cách xác định trước các chức năng phần mềm (SW) và phần cứng (HW) rồi sau đó các bước thiết kế chi tiết được tiến hành một cách độc lập ở hai khối. Hiện nay đa số các hệ thống tự động hóa thiết kế (CAD) thường dành cho thiết kế phần cứng. Các hệ thống nhúng hiện nay sử dụng đồng thời nhiều công nghệ như vi xử lý, DSP, mạng và các chuẩn phối ghép, protocol, do vậy xu thế thiết kế các hệ nhúng hiện nay đòi hỏi có khả năng thay đổi mề ... àm này sẽ tạo ra một sóng vuông ở tần số được định trước (chỉ nửa chu kỳ) tại một pin digital bất kỳ (analog vẫn được). Thời hạn của quá trình tạo ra sóng âm có thể được định trước hoặc nó sẽ phát ra âm thanh liên tục cho đến khi Arduino IDE chạy hàm noTone(). Chân digital đó cần được kết nối tới một buzzer hoặc một loa để có thể phát được âm thanh. Lưu ý rằng, chỉ có thể sử dụng duy nhất mộ hàm tone() trong cùng một thời điểm. Nếu hàm tone() đang chạy trên một pin nào đó, bây giờ lại tone() thêm một lần nữa thì hàm tone() sau sẽ không có hiệu lực. Nếu tone() lên pin đang được tone() thì hàm tone() sau sẽ thay đổi tần số sóng của pin đó. Trên mạch Arduino Mega, sử dụng hàm tone() thì sẽ can thiệp đến đầu ra PWM tại các chân digital 3 và digital 11. Hàm tone() sẽ không thể phát ra âm thanh có tần số < 31 Hz. Để biết têm về kĩ thuật này, hãy xem trang này. Chú ý: Nếu muốn chơi nhiều cao độ khác nhau trên nhiều pin. Thì trước khi chơi trên một pin khác thì phải noTone() trên pin đang được sử dụng. Cú pháp tone(pin, frequency) tone(pin, frequency, duration) Tham số pin: cổng digial / analog muốn chơi nhạc (nói cách khác là pin được kết nối tới loa) frequency: tần số của sóng vuông (sóng âm) - unsigned int duration: thời gian phát nhạc, đơn vị là mili giây (tùy chọn) - unsigned long Trả về không Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 97 Ví dụ Phát nhạc bằng Arduino với một cái loa hoặc buzzer 4.2.3.7.2 noTone() Hàm này có nhiệm vụ kết thúc một sự kiện tone() trên một pin nào đó (đang chạy lệnh tone()). Nếu không có bất kỳ hàm tone() nào đang hoạt động thì hàm này sẽ không gây bất kỳ ảnh hưởng gì đến chương trình. Chú ý: Nếu muốn chơi nhiều cao độ khác nhau trên nhiều pin. Thì trước khi chơi trên một pin khác thì b phải noTone() trên pin đang được sử dụng. Cú pháp noTone(pin) Tham số pin: cổng digial / analog muốn chơi nhạc (nói cách khác là pin được kết nối tới loa) Trả về Không 4.2.3.7.3 shiftOut() shiftOut() có nhiệm vụ chuyển 1 byte (gồm 8 bit) ra ngoài từng bit một. Bit được chuyển đi có thể được bắt đầu từ bit nằm bên trái nhất (leftmost) hoặc từ bit nằm bên phải nhất (rightmost). Các bit này được xuất ra tại chân dataPin sau khi chân clockPin được pulsed (có mức điện thế là HIGH, sau đó bị đẩy xuống LOW). Lưu ý: Nếu đang giao tiếp với một thiết bị mà chân clock của nó có giá trị được thay đổi từ mức điện thế LOW lên HIGH (rising edge) khi shiftOut, thì cần chắc chắn rằng chân clockPin cần được chạy lệnh này: digitalWrite(clockPin,LOW); Cú pháp shiftOut(dataPin, clockPin, bitOrder, value) Tham số dataPin: pin sẽ được xuất ra tín hiệu (int) clockPin: pin dùng để xác nhận việc gửi từng bit của dataPin (int) bitOrder: một trong hai giá trị MSBFIRST hoặc LSBFIRST. (Bắt đầu từ bit bên phải nhất hoặc Bắt đầu từ bit bên trái nhất) value: dữ liệu cần được shiftOut. (byte) Chú ý shiftOut() chỉ xuất được dữ liệu kiểu byte. Nếu muốn xuất một kiểu dữ liệu lớn hơn thì phải shiftOut 2 lần (hoặc nhiều hơn), mỗi lần là 8 bit. Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 98 Trả về không Ví dụ Điều khiển 8 đèn LED sáng theo ý muốn. 4.2.3.7.4 pulseIn() Đọc một xung tín hiệu digital (HIGH/LOW) và trả về chu kì của xung tín hiệu, tức là thời gian tín hiệu chuyển từ mức HIGH xuống LOW hoặc ngược lại (LOW -> HIGH). Một số cảm biến như cảm biến màu sắc như TCS3200D hay cảm biến siêu âm dòng HC-SRxx phải giao tiếp qua xung tín hiệu nên ta phải kết hợp giữa 2 hàm digitalWrite() để xuất tín hiệu và pulseIn() để đọc tín hiệu. Cú pháp pulseIn(pin, value); pulseIn(pin, value, timeout); Trong đó: pin là chân được chọn để đọc xung. pin có kiểu dữ liệu là int. Nếu đặt value là HIGH, hàm pulseIn() sẽ đợi đến khi tín hiệu đạt mức HIGH, khởi động bộ đếm thời gian. Khi tín hiệu nhảy xuống LOW, bộ đếm thời gian dừng lại. pulseIn() sẽ trả về thời gian tín hiệu nhảy từ mức HIGH xuống LOW này. Nếu đặt value là LOW, hàm pulseIn() sẽ làm ngược lại, đó là đo thời gian tín hiệu nhảy từ mức LOW lên HIGH. value có kiểu dữ liệu là int. Nếu tín hiệu luôn ở một mức HIGH/LOW cố định thì sau khoảng thời gian timeout, hàm pulseIn() sẽ dừng bộ đếm thời gian và trả về giá trị 0. timeout được tính bằng đơn vị micro giây. Giá trị mặc định của timeout là 60.106 tương ứng với 1 phút. Giá trị tối đa là 180.106 tương ứng với 3 phút. timeout có kiểu dữ liệu là unsigned long. Trả về Một số nguyên kiểu unsigned long, đơn vị là micro giây. pulseIn() trả về 0 nếu thời gian nhảy trạng thái HIGH/LOW vượt quá timeout Ví dụ int pin = 7; unsigned long duration; void setup() { Serial.begin(9600); pinMode(pin, INPUT); } Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 99 void loop() { duration = pulseIn(pin, HIGH); //Hãy nối chân 7 của Arduino vào đường tín hiệu //muốn đọc xung Serial.println(duration); } 4.2.3.8 Bits và Bytes 4.2.3.8.1 lowByte() lowByte() là hàm trả về byte cuối cùng (8 bit cuối cùng) của một chuỗi các bit. Một số nguyên bất kì cũng được xem như là một chuỗi các bit, vì bất kì số nguyên nào cũng có thể biểu diễn ở hệ nhị phân dưới dạng các bit "0" và "1". Lưu ý: lowByte() không nhận giá trị thuộc kiểu dữ liệu số thực. Cú pháp lowByte([giá trị cần lấy ra 8 bit cuối]); Trả về byte Ví dụ int A = lowByte(0B11110011001100); //A = 0B11001100 = 204; int B = lowByte(511); //B = lowByte(0B111111111) = 255; int C = lowByte(5); //C = lowByte(0B00000101) = 0B101 = 5; 4.2.3.8.2 highByte() highByte() là hàm trả về một chuỗi 8 bit kề với 8 bit cuối cùng của một chuỗi các bit. Như vậy, nếu dữ liệu đưa vào một chuỗi 16bit thìhighByte() sẽ trả về 8 bit đầu tiên, nếu dữ liệu đưa vào là một chuỗi 8bit hoặc nhỏ hơn, highByte() sẽ trả về giá trị 0. Một số nguyên bất kì cũng được xem như là một chuỗi các bit, vì bất kì số nguyên nào cũng có thể biểu diễn ở hệ nhị phân dưới dạng các bit "0" và "1". Lưu ý: highByte() không nhận giá trị thuộc kiểu dữ liệu số thực. Cú pháp highByte([giá trị đưa vào]); Trả về byte Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 100 Ví dụ int A = highByte(0B1111111100000000); //A = 0B11111111 = 255; int B = highByte(0B10101010); //B = 0 int C = highByte(0B110000000011111111) //C = 0B00000000 = 0 int D = highByte(1023); //D = highByte(0B111111111) = 0B11 = 3 4.2.3.8.3 bitRead() bitRead() sẽ trả về giá trị tại một bit nào đó được xác định bởi người lập trình của một số nguyên. Cú pháp bitRead(x, n) Tham số x: một số nguyên thuộc bất cứ kiểu số nguyên nào n: bit cần đọc. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0 Trả về Giá trị của 1 bit (1 hoặc là 0) Ví dụ bitRead(B11110010,0); // trả về 0 bitRead(B11110010,1); // trả về 1 bitRead(B11110010,2); // trả về 0 //Hàm bitRead có thể viết như sau B11110010 >> 0 & 1 // = 0 B11110010 >> 1 & 1 // = 1 B11110010 >> 2 & 1 // = 0 4.2.3.8.4 bitWrite() bitWrite() sẽ ghi đè bit tại một vị trí xác định của số nguyên. Cú pháp bitWrite(x, n, b) Tham số x: một số nguyên thuộc bất cứ kiểu số nguyên nào n: vị trí bit cần ghi. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0. b: 1 hoặc 0 Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 101 Trả về không Ví dụ bitWrite(B11110010,0,1); // B11110011 bitWrite(B11110010,1,0); // B11110000 bitWrite(B11110010,2,1); // B11110110 //Hàm bitWrite có thể viết như sau B11110010 | (1 << 0) // = B11110011 B11110010 & ~(1 << 1) // = B11110000 B11110010 | (1 << 2) // = B11110110 4.2.3.8.5 bitSet() bitSet() sẽ thay giá trị tại một bit xác định của một số nguyên thành 1. Cú pháp bitSet(x, n) Tham số x: một số nguyên thuộc bất cứ kiểu số nguyên nào n: vị trí bit cần ghi. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0. Trả về không Ví dụ bitSet(B11110010,0); // B11110011 bitSet(B11110010,2); // B11110110 //Hàm bitSet có thể viết như sau B11110010 | (1 << 0) // = B11110011 B11110010 | (1 << 2) // = B11110110 4.2.3.8.6 bitClear() bitClear() sẽ thay giá trị tại một bit xác định của một số nguyên thành 0. Cú pháp bitClear(x, n) Tham số x: một số nguyên thuộc bất cứ kiểu số nguyên nào Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 102 n: vị trí bit cần ghi. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0. Trả về không Ví dụ bitClear(B11110010,1); // B11110000 //Hàm bitClear có thể viết như sau B11110010 & ~(1 << 1) // = B11110000 4.2.3.8.7 bit() Trả về một số nguyên dạng 2n (2 mũ n). Cú pháp bit(n) Tham số n: số nguyên Trả về một số nguyên Ví dụ bit(0); // 2^0 = 1 bit(1); // 2^1 = 2 bit(2); // 2^2 = 4 bit(8); // 2^8 = 256 // cũng có thể viết như sau 1 << 0 // = 1 1 << 1 // = 2 1 << 2 // = 4 1 << 8 // = 256 4.2.3.9 Ngắt (interrupt) 4.2.3.9.1 attachInterrupt() Ngắt (interrupt) là những lời gọi hàm tự động khi hệ thống sinh ra một sự kiện. Những sự kiện này được nhà sản xuất vi điều khiển thiết lập bằng phần cứng và được cấu hình trong phần mềm bằng những tên gọi cố định. Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 103 Vì ngắt hoạt động độc lập và tự sinh ra khi được cấu hình nên chương trình chính sẽ đơn giản hơn. Một ví dụ điển hình về ngắt là hàm millis(). Hàm này tự động chạy cùng với chương trình và trả về 1 con số tăng dần theo thời gian mặc dù chúng ta không cài đặt nó. Việc cài đặt hàmmillis() sử dụng đến ngắt và được cấu hình tự động bên trong mã chương trình Arduino. Vì sao cần phải dùng đến ngắt? Ngắt giúp chương trình gọn nhẹ và xử lý nhanh hơn. Chẳng hạn, khi kiểm tra 1 nút nhấn có được nhấn hay không, thông thường cần kiểm tra trạng thái nút nhấn bằng hàm digitalRead() trong đoạn chương trình loop(). Với việc sử dụng ngắt, chỉ cần nối nút nhấn đến đúng chân có hỗ trợ ngắt, sau đó cài đặt ngắt sẽ sinh ra khi trạng thái nút chuyển từ HIGH- >LOW. Thêm 1 tên hàm sẽ gọi khi ngắt sinh ra. Vậy là xong, biến trong đoạn chương trình ngắt sẽ cho ta biết trạng thái nút nhấn. Số lượng các ngắt phụ thuộc vào từng dòng vi điều khiển. Với Arduino Uno chỉ có 2 ngắt, Mega 2560 có 6 ngắt và Leonardo có 5 ngắt. Board int.0 int.1 int.2 int.3 int.4 int.5 Uno, Ethernet 2 3 Mega2560 2 3 21 20 19 18 Leonardo 3 2 0 1 7 Cú pháp attachInterrupt(interrupt, ISR, mode); Thông số interrupt: Số thứ tự của ngắt. Trên Arduino Uno, có 2 ngắt với số thứ tự là 0 và 1. Ngắt số 0 nối với chân digital số 2 và ngắt số 1 nối với chân digital số 3. Muốn dùng ngắt phải gắn nút nhấn hoặc cảm biến vào đúng các chân này thì mới sinh ra sự kiện ngắt. Nếu dùng ngắt số 0 mà gắn nút nhấn ở chân digital 4 thì không chạy được rồi. ISR: tên hàm sẽ gọi khi có sự kiện ngắt được sinh ra. mode: kiểu kích hoạt ngắt, bao gồm LOW: kích hoạt liên tục khi trạng thái chân digital có mức thấp HIGH: kích hoạt liên tục khi trạng thái chân digital có mức cao. RISING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp thấp sang mức điện áp cao. FALLING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp cao sang mức điện áp thấp. Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 104 Lưu ý: với mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital còn giữ mức điện áp tương ứng. Trả về không Ví dụ Đoạn chương trình dưới đây sẽ làm sáng đèn led khi không nhấn nút và làm đèn led tắt đi khi người dùng nhấn nút, nếu vẫn giữ nút nhấn thì đèn led vẫn còn tắt. Sau khi thả nút nhấn, đèn led sẽ sáng trở lại. int ledPin = 13; void tatled() { digitalWrite(ledPin, LOW); // tắt đèn led } void setup() { pinMode(ledPin, OUTPUT); pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0 attachInterrupt(0, tatled, LOW); // gọi hàm tatled liên tục khi còn nhấn nút } void loop() { digitalWrite(ledPin, HIGH); // bật đèn led } Một ví dụ khác khi sử dụng ngắt, có thể thoát khỏi các hàm delay để xử lý 1 đoạn chương trình khác int ledPin = 13; void tatled() { // tắt đèn led khi nhấn nút, nhả ra led nhấp nháy trở lại digitalWrite(ledPin, LOW); } void setup() Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 105 { pinMode(ledPin, OUTPUT); pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0 attachInterrupt(0, tatled, LOW); } void loop() { // đoạn chương trình này nhấp nháy led sau 500ms digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); } 4.2.3.9.2 detachInterrupt() Hàm detachInterrupt() sẽ tắt các ngắt đã được kích hoạt tương ứng với thông số truyển vào. Giả sử sau khi nhấn nút bấm lần đầu tiên đèn led sẽ tắt nhưng nhấn lần thứ 2 đèn sẽ không tắt nữa. Lúc này cần dùng đến detachInterrupt() để tắt ngắt chúng ta đã tạo ra. Cú pháp detachInterrupt(interrupt); Thông số interrupt: số thứ tự ngắt (xem thêm ở bài attachInterrupt() ) Trả về không Ví dụ Đoạn chương trình dưới đây sẽ bật sáng đèn led và chỉ tắt nó khi nhấn lần đầu tiên, thả ra đèn sẽ sáng lại. Nếu tiếp tục nhấn nữa thì đèn vẫn sáng mà không bị tắt đi. int ledPin = 13; // đèn LED được kết nối với chân digital 13 boolean daNhan = false; // lưu giữ giá trị cho biết đã nhấn nút hay chưa void tatled() { digitalWrite(ledPin, LOW); // tắt đèn led khi còn nhấn nút daNhan = true; // lúc này đã nhấn nút Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 106 } void setup() { pinMode(ledPin, OUTPUT); // thiết đặt chân ledPin là OUTPUT pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0 attachInterrupt(0, tatled, LOW); // cài đặt ngắt gọi hàm tatled } void loop() { digitalWrite(ledPin, HIGH); // bật đèn led if (daNhan == true) { // Nếu đã nhấn nút thì tắt ngắt đi detachInterrupt(0); } } 4.2.3.9.3 interrupts() Mặc định, Arduino luôn bật các ngắt nên trong phần setup(), không cần gọi hàm này để bật các ngắt. Hàm interrupts() sẽ bật toàn bộ các ngắt đã được cài đặt. Nếu vì lý do nào đó ta tắt các ngắt bằng hàm noInterrupts(), sử dụng hàm này để bật lại các ngắt. Cú pháp interrupts(); Thông số không Trả về không Ví dụ void setup() {} void loop() { noInterrupts(); // tắt các ngắt để chạy Chương IV: Phần mềm nhúng Bài giảng lập trình nhúng 107 // đoạn chương trình yêu cầu cao về thời gian interrupts(); // bật lại các ngắt, các ngắt hoạt động // bình thường trở lại } 4.2.3.9.4 noInterrupts() Khi cần chạy các đoạn chương trình yêu cầu chính xác về thời gian, cần tắt các ngắt để Arduino chỉ tập trung vào xử lý các tác vụ cần thiết và chỉ duy nhất các tác vụ này. Các ngắt chạy nền sẽ không được thực thi sau khi gọi hàm noInterrupts(). Cú pháp noInterrupts(); Thông số không Trả về không Ví dụ void setup() {} void loop() { noInterrupts(); // tắt các ngắt để chạy // đoạn chương trình yêu cầu cao về thời gian interrupts(); // bật lại các ngắt, các ngắt hoạt động // bình thường trở lại }
File đính kèm:
- giao_trinh_lap_trinh_nhung.pdf