{"id":99,"date":"2014-08-30T12:00:53","date_gmt":"2014-08-30T11:00:53","guid":{"rendered":"http:\/\/www.jelectronique.com\/?p=99"},"modified":"2014-08-30T16:43:42","modified_gmt":"2014-08-30T15:43:42","slug":"tuto-asf-timer-en-mode-normal","status":"publish","type":"post","link":"https:\/\/www.jelectronique.com\/?p=99","title":{"rendered":"TUTO XMEGA (ASF) : Timer en mode NORMAL"},"content":{"rendered":"<p>La derniere version de ce tuto est disponible sur le <a href=\"http:\/\/wiki.jelectronique.com\/doku.php?id=avr_studio_6#timer\">WIKI <\/a><\/p>\n<div class=\"level3\">\n<p>Cr\u00e9er un nouveau projet ASF.<\/p>\n<p>Importer les librairies qui sont n\u00e9cessaires. Cliquer sur ASF \u2192 ASF Wizard. Chercher les librairies suivantes :<\/p>\n<ul>\n<li class=\"level1\">\n<div class=\"li\">TC &#8211; Timer Counter (driver)<\/div>\n<\/li>\n<li class=\"level1\">\n<div class=\"li\">GPIO &#8211; G\u00e9n\u00e9ra purpose Input\/Output<\/div>\n<\/li>\n<li class=\"level1\">\n<div class=\"li\">Generic board support (elle integre des fonctions qui seront necessaire pour utiliser la librairie delay)<\/div>\n<\/li>\n<li class=\"level1\">\n<div class=\"li\">IOPORT &#8211; G\u00e9n\u00e9ra purpose Input\/Output (Librairie que nous avons vu dans la partie entr\u00e9e\/sorties.<\/div>\n<\/li>\n<\/ul>\n<p><a class=\"media\" title=\"avr_studio_asf_timer.png\" href=\"http:\/\/wiki.jelectronique.com\/lib\/exe\/detail.php?id=avr_studio_6&amp;media=avr_studio_asf_timer.png\"><img decoding=\"async\" class=\"media\" src=\"http:\/\/wiki.jelectronique.com\/lib\/exe\/fetch.php?w=800&amp;tok=bbd43e&amp;media=avr_studio_asf_timer.png\" alt=\"\" width=\"800\" \/><\/a><\/p>\n<p>Nous allons utiliser l&rsquo;horloge par d\u00e9faut de 2Mhz.<br \/>\nL&rsquo;objectif de cette exemple sera de faire clignoter une LED toutes les secondes.<\/p>\n<p>Dans le principe de fonctionnement, le timer est cadenc\u00e9 par une horloge. A chaque coup d&rsquo;horloge, le compteur va s&rsquo;incr\u00e9menter.<\/p>\n<p>Nous utiliserons le Timer 0 qui est un timer de 16bits. Il a donc, au maximum, 65535 pas d&rsquo;incr\u00e9mentation.<\/p>\n<p>Nous voulons que la LED s&rsquo;allume toutes les secondes. Le timer doit donc d\u00e9clencher un interruption toutes les 500ms.<\/p>\n<p>Avec un horloge \u00e0 2Mhz cela nous fait un pas d&rsquo;incr\u00e9mentation toutes 0.5\u00b5s m\u00eame si le compteur allait jusqu&rsquo;\u00e0 65535 cela nous ferait 33ms de temps entre chaque interruption sachant que nous voulons environ 500ms.<\/p>\n<p>Nous avons le choix entre les diviseurs suivants :<\/p>\n<pre class=\"code c\">    TC_CLKSEL_DIV1_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x01<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock *\/<\/span>\r\n    TC_CLKSEL_DIV2_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x02<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock \/ 2 *\/<\/span>\r\n    TC_CLKSEL_DIV4_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x03<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock \/ 4 *\/<\/span>\r\n    TC_CLKSEL_DIV8_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x04<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock \/ 8 *\/<\/span>\r\n    TC_CLKSEL_DIV64_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x05<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock \/ 64 *\/<\/span>\r\n    TC_CLKSEL_DIV256_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x06<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock \/ 256 *\/<\/span>\r\n    TC_CLKSEL_DIV1024_gc <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"nu12\">0x07<\/span><span class=\"sy0\">&lt;&lt;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">,<\/span>  <span class=\"coMULTI\">\/* System Clock \/ 1024 *\/<\/span><\/pre>\n<p>Nous allons donc diviser la fr\u00e9quence par 64. Ce qui nous fera un pas d&rsquo;incr\u00e9mentation toutes les 32\u00b5s. Pour avoir un p\u00e9riode de 500ms, il faudra que notre compteur compte jusqu&rsquo;\u00e0 500 000 \/ 32 = 15625<\/p>\n<pre class=\"code c\"><span class=\"co2\">#include &lt;asf.h&gt;<\/span>\r\n\u00a0\r\n<span class=\"co1\">\/\/Led<\/span>\r\n<span class=\"co2\">#define LED IOPORT_CREATE_PIN(PORTR, 1)<\/span>\r\n\u00a0\r\n<span class=\"co1\">\/\/D\u00e9clenchement toutes les 500ms<\/span>\r\n<span class=\"kw4\">static<\/span> <span class=\"kw4\">void<\/span> timer0_tick<span class=\"br0\">(<\/span><span class=\"kw4\">void<\/span><span class=\"br0\">)<\/span>\r\n<span class=\"br0\">{<\/span>\r\n\tioport_toggle_pin_level<span class=\"br0\">(<\/span>LED<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span> <span class=\"co1\">\/\/Inverse l'\u00e9tat de la LED<\/span>\r\n<span class=\"br0\">}<\/span>\r\n\u00a0\r\n<span class=\"kw4\">int<\/span> main <span class=\"br0\">(<\/span><span class=\"kw4\">void<\/span><span class=\"br0\">)<\/span>\r\n<span class=\"br0\">{<\/span>\r\n\t<span class=\"co1\">\/\/Initialisation du controleur d'interruptions<\/span>\r\n\tpmic_init<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\r\n\t<span class=\"co1\">\/\/Initialisation de l'horloge\t<\/span>\r\n\tsysclk_init<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\t\r\n\u00a0\r\n\t<span class=\"co1\">\/\/Initialisation des entr\u00e9es\/sorties<\/span>\r\n\tioport_set_pin_dir<span class=\"br0\">(<\/span>LED<span class=\"sy0\">,<\/span> IOPORT_DIR_OUTPUT<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\r\n\u00a0\r\n\t<span class=\"co1\">\/\/Initialisation du Timer 0<\/span>\r\n\ttc_enable<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\r\n\ttc_set_overflow_interrupt_callback<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> timer0_tick<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span> <span class=\"co1\">\/\/Cr\u00e9ation d'un callback qui sera execut\u00e9 quand un overflow du timer sera d\u00e9clench\u00e9.<\/span>\r\n\ttc_set_wgm<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> TC_WG_NORMAL<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\t<span class=\"co1\">\/\/Choix du mode du timer0, dans ce cas il comptera jusqu'\u00e0 sa valeur \"TOP\" et retombera \u00e0 0<\/span>\r\n\ttc_write_period<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> <span class=\"nu0\">15625<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\t\t<span class=\"co1\">\/\/D\u00e9finition de la valeur \"TOP\"\t<\/span>\r\n\ttc_set_overflow_interrupt_level<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> TC_INT_LVL_LO<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t<span class=\"co1\">\/\/Activation de l'interruption du timer <\/span>\r\n\tcpu_irq_enable<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\t\t\t\t\t\t\t\t\t<span class=\"co1\">\/\/Activation de l'interruption globale\t\t\t\t\t<\/span>\r\n\ttc_write_clock_source<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> TC_CLKSEL_DIV64_gc<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\t\t<span class=\"co1\">\/\/Activation de l'horloge du timer 0<\/span>\r\n\u00a0\r\n\tboard_init<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\r\n\u00a0\r\n\t<span class=\"kw1\">while<\/span><span class=\"br0\">(<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">)<\/span>\r\n\t<span class=\"br0\">{<\/span>\r\n\u00a0\r\n\t<span class=\"br0\">}<\/span>\r\n<span class=\"br0\">}<\/span><\/pre>\n<p>Explications :<\/p>\n<pre class=\"code C\">pmic_init<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>Initialise le controleur d&rsquo;interruption. Sans ca, les interruptions du timer ne se d\u00e9clencheront pas.<\/p>\n<pre class=\"code C\">sysclk_init<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>Initialise l&rsquo;horloge syst\u00e8me. Cf conf_clock.h (Horloge de 2Mhz sans pr\u00e9divison)<\/p>\n<pre class=\"code C\">tc_enable<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>Active le timer0<\/p>\n<pre class=\"code C\">tc_set_overflow_interrupt_callback<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> timer0_tick<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>D\u00e9finit que la fonction timer0_tick sera appel\u00e9e \u00e0 chaque interruption du timer 0. La fonction :<\/p>\n<pre class=\"code C\"><span class=\"kw4\">static<\/span> <span class=\"kw4\">void<\/span> timer0_tick<span class=\"br0\">(<\/span><span class=\"kw4\">void<\/span><span class=\"br0\">)<\/span>\r\n<span class=\"br0\">{<\/span>\r\n\tioport_toggle_pin_level<span class=\"br0\">(<\/span>LED<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span> <span class=\"co1\">\/\/Inverse l'\u00e9tat de la LED<\/span>\r\n<span class=\"br0\">}<\/span><\/pre>\n<p>sera execut\u00e9e toutes les 500ms<\/p>\n<pre class=\"code C\">tc_set_wgm<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> TC_WG_NORMAL<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>D\u00e9finit le mode de fonctionnement \u201cNormal\u201d du timer. Dans ce cas il comptera jusqu&rsquo;\u00e0 sa valeur \u201cTOP\u201d, d\u00e9clenchera l&rsquo;interruption overflow, repassera \u00e0 0 et ainsi de suite \u2026<\/p>\n<pre class=\"code C\">cpu_irq_enable<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>Activation globale des interruptions<\/p>\n<pre class=\"code C\">tc_write_clock_source<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>TCC0<span class=\"sy0\">,<\/span> TC_CLKSEL_DIV64_gc<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<p>On alimente le timer avec l&rsquo;horloge syst\u00e8me \/ 64<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>La derniere version de ce tuto est disponible sur le WIKI Cr\u00e9er un nouveau projet ASF. Importer les librairies qui sont n\u00e9cessaires. Cliquer sur ASF \u2192 ASF Wizard. Chercher les librairies suivantes : TC &#8211; Timer Counter (driver) GPIO &#8211;&hellip; <a href=\"https:\/\/www.jelectronique.com\/?p=99\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":26,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-99","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-electronique"],"_links":{"self":[{"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/posts\/99","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=99"}],"version-history":[{"count":6,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/posts\/99\/revisions"}],"predecessor-version":[{"id":108,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/posts\/99\/revisions\/108"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=\/wp\/v2\/media\/26"}],"wp:attachment":[{"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=99"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=99"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jelectronique.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=99"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}