<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=4&amp;t=20630&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2018-04-22T20:10:11+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=20630&amp;mode</id>
<entry>
<author><name><![CDATA[wojtekr]]></name></author>
<updated>2018-04-22T20:10:11+01:00</updated>
<published>2018-04-22T20:10:11+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207055#p207055</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207055#p207055"/>
<title type="html"><![CDATA[Re: Problem ze strukturą-  PROGMEM do obsługi menu]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207055#p207055"><![CDATA[
Dzięki, posprawdzam i dam znać<br /><br />Po gapieniu się w kod tak coś przeczuwałem, że z tymi CONST'ami to tak jakoś jest - na razie chciałem ogarnąć PROGMEM, rozwiązywanie takich problemów jest rozwijające, dopiero w drugim kroku docelowym chciałem użyć __FLASH<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=18360">wojtekr</a> — 22 kwi 2018, o 20:10</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2018-04-22T19:12:10+01:00</updated>
<published>2018-04-22T19:12:10+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207049#p207049</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207049#p207049"/>
<title type="html"><![CDATA[Re: Problem ze strukturą-  PROGMEM do obsługi menu]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207049#p207049"><![CDATA[
<div class="quotetitle">wojtekr napisał(a):</div><div class="quotecontent"><br />[syntax=c]ssd1306_numdec_font6x8(menu_ptr-&gt;sub_menu_value_speed);[/syntax]<br /></div><br />Wskaźnik <strong><em>menu_ptr</em></strong> wskazuje na pamięć programu (FLASH), więc aby odczytać wartość <strong><em>sub_menu_value_speed</em></strong> należy użyć makra <strong><em>pgm_read_byte()</em></strong>, czyli powinno być:[syntax=c]ssd1306_numdec_font6x8( pgm_read_byte(&amp;(menu_ptr-&gt;sub_menu_value_speed)) );<br />// nie wiem, jaki typ argumentu przyjmuje funkcja, ale może być konieczne rzutowanie, przykłaodwo:<br />ssd1306_numdec_font6x8( (const int16_t)pgm_read_byte(&amp;(menu_ptr-&gt;sub_menu_value_speed)) );[/syntax]<br />Należy pamiętać, że do odczytu np. zmiennej 16-bitowej należy użyć makra <strong><em>pgm_read_word()</em></strong>.<br /><br /><br /><em>Dlaczego raz działa a raz nie?</em><div class="quotetitle">wojtekr napisał(a):</div><div class="quotecontent"><br />[syntax=c]//Tak działa - dla każdej wartości za zakresu 0-5<br />const Menu_Struct *menu_ptr = &amp;menu&#91;2&#93;;<br /> <br />//Tak działa - dla każdej wartości za zakresu 0-5<br />uint8_t menu_pos=2;<br />const Menu_Struct *menu_ptr = &amp;menu&#91;menu_pos&#93;;<br /> <br />//tak działa częściowo - czyli nie działa<br />uint8_t menu_pos=1;<br />if(++menu_pos&gt;5) menu_pos=0;<br />const Menu_Struct *menu_ptr = &amp;menu&#91;menu_pos&#93;;[/syntax]<br /></div><br />Zauważ, że w pierwszym i drugim przypadku wartość indeksu tablicy struktur jest znana na etapie kompilacji. Kompilator zna więc wartość wskaźnika do struktury (<strong><em>menu_ptr</em></strong>) i może w procesie optymalizacji zastąpić wyrażenie <strong><em>menu_ptr-&gt;sub_menu_value_speed</em></strong> jego wartością.<br />Przykładowo można przyjąć co następuje:[syntax=c]// definiujemy wskaźnik, którego wartość może być obliczona w trakcie kompilacji<br />    const Menu_Struct *menu_ptr = &amp;menu&#91;2&#93;;<br /><br />// odwołujemy się do elementu struktury<br />    ssd1306_numdec_font6x8(menu_ptr-&gt;sub_menu_value_speed);<br /><br />// kompilator wie, że wartość elementu 'sub_menu_value_speed' w strukturze o indeksie 2<br />// w tablicy struktur 'menu&#91;&#93;' ma wartość 50, więc powyższą linijkę kodu traktuje jako<br />    ssd1306_numdec_font6x8(50);<br />// gdyż pozwala to zmniejszyć rozmiar kodu wynikowego i zwiększa szybkość działania<br />// w tym przypadku funkcja 'ssd1306_numdec_font6x8()' będzie działać prawidłowo[/syntax]<br /><br />Jeżeli natomiast do indeksowania tablicy użyjesz zmiennej, której wartość jest np. inkrementowana w pętli for(), to kompilator nie może zrobić tak jak powyżej. Musi wygenerować kod, który będzie dopiero w mikrokontrolerze docelowym realizował odczyt z odpowiedniej komórki pamięci. W tym przypadku zapis:[syntax=c]ssd1306_numdec_font6x8(menu_ptr-&gt;sub_menu_value_speed);[/syntax] spowoduje odczyt danych z pamięci RAM, a w rzeczywistości znajdują się przecież w pamięci FLASH.<br /><br />Proponuję zapoznać się z <a href="http://avr8bit.cba.pl/?doc=avr_flash_data"  class="postlink">kwalifikatorami <em>__flash</em> oraz <em>__memx</em></a> do definiowania danych w pamięci FLASH. Pozwoli to uniknąć tego typu kłopotów. <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 22 kwi 2018, o 19:12</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[wojtekr]]></name></author>
<updated>2018-04-22T12:10:57+01:00</updated>
<published>2018-04-22T12:10:57+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207037#p207037</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207037#p207037"/>
<title type="html"><![CDATA[Problem ze strukturą-  PROGMEM do obsługi menu]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=20630&amp;p=207037#p207037"><![CDATA[
Mam problem, którego kompletnie nie rozumiem.<br /><br />Zdefiniowałem strukturę do menu oraz tablicę:<br /><br />[syntax=c]typedef struct {<br />const char * menu_ptr;<br />const char * sub_menu_ptr;<br />uint16_t sub_menu_value_def;<br />uint16_t sub_menu_value_min;<br />uint16_t sub_menu_value_max;<br />uint8_t sub_menu_value_step;<br />uint8_t sub_menu_value_speed;<br />} Menu_Struct;<br /><br />const char menu_1_txt&#91;&#93; PROGMEM = &quot;     STROBE     &quot;;<br />const char s_menu_1_txt_1&#91;&#93; PROGMEM = &quot;DELAY           &quot;;<br />const char s_menu_1_txt_2&#91;&#93; PROGMEM = &quot;PERIOD          &quot;;<br />const char s_menu_1_txt_3&#91;&#93; PROGMEM = &quot;TIME            &quot;;<br /><br />const char menu_2_txt&#91;&#93; PROGMEM = &quot;     BEACON     &quot;;<br />const char s_menu_2_txt_1&#91;&#93; PROGMEM = &quot;SPEED           &quot;;<br /><br />const char menu_3_txt&#91;&#93; PROGMEM = &quot;     SERVO 1    &quot;;<br />const char s_menu_3_txt_1&#91;&#93; PROGMEM = &quot;CENTER          &quot;;<br /><br />const char menu_4_txt&#91;&#93; PROGMEM = &quot;    SETTINGS    &quot;;<br />const char s_menu_4_txt_1&#91;&#93; PROGMEM = &quot;SET DEFAULT     &quot;;<br /><br />const Menu_Struct menu&#91;&#93; PROGMEM = {<br />{menu_1_txt,s_menu_1_txt_1,10,550,570,1,50},<br />{menu_1_txt,s_menu_1_txt_2,20,400,600,1,50},<br />{menu_1_txt,s_menu_1_txt_3,30,1,1000,1,50},<br /><br />{menu_2_txt,s_menu_2_txt_1,40,500,700,1,50},<br /><br />{menu_3_txt,s_menu_3_txt_1,50,1000,2000,1,10},<br /><br />{menu_4_txt,s_menu_4_txt_1,60,0,1,1,100},<br />};[/syntax]<br /><br /><br />Po skompilowaniu i uruchomieniu na wyświetlaczu mam wszystko ok<br /><br />[syntax=c]int main() {<br />uint8_t menu_pos=0;<br /><br /><br /><br /><br />const Menu_Struct *menu_ptr = &amp;menu&#91;0&#93;;<br />draw_menu(menu_ptr,menu_pos,menu_ptr-&gt;sub_menu_value_def);<br />ssd1306_setpos(0,0);ssd1306_numdec_font6x8(menu_pos);<br />ssd1306_setpos(0,7);ssd1306_numdec_font6x8(menu_ptr-&gt;sub_menu_value_speed);<br />ssd1306_setpos(50,7);ssd1306_numdec_font6x8(menu_ptr-&gt;sub_menu_value_min);<br />ssd1306_setpos(90,7);ssd1306_numdec_font6x8(menu_ptr-&gt;sub_menu_value_max);[/syntax]<br /><br />Tak jak by się coś waliło z indeksem tablicy wskaźników po incrementacji:<br /><br /><br />[syntax=c]//Tak działa - dla każdej wartości za zakresu 0-5<br />const Menu_Struct *menu_ptr = &amp;menu&#91;2&#93;;<br /><br />//Tak działa - dla każdej wartości za zakresu 0-5<br />uint8_t menu_pos=2; <br />const Menu_Struct *menu_ptr = &amp;menu&#91;menu_pos&#93;;<br /><br />//tak działa częściowo - czyli nie działa<br />uint8_t menu_pos=1; <br />if(++menu_pos&gt;5) menu_pos=0;<br />const Menu_Struct *menu_ptr = &amp;menu&#91;menu_pos&#93;;[/syntax]<br /><br />w tym ostatnim przypadku draw_menu() działa (wyświetla teksty z const const char * menu_ptr i const char * sub_menu_ptr;)  a menu_ptr-&gt;sub_menu_value_speed i inne wyświetlają jakieś bzdury.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=18360">wojtekr</a> — 22 kwi 2018, o 12:10</p><hr />
]]></content>
</entry>
</feed>