{"id":1008,"date":"2024-07-17T19:04:13","date_gmt":"2024-07-17T17:04:13","guid":{"rendered":"https:\/\/www.pinguytaz.net\/?p=1008"},"modified":"2024-07-14T19:01:29","modified_gmt":"2024-07-14T17:01:29","slug":"rust-embebido-arduino-interrupciones-externas-parte-5","status":"publish","type":"post","link":"https:\/\/www.pinguytaz.net\/index.php\/2024\/07\/17\/rust-embebido-arduino-interrupciones-externas-parte-5\/","title":{"rendered":"Rust-Embebido \u00abArduino\u00bb Interrupciones externas parte 5"},"content":{"rendered":"\n<p>Llegamos a la quinta entrega de esta programaci\u00f3n embebida de Arduino con Rust:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.pinguytaz.net\/index.php\/2024\/06\/09\/rust-embebido-arduino-introduccion-parte-1\/\" title=\"Rust-Embebido \u00abArduino\u00bb Introducci\u00f3n parte 1\">Introducci\u00f3n parte 1<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.pinguytaz.net\/index.php\/2024\/06\/29\/rust-embebido-arduino-e-s-digitales-parte-2\/\" title=\"Rust-Embebido \u00abArduino\u00bb E\/S Digitales parte 2\">E\/S Digitales parte 2<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.pinguytaz.net\/index.php\/2024\/07\/03\/rust-embebido-arduino-entradas-analogicas-parte-3\/\" title=\"Rust-Embebido \u00abArduino\u00bb Entradas anal\u00f3gicas parte 3\">Entradas anal\u00f3gicas parte 3<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.pinguytaz.net\/index.php\/2024\/07\/09\/rust-embebido-arduino-pwm-parte-4\/\" data-type=\"post\" data-id=\"1006\">PWM parte 4<\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Continuamos con la quinta entrega en la que explicaremos un tema muy interesante de como utilizar las interrupciones externas.<\/p>\n\n\n\n<p>Tenemos dos interrupciones externas que se activa en diferentes pines:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>INT0<\/strong> Se activara mediante el pin digital D2<\/li>\n\n\n\n<li><strong>INT1<\/strong> Se activara mediante el pin digital D3<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Definiremos una funci\u00f3n callback para el tratamiento de la <strong> ISR<\/strong> (Interruption Service Rutine) esta funci\u00f3n no tendr\u00e1 par\u00e1metros ni retorno solamente ejecutara c\u00f3digo, las reglas basicas de las <strong>funciones ISR<\/strong> son:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cortas y r\u00e1pidas<\/li>\n\n\n\n<li>No usar funciones de tiempo<\/li>\n\n\n\n<li>Dentro de la funci\u00f3n ISR los datos serie pueden perderse, por lo que no es buen idea su lectura.<\/li>\n\n\n\n<li>Para imprimir por consola, por ejemplo para saber cuando entra y que quede registro, se usaria una bandera y luego fuera ver si esta activa imprimelo que queramos.<\/li>\n\n\n\n<li>Si usamos variables que tienen que ser usada dentro y fuera de la funci\u00f3n deber\u00e1 declararse como std::sync::atomic.<\/li>\n<\/ul>\n\n\n\n<p>Para su programaci\u00f3n lo primero es hacer que el compilador aplique la convenci\u00f3n de llamada correcta a los controladores de interrupci\u00f3n mediante el siguiente c\u00f3digo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!&#91;feature(abi_avr_interrupt)]<\/code><\/pre>\n\n\n\n<p>Para habilitar una interrupci\u00f3n externa (INT0 o INT1) debemos tocar los registros <strong>EICRA<\/strong>(Registro de control de interrupciones A) que se ve en la figura y el registro <strong>EIMSK<\/strong> que es la mascara de las interrupciones externas<\/p>\n\n\n\n<figure class=\"wp-block-image alignleft size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"671\" height=\"100\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image.png\" alt=\"\" class=\"wp-image-1078\" style=\"width:805px;height:auto\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image.png 671w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-300x45.png 300w\" sizes=\"auto, (max-width: 671px) 100vw, 671px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-text-align-left\">Registro <strong>EICRA<\/strong> (Registro de control de interrupciones A)<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image alignleft size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"677\" height=\"105\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-2.png\" alt=\"\" class=\"wp-image-1080\" style=\"width:711px;height:auto\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-2.png 677w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-2-300x47.png 300w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Registro EIMSK (Registro de mascara de interrupciones externas<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Donde se ve que tenemos dos bits para la configuraci\u00f3n de la interrupci\u00f3n <strong>INT0<\/strong> que corresponde al registro <strong>ISC0<\/strong> y la interrupci\u00f3n <strong>INT1<\/strong> que usa el registro <strong>ISC1<\/strong> y los valores que pueden tomarse se ven en la siguiente tabla.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image alignleft size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"385\" height=\"155\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-1.png\" alt=\"\" class=\"wp-image-1079\" style=\"width:292px;height:auto\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-1.png 385w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2024\/07\/image-1-300x121.png 300w\" sizes=\"auto, (max-width: 385px) 100vw, 385px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Habilitamos INT0 en flanco de bajada, es decir al pulsar el bot\u00f3n \ndp.EXINT.eicra.modify(|_, w| w.isc0().bits(0x02));     \/\/ Registro EICRA isc0() Bits 0:1  \n\ndp.EXINT.eimsk.modify(|_, w| w.int0().set_bit());     \/\/  Registro EIMSK INT0 bit0 a 1. <\/code><\/pre>\n\n\n\n<p>Con los registros EICRA y EIMSK configurados debemos habilitar las interrupciones indicando que se trata de c\u00f3digo inseguro \u00ab<em>unsafe<\/em>\u00ab<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsafe { avr_device::interrupt::enable() };        \/\/ Habilita las interrupciones<\/code><\/pre>\n\n\n\n<p>Y ya solo nos queda definir la funci\u00f3n de tratamiento de la <strong>ISR<\/strong>, recordando que no tienen ni par\u00e1metros ni retorno as\u00ed que la comunicaci\u00f3n con el exterior lo deber\u00e1 realizar con variables globales, para ser m\u00e1s exacto variables at\u00f3micas.<\/p>\n\n\n\n<p>Las variables at\u00f3micas son de dos tipos (8bits y booleana) y para usarla tenemos tres funciones<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Declaraci\u00f3n de variables atomicas\nstatic ESTADO: AtomicI8 = AtomicI8::new(0);     \/\/ 8 bits\nstatic REBOTE: AtomicBool = AtomicBool::new(false);    \/\/ Boolean\n\n\/\/ Uso de las variables at\u00f3micas\nESTADO.load(Ordering::SeqCst);   \/\/ Recoge el valor de la variable ESTADO\nESTADO.store(12, Ordering::SeqCst);   \/\/ Cambia a 12 el valor de ESTADO\nREBOTE.store(true, Ordering::SeqCst);   \/\/ Cambia a true REBOTE<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Y ya solo nos queda definir la funci\u00f3n ISR que tratara la interrupci\u00f3n cuando se produzca.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#&#91;avr_device::interrupt(atmega328p)]\nfn INT0() {  \u2026 }     Interrupci\u00f3n 0 que se activa en el pin2.\n#&#91;avr_device::interrupt(atmega328p)]\nfn INT1() {  \u2026 }     Interrupci\u00f3n 0 que se activa en el pin3.<\/code><\/pre>\n\n\n\n<p>Tenemos un c\u00f3digo de ejemplo en <a href=\"https:\/\/github.com\/pinguytaz\/Arduino-ESP32\/blob\/master\/CuadernoTecnico\/RustArduino\/src\/bin\/intexternas.rs\">https:\/\/github.com\/pinguytaz\/Arduino-ESP32\/blob\/master\/CuadernoTecnico\/RustArduino\/src\/bin\/intexternas.rs<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Llegamos a la quinta entrega de esta programaci\u00f3n embebida de Arduino con Rust: Continuamos con la quinta entrega en la que explicaremos un tema muy interesante de como utilizar las interrupciones externas. Tenemos dos interrupciones externas que se activa en diferentes pines: Definiremos una funci\u00f3n callback para el tratamiento de la ISR (Interruption Service Rutine) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":996,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[3,186],"tags":[23,187],"class_list":["post-1008","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-rust","tag-arduino","tag-rust"],"_links":{"self":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts\/1008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/comments?post=1008"}],"version-history":[{"count":6,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts\/1008\/revisions"}],"predecessor-version":[{"id":1088,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts\/1008\/revisions\/1088"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/media\/996"}],"wp:attachment":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/media?parent=1008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/categories?post=1008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/tags?post=1008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}