EasySTM32 - Порты микроконтроллера.htm 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru-ru" dir="ltr" lang="ru-ru"><head>
  3. <!-- base href="http://easystm32.ru/for-beginners/11-mcu-ports" -->
  4. <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  5. <meta name="keywords" content="Микроконтроллеры, электроника, STM32">
  6. <meta name="author" content="Medved">
  7. <meta name="description" content="Микроконтроллеры STM32">
  8. <meta name="generator" content="Joomla! - Open Source Content Management">
  9. <title>EasySTM32 - Порты микроконтроллера</title>
  10. <link href="http://easystm32.ru/templates/shoplab/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
  11. <link href="http://easystm32.ru/component/search/?Itemid=108&amp;catid=10&amp;id=11&amp;format=opensearch" rel="search" title="Искать EasySTM32" type="application/opensearchdescription+xml">
  12. <style type="text/css">
  13. #wrapper { margin: 0 auto; width: 960px;padding:0;}
  14. .s-c-s #colmid { left:245px;}
  15. .s-c-s #colright { margin-left:-245px;}
  16. .s-c-s #col1pad { margin-left:245px;}
  17. .s-c-s #col2 { left:0px;width:245px;}
  18. .s-c-s #col3 { width:0px;}
  19. .s-c-x #colright { left:245px;}
  20. .s-c-x #col1wrap { right:245px;}
  21. .s-c-x #col1 { margin-left:245px;}
  22. .s-c-x #col2 { right:245px;width:245px;}
  23. .x-c-s #colright { margin-left:-0px;}
  24. .x-c-s #col1 { margin-left:0px;}
  25. .x-c-s #col3 { left:0px;width:0px;}
  26. </style>
  27. <script src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/mootools-core.js" type="text/javascript"></script>
  28. <script src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/core.js" type="text/javascript"></script>
  29. <script src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/caption.js" type="text/javascript"></script>
  30. <script src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/mootools-more.js" type="text/javascript"></script>
  31. <script type="text/javascript">
  32. window.addEvent('load', function() {
  33. new JCaption('img.caption');
  34. });
  35. function keepAlive() { var myAjax = new Request({method: "get", url: "index.php"}).send();} window.addEvent("domready", function(){ keepAlive.periodical(840000); });
  36. </script>
  37. <link type="text/css" rel="stylesheet" href="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/shCore.css">
  38. <link type="text/css" rel="stylesheet" href="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/shThemeDefault.css">
  39. <script type="text/javascript" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/shCore.js"></script>
  40. <script type="text/javascript" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/shBrushCpp.js"></script>
  41. <link rel="stylesheet" href="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/system.css" type="text/css">
  42. <link rel="stylesheet" href="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/styles.css" type="text/css" media="screen,projection">
  43. <script language="javascript" type="text/javascript">
  44. window.addEvent('domready', function(){
  45. var top_panel = document.id('top-panel');
  46. var sub_panel = document.id('sub-panel');
  47. var topFx = new Fx.Slide(top_panel);
  48. if (Cookie.read('top-panel') == '1') {
  49. topFx.show();
  50. } else {
  51. topFx.hide();
  52. }
  53. sub_panel.addEvents({
  54. 'click' : function(){
  55. if (topFx.open) {
  56. Cookie.write('top-panel', '0');
  57. } else {
  58. Cookie.write('top-panel', '1');
  59. }
  60. topFx.toggle();
  61. }
  62. });
  63. });
  64. </script>
  65. </head>
  66. <body>
  67. <div id="popup_name" class="popup_block">
  68. </div>
  69. <div class="topground"></div>
  70. <div id="main">
  71. <div id="wrapper">
  72. <div id="header"><div class="headtop"><div id="top-panel">
  73. <div class="currency"></div>
  74. </div>
  75. <div id="sub-panel">
  76. </div></div>
  77. <div class="logo">
  78. <a href="http://easystm32.ru/" id="logo" title="EasySTM32.ru"><img src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/logo.jpg" alt=""></a>
  79. </div>
  80. <div class="supertop"><div class="left"></div><div class="arm">
  81. <ul class="menu">
  82. <li class="item-106"><a href="http://easystm32.ru/donate">Donate!</a></li></ul>
  83. </div><div class="clr"></div></div>
  84. </div>
  85. <div id="navigace"><div class="levy">
  86. <img alt="" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/levy.png">
  87. </div> <div class="pravy">
  88. <img alt="" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/pravy.png">
  89. </div>
  90. <form action="/for-beginners" method="post">
  91. <div class="search">
  92. <input name="searchword" id="mod-search-searchword" maxlength="20" class="inputbox" size="20" value="Поиск..." onblur="if (this.value=='') this.value='Поиск...';" onfocus="if (this.value=='Поиск...') this.value='';" type="text"><input class="button" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/buttonsearch.png" onclick="this.form.searchword.focus();" alt="submit" type="image"><input name="task" value="search" type="hidden">
  93. <input name="option" value="com_search" type="hidden">
  94. <input name="Itemid" value="108" type="hidden">
  95. </div>
  96. </form>
  97. <ul class="menu">
  98. <li class="item-122"><a href="http://easystm32.ru/soft">Программы</a></li><li class="item-120"><a href="http://easystm32.ru/library">Библиотека</a></li><li class="item-119"><a href="http://easystm32.ru/about">О сайте</a></li><li class="item-121"><a href="http://easystm32.ru/contacts">Обратная связь</a></li><li class="item-123"><a href="http://easystm32.ru/links">Ссылки</a></li><li class="item-148"><a href="http://easystm32.ru/?format=feed&amp;type=rss">RSS</a></li></ul>
  99. </div>
  100. <div id="message">
  101. <div id="system-message-container">
  102. </div>
  103. </div>
  104. <div id="main-content" class="s-c-s">
  105. <div id="colmask">
  106. <div id="colmid">
  107. <div id="colright">
  108. <div id="col1wrap">
  109. <div id="col1pad">
  110. <div id="col1">
  111. <div class="component"><div class="breadcrumbs-pad">
  112. <script type="text/javascript">
  113. var begun_auto_pad = 353320856;
  114. var begun_block_id = 353320860;
  115. </script>
  116. <script src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/autocontext2.js" type="text/javascript"></script>
  117. </div><div class="item-page">
  118. <h2>
  119. <a href="http://easystm32.ru/for-beginners/11-mcu-ports">
  120. Порты микроконтроллера</a>
  121. </h2>
  122. <p style="text-align: justify;">Порты ввода/вывода пожалуй важнейшая
  123. часть микроконтроллера, без неё всё остальное просто бессмысленно.
  124. Сколько бы не было у контроллера памяти, периферии, какой бы высокой не
  125. была тактовая частота - это всё не имеет значения если он не может
  126. взаимодействовать с внешним миром. А взаимодействие это осуществляется
  127. через эти самые порты ввода/вывода. Далее для краткости будем называть
  128. их просто портами. Порт это некоторый именованный набор из 16-ти (как
  129. правило) ног контроллера, каждая из которых может быть индивидуально
  130. настроена и использована. Количество портов может различаться, например в
  131. контроллере установленном в отладочной плате STM32vl Discovery имеются
  132. три порта A,B,C. Существует два основных режима работы ног контроллера:
  133. вход и выход. Когда нога контроллера настроена на выход - к ней можно
  134. прицепить любой потребитель: светодиод, пищалку, да и вообще что угодно.
  135. Нужно понимать что ноги у контроллера не потянут большую нагрузку.
  136. Максимальный ток который может пропустить через себя одна нога
  137. составляет ~20 мА. Если планируется подключать что-то с более высоким
  138. энергопотреблением то нужно делать это через транзисторный ключ. В
  139. противном случае нога порта (а то и весь порт, чем черт не шутит) сгорит
  140. и перестанет выполнять свои функции. Чтобы обезопасить ногу порта можно
  141. прицепить к ней резистор номиналом примерно 220 ом. Таким образом при
  142. напряжении питания 3.3 вольта даже при коротком замыкании ноги на землю
  143. ток не превысит критического значения. &nbsp;Второй режим работы ноги
  144. контроллера - это вход. Благодаря этому режиму мы можем считывать
  145. например состояние кнопок, проверяя есть ли на ноге напряжение или нет.
  146. Это вкратце, а сейчас рассмотрим подробнее как работать с портами.
  147. Рассматривать будем конечно же на практике, благо что аппаратная часть
  148. (светодиоды и кнопка) для наших экспериментов уже реализована на плате
  149. STM32vl Discovery. Если же платы нет, то можно подключить к контроллеру
  150. светодиоды и кнопку следующим образом:&nbsp;</p>
  151. <p style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/schematic.png" alt="schematic" width="650"></p>
  152. <p style="text-align: center;">&nbsp;</p>
  153. <p>Для начала попробуем зажечь светодиоды, для этого мы должны произвести аж целых три действия:&nbsp;</p>
  154. <ol>
  155. <li>Включить тактирование порта</li>
  156. <li>Настроить две ножки как выходы</li>
  157. <li>Установить логическую единицу на 2-х выводах порта</li>
  158. </ol>
  159. <p>Для начала создадим проект в CooCox'e точно так же как мы <a href="http://easystm32.ru/for-beginners/8-soft-for-stm32">[делали ранее]</a>. Запишем в файл main.c следующий код и будем разбираться:&nbsp;</p>
  160. <p><span style="text-align: justify;"><script type="text/javascript">
  161. SyntaxHighlighter.config.clipboardSwf = "http://easystm32.ru/plugins/content/CodeCitation/codecitation/scripts/clipboard.swf";
  162. SyntaxHighlighter.defaults["auto-links"] = true;
  163. SyntaxHighlighter.defaults["collapse"] = false;
  164. SyntaxHighlighter.defaults["gutter"] = true;
  165. SyntaxHighlighter.defaults["smart-tabs"] = true;
  166. SyntaxHighlighter.defaults["tab-size"] = 4;
  167. SyntaxHighlighter.defaults["toolbar"] = true;
  168. SyntaxHighlighter.defaults["wrap-lines"] = true;
  169. SyntaxHighlighter.all();
  170. </script></span></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp">#include &lt;stm32f10x_rcc.h&gt;
  171. int main(void) {
  172. RCC-&gt;APB2ENR |= RCC_APB2Periph_GPIOC;
  173. GPIOC-&gt;CRH |=0x33;
  174. GPIOC-&gt;CRH &amp;= ~0xCC;
  175. GPIOC-&gt;ODR |= (GPIO_ODR_ODR9 | GPIO_ODR_ODR8);
  176. } </pre></div><p></p>
  177. <p>&nbsp;</p>
  178. <p style="text-align: justify;">Всего-то четыре строчки кода, но сколько
  179. смысла :) Для начала разберемся что значит "Включить тактирование
  180. порта". В контроллере полно периферии: Таймеры, АЦП, USART и т.д. Порт
  181. ввода/вывода является такой же периферией. Когда периферия включена
  182. (подаются тактовые импульсы) - она потребляет ток. Нет тактирования -
  183. нет потребления. По умолчанию вообще весь этот зоопарк периферии
  184. вырублен. Итак нас интересует порт C, ведь именно на нем висят наши
  185. светодиоды. Для включения/выключения периферии есть два регистра
  186. RCC_APB1ENR и RCC_APB2ENR. Нам нужен последний, потому что через него мы
  187. можем управлять тактированием порта C. Устроен этот регистр так:&nbsp;</p>
  188. <p><img style="border-style: initial; border-color: initial; border-image: initial; display: block; margin-left: auto; margin-right: auto; border-width: 0px;" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/rcc_apb2enr.png" alt="rcc_apb2enr" border="0" width="650"></p>
  189. <p style="text-align: justify;"><span style="text-align: justify;">Как видно на картинке в нем есть бит IOPCEN. Установив его в единицу мы включим наш порт. Именно это и делает строчка кода&nbsp;</span></p>
  190. <p></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp">RCC-&gt;APB2ENR |= RCC_APB2Periph_GPIOC;
  191. </pre></div><p></p>
  192. <p style="text-align: justify;">После включения тактирования мы должны
  193. настроить&nbsp;некоторые (а именно 8-ю и 9-ю)&nbsp;ноги порта на
  194. выход.&nbsp;За конфигурирование вообще любого
  195. порта&nbsp;отвечают&nbsp;два регистра GPIOx_CRL и GPIOx_CRH где икс это
  196. буква порта (от A до G), в нашем случае это буква С. Оба регистра
  197. выполняют одну и ту же функцию, просто GPIOx_CRL отвечает за
  198. конфигурирование младшей половины порта (ножки с 0 по 7), а GPIOx_CRH
  199. старшей (ножки с 8 по 15). Наши светодиоды висят на ногах PC8 и PC9 а
  200. это значит что для настройки этих ног в режим выхода нам потребуется
  201. регистр GPIOC_CRH. Вот так он устроен:&nbsp;</p>
  202. <p style="text-align: justify;"><img style="border-style: initial; border-color: initial; border-image: initial; display: block; margin-left: auto; margin-right: auto; border-width: 0px;" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/gpiox_crh.jpg" alt="gpiox_crh" border="0" width="650"><span style="text-align: justify;">Как
  203. видно из этой красивой и цветной картинки, на каждую ногу отводится по
  204. четыре бита. Причем биты объединены в две группы по два бита в каждой.
  205. первая группа - MODE. Собственно эти биты решают входм или выходом будет
  206. конкретная ножка порта, допустимы следующие комбинации:&nbsp;</span></p>
  207. <table border="0">
  208. <tbody>
  209. <tr>
  210. <td>MODE1 &nbsp;</td>
  211. <td>MODE0 &nbsp;</td>
  212. <td>Значение</td>
  213. </tr>
  214. <tr>
  215. <td>0</td>
  216. <td>0</td>
  217. <td>Вход (Состояние по умолчанию)</td>
  218. </tr>
  219. <tr>
  220. <td>0</td>
  221. <td>1</td>
  222. <td>Выход, максимальная частота 10 МГц</td>
  223. </tr>
  224. <tr>
  225. <td>1</td>
  226. <td>0</td>
  227. <td>Выход, максимальная частота 2 МГц</td>
  228. </tr>
  229. <tr>
  230. <td>1</td>
  231. <td>1</td>
  232. <td>Выход, максимальная частота 50 МГц</td>
  233. </tr>
  234. </tbody>
  235. </table>
  236. <p style="text-align: justify;">Максимальная частота в моём понимании
  237. это насколько быстро нога может менять свое состояние, скорее всего
  238. частота влияет на энергопотребление. Теперь для рассмотрим следующую
  239. группу бит CNF. Если мы настроили ногу на выход (биты MODE отличны от
  240. нуля) то биты группы CNF могут принимать следующие значения:&nbsp;</p>
  241. <table border="0">
  242. <tbody>
  243. <tr>
  244. <td>CNF1 &nbsp;</td>
  245. <td>CNF0 &nbsp;</td>
  246. <td>Значение</td>
  247. </tr>
  248. <tr>
  249. <td>0</td>
  250. <td>0</td>
  251. <td>&nbsp;Обычный режим. Push-pull</td>
  252. </tr>
  253. <tr>
  254. <td>0</td>
  255. <td>1</td>
  256. <td>&nbsp;Обычный режим. Открытый коллектор</td>
  257. </tr>
  258. <tr>
  259. <td>1</td>
  260. <td>0</td>
  261. <td>&nbsp;Альтернативный режим. Push-pull</td>
  262. </tr>
  263. <tr>
  264. <td>1</td>
  265. <td>1</td>
  266. <td>&nbsp;Альтернативный режим. Открытый коллектор</td>
  267. </tr>
  268. </tbody>
  269. </table>
  270. <p style="text-align: justify;">Тут всё немного сложнее, во-первых
  271. разберёмся что подразумевается под обычным и альтернативный режимами. В
  272. обычном режиме вы можете распоряжаться ногой как вам угодно, например
  273. установить единицу или ноль при помощи своего кода. В альтернативном
  274. режиме вы передаёте эту ножку контроллера в распоряжение какой-либо
  275. периферии контроллера например UART'у, SPI, I2c и всему прочему что
  276. нуждается в ножках. Теперь разберемся чем отличается push-pull от
  277. открытого коллектора. В режиме push-pull нога всегда находится в одном
  278. из двух состояний: На ней всегда либо земля либо полное напряжение
  279. питания. В режиме открытого коллектора: Земля или ничего, нога просто
  280. как-бы зависает в воздухе ни к чему не подключенная внутри контроллера.
  281. Теперь рассмотрим что означают те же самый два бита если наш порт
  282. настроен на вход (биты MODE обнулены):</p>
  283. <table border="0">
  284. <tbody>
  285. <tr>
  286. <td>CNF1 &nbsp;</td>
  287. <td>CNF0 &nbsp;</td>
  288. <td>Значение</td>
  289. </tr>
  290. <tr>
  291. <td>0</td>
  292. <td>0</td>
  293. <td>&nbsp;Аналоговый режим</td>
  294. </tr>
  295. <tr>
  296. <td>0</td>
  297. <td>1</td>
  298. <td>&nbsp;Вход без подтяжки</td>
  299. </tr>
  300. <tr>
  301. <td>1</td>
  302. <td>0</td>
  303. <td>&nbsp;Вход с подтяжкой</td>
  304. </tr>
  305. <tr>
  306. <td>1</td>
  307. <td>1</td>
  308. <td>&nbsp;Зарезервировано</td>
  309. </tr>
  310. </tbody>
  311. </table>
  312. <p style="text-align: justify;">Аналоговый режим предназначен для работы
  313. АЦП, если мы хотим чтоб АЦП мог производить измерения используя эту
  314. ногу мы должны выбрать этот режим. Вход без подтяжки делает ногу входом с
  315. Hi-z состоянием, это означает что сопротивление входа велико и любая
  316. электрическая наводка (помеха) может вызвать появление на таком входе
  317. единицу или ноль, причем сделать это не предсказуемо. Во избежание этого
  318. нужно использовать подтяжку, она позволяет установить на входе какое
  319. либо устойчивое состояние которое не будет зависеть от помех. Подтяжка
  320. представляет собой резистор большого сопротивления подключенный одним
  321. концом к земле или к плюсу питания, а другим концом ко входу. Например
  322. если включена подтяжка к плюсу питания, то когда нога контроллера ни
  323. куда не припаяна на ней всегда логическая единица. Если мы припаяем
  324. кнопку между этой ножкой и землёй, то всякий раз при нажатии кнопки на
  325. ноге будет появляться логический ноль. Если бы подтяжка была выключена,
  326. то в момент нажатия кнопки на ноге так же появлялся бы ноль, но при
  327. отпущенной кнопке нога могла бы легко поймать любую наводку и вызвать
  328. появление логической единицы на ноге. В результате, микроконтроллер бы
  329. думал что кто-то хаотично жмет на кнопку. Мы рассмотрим все это на
  330. практике чуть позже, а сейчас вернемся к нашему регистру&nbsp;<span style="text-align: justify;">GPIOC_CRH. Итак мы планируем установить биты этого регистра (для двух ножек <span style="text-align: justify;">PC8 и PC9)</span>&nbsp;следующим образом:&nbsp;</span></p>
  331. <p><span style="text-align: justify;"><img src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/gpioc_crh_config.png" alt="gpioc_crh_config" width="650"></span></p>
  332. <p style="text-align: justify;">Исходя из вышесказанного, такая
  333. комбинация бит настроит обе ножки на выход с максимальной частотой 50
  334. МГц в обычном режиме push-pull, что нам вполне подходит. Эта строчка
  335. устанавливает в единицы биты MODE:</p>
  336. <p></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp"> GPIOC-&gt;CRH |=0x33;
  337. </pre></div><p></p>
  338. <p>А вот эта, обнуляет биты CNF:</p>
  339. <p></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp"> GPIOC-&gt;CRH &amp;= ~0xCC;
  340. </pre></div><p></p>
  341. <p>После выполнения этих двух строк, младшие 8 бит этого регистра будут
  342. такими как на рисунке выше: 00110011, при этом все остальные биты
  343. останутся в том состоянии в котором они и были, наш код их не затронет. В
  344. принципе, в &nbsp;данном случае не будет ничего страшного если вместо
  345. этих двух строк мы просто напишем:&nbsp;</p>
  346. <p></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp"> GPIOC-&gt;CRH = 0x33; // 0x33 это и есть 00110011
  347. </pre></div><p></p>
  348. <p>Но нужно понимать что во все остальные биты (кроме первых восьми)
  349. запишутся нули, и это повлияет на конфигурацию остальных пинов (они все
  350. станут аналоговыми входами). Теперь когда обе ножки сконфигурированы
  351. можно попробовать зажечь светодиоды. За вывод данных в порт C отвечает
  352. регистр&nbsp;GPIOC_ODR, записывая в определённый бит единицу, мы
  353. получаем логическую единицу на соответствующей ножке порта. Поскольку в
  354. порте С 16 ножек, а регистр 32-х битный, то используются только первые
  355. 16 бит. Светодиоды подключены к пинам&nbsp;<span style="text-align: justify;">PC8 и PC9, поэтому мы должны установить восьмой и девятый биты. Для этого служит строчка:</span></p>
  356. <p><span style="text-align: justify;"></span></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp"> GPIOC-&gt;ODR |= (GPIO_ODR_ODR9 | GPIO_ODR_ODR8);
  357. </pre></div><p></p>
  358. <p style="text-align: justify;"><span style="text-align: justify;">Очень
  359. надеюсь, что читатели знакомы с битовой арифметикой в Си :) ибо без неё
  360. может быть сложновато. Ну собственно все, после компиляции и загрузки
  361. программы в контроллер - на платке загорятся два светодиода: синий и
  362. зелёный. Использование регистра&nbsp;GPIOC_ODR - это не единственный
  363. способ изменить состояние порта С. Существует еще один регистр
  364. позволяющий сделать это -&nbsp;GPIOC_BSRR. Этот регистр позволят
  365. атомарно устанавливает состояние какой-либо ножки. Ведь в примере выше
  366. мы делали следующим образом: </span></p>
  367. <p style="text-align: justify;"><span style="text-align: justify;">1) Считывали текущее состояние регистра&nbsp;GPIOC_ODR в некоторую временную переменную </span></p>
  368. <p style="text-align: justify;"><span style="text-align: justify;">2) устанавливали в ней нужные биты (8-й и 9-й) </span></p>
  369. <p style="text-align: justify;"><span style="text-align: justify;">3) записывали то что получилось обратно в регистр&nbsp;<span style="text-align: justify;">GPIOC_ODR. </span></span></p>
  370. <p style="text-align: justify;"><span style="text-align: justify;"><span style="text-align: justify;">Чтение-&gt;модификация-&gt;запись
  371. это довольно долгая процедура, иногда надо делать это очень быстро. Вот
  372. тут то и выходит на сцену регистр&nbsp;<span style="text-align: justify;">GPIOC_BSRR. Посмотрим как он устроен:&nbsp;</span></span></span></p>
  373. <p><img style="display: block; margin-right: auto; margin-left: auto;" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/gpioc_bsrr.png" alt="gpioc_bsrr" width="650"></p>
  374. <p>На каждую ножку порта выделяется по два бита: BRXX и BSXX. Далее всё
  375. просто: записывая единицу в бит BSXX мы устанавливаем на соответствующей
  376. ножке логическую единицу. Записывая единицу в бит BRXX мы сбрасываем в
  377. ноль соответствующую ножку. Запись нулей в любой из битов не приводит ни
  378. к чему. Если мы заменим последнюю строчку программы на :&nbsp;</p>
  379. <p><span style="text-align: justify;"></span></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp">GPIOC-&gt;BSRR=(GPIO_BSRR_BS8|GPIO_BSRR_BS9);
  380. </pre></div><p></p>
  381. <p><span style="text-align: justify;">то получим тот же результат, но
  382. работает оно быстрей :) Ну а для того чтоб сбросить в ноль определённые
  383. биты порта С необходим так же записать две единицы но уже в биты BR8 и
  384. BR9:</span></p>
  385. <p><span style="text-align: justify;"></span></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp">GPIOC-&gt;BSRR=(GPIO_BSRR_BR8|GPIO_BSRR_BR9);
  386. </pre></div><p></p>
  387. <p style="text-align: justify;"><span style="text-align: justify;">Но и
  388. это еще не всё :) Так же изменить состояние порта можно при помощи
  389. регистра GPIOC_BRR, установив в единицу какой либо из первых 16-бит, мы
  390. сбросим в ноль соответствующие ножки порта. Зачем он нужен - не понятно,
  391. ведь есть же регистр GPIOC_BSRR который может делать тоже самое да и
  392. еще плюс устанавливать логическую единицу на ноге (а не только
  393. сбрасывать в ноль как GPIOC_BRR). &nbsp;С выводом данных в порт теперь
  394. точно всё. Настало время что-то из порта прочитать. Ну а читать мы будет
  395. состояние кнопки, которая у нас подключена к ноге PA0. Когда кнопка не
  396. нажата - на ножке PA0 присутствует логический ноль за счёт резистора
  397. номиналом 10 кОм который подтягивает этот вывод к земле. &nbsp;После
  398. замыкания контактов кнопки, слабенькая подтяжка к земле будет подавлена
  399. напряжением питания и на входе появится логическая единица. Сейчас мы
  400. попробуем написать программу которая читает состояние ножки PA0 и в
  401. зависимости от наличия логической единицы, зажигает или гасит
  402. светодиоды. Управлять состоянием светодиодов мы уже научились из
  403. предыдущего примера, осталось только разобраться как читать что-то из
  404. порта. Для чтения из порта А используется регистр GPIOA_IDR. В его
  405. внутреннем устройстве нет ничего особо сложного и поэтому я не буду
  406. рисовать тут картинку, а объясню всё парой слов: Первые 16 бит регистра
  407. соответствуют 16 ногам порта. Что приходит в порт - то и попадает в этот
  408. регистр. Если на всех ногах порта А будут присутствовать логические
  409. единицы, то и из регистра GPIOA_IDR мы прочитаем 0xFFFF. Естественно, не
  410. надо забывать настраивать порт как вход, хотя по умолчанию он настроен
  411. именно так как нам надо, просто сделаем это для понимания сути дела.
  412. После этого в бесконечном цикле мы считываем регистр GPIOA_IDR, зануляем
  413. в все биты кроме нулевого (кнопка ведь висит на PA</span><strong style="text-align: justify;">0</strong><span style="text-align: justify;">)
  414. и сравниваем результат с единицей. Если результат равен единице значит
  415. кто-то удерживает нажатой кнопку (и надо зажечь светодиоды), в противном
  416. случае (если 0) кнопка отпущена и светодиоды надо погасить. Может
  417. возникнуть здравый вопрос: Зачем занулять все остальные биты кроме
  418. нулевого? А дело тут вот в чем, все остальные ноги порта (как и PA0) так
  419. же настроены на вход без подтяжки. Это означает что в любой момент
  420. времени там может быть вообще всё что угодно, всё зависит от количества
  421. вокруг контроллера наводок и помех. Следовательно при нажатой кнопке из
  422. регистра&nbsp;</span><span style="text-align: justify;">GPIOA_IDR может прочитаться не только 0000 0000 0000 0001 но и например 0000 0000 0<strong>1</strong>0<strong>1</strong>&nbsp;0001 а следовательно сравнивать такое число с единицей нельзя, однако после зануления остальных битов вполне можно.&nbsp;</span>Посмотрим на код реализующий всё сказанное выше:&nbsp;</p>
  423. <p><span style="text-align: justify;"></span></p><div style="overflow: hidden; display: block; height: auto; width: inherit;"><pre class="brush:cpp">#include &lt;stm32f10x_rcc.h&gt;
  424. int main(void) {
  425. //Включим тактирование порта С (со светодиодами) и порта А (с кнопкой)
  426. RCC-&gt;APB2ENR |= (RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA );
  427. //Настроим ножки со светодиодами как выходы
  428. GPIOC-&gt;CRH |=0x33;
  429. GPIOC-&gt;CRH &amp;= ~0xCC;
  430. //Настроим ногу PA0 как вход без подтяжки (подтягивающий резистор уже есть на плате)
  431. GPIOA-&gt;CRL |= 0x04;
  432. GPIOA-&gt;CRL &amp;= ~0x11;
  433. while(1) { //Бесконечный цикл
  434. if ((GPIOA-&gt;IDR &amp; 0x01)==0x01) { //Кнопка нажата?
  435. GPIOC-&gt;BSRR=(GPIO_BSRR_BS8|GPIO_BSRR_BS9); //Зажигаем светодиоды
  436. } else {
  437. GPIOC-&gt;BSRR=(GPIO_BSRR_BR8|GPIO_BSRR_BR9); //Гасим светодиоды
  438. }
  439. }
  440. }
  441. </pre></div><p></p>
  442. <p style="text-align: justify;"><span style="text-align: justify;">Код
  443. не особо сложный, но если вдруг появились вопросы, то они принимаются в
  444. комментариях. Напоследок хотелось бы в двух словах рассказать о еще
  445. одном регистре с непонятной областью практического применения -&nbsp;</span><span style="text-align: justify;">GPIOx_LCKR.
  446. Он служит для блокировки настроек порта. Это означает что настроив
  447. какую либо ножку порта на выход и установив соответствующий бит
  448. блокировки в этом регистре, мы не сможем сделать её входом (только после
  449. сброса контроллера).</span></p>
  450. <p style="text-align: justify;"><span style="text-align: justify;"><img style="text-align: justify; display: block; margin-left: auto; margin-right: auto;" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/gpiox_lckr.png" alt="gpiox_lckr" width="650"></span></p>
  451. <p>Как видно из рисунка, кроме битов блокировки для каждой ноги порта,
  452. тут есть еще бит LCKK. Он используется когда мы хотим установить
  453. какой-либо бит блокировки. Алгоритм работы с этим регистром следующий:</p>
  454. <ol>
  455. <li>Устанавливаем нужные биты блокировки</li>
  456. <li>Записываем в LCKK единицу</li>
  457. <li>Записываем в LCKK ноль</li>
  458. <li>Записываем в LCKK единицу</li>
  459. <li>Читаем из LCKK ноль</li>
  460. <li>Читаем из LCKK единицу (опционально, только для того, чтоб убедиться что блокировка сработала)</li>
  461. </ol>
  462. <p>Всё, после этого переназначить настройки ног порта (соответствующие
  463. установленным битам блокировки) уже не получится. Если вы смогли найти
  464. практическое применение этой фичи - сообщить мне об этом пожалуйста :)</p> </div>
  465. </div>
  466. </div>
  467. </div>
  468. </div>
  469. <div id="col2">
  470. <div class="moduletable_menu">
  471. <h3 class="module-title">Разделы сайта</h3>
  472. <div class="res">
  473. <div class="module-content">
  474. <ul class="menu">
  475. <li class="item-101"><a href="http://easystm32.ru/">Главная страница</a></li><li class="item-108 current active"><a href="http://easystm32.ru/for-beginners">Для начинающих</a></li><li class="item-107"><a href="http://easystm32.ru/stm32vl-discovery">STM32VL Discovery</a></li><li class="item-147"><a href="http://easystm32.ru/stm32f4-discovery">STM32F4 Discovery</a></li><li class="item-109"><a href="http://easystm32.ru/tools">Инструменты</a></li><li class="item-110"><a href="http://easystm32.ru/interfaces">Интерфейсы</a></li><li class="item-111"><a href="http://easystm32.ru/technologies">Технологии</a></li><li class="item-112"><a href="http://easystm32.ru/useful-things">Полезности</a></li><li class="item-113"><a href="http://easystm32.ru/indication">Индикация</a></li><li class="item-114"><a href="http://easystm32.ru/power-supplies">Питание</a></li><li class="item-115"><a href="http://easystm32.ru/projects">Проекты</a></li><li class="item-116"><a href="http://easystm32.ru/sensors">Датчики</a></li><li class="item-117"><a href="http://easystm32.ru/debug">Отладка</a></li></ul>
  476. </div>
  477. </div><div class="modul"></div></div>
  478. <div class="moduletable">
  479. <h3 class="module-title">Форма входа</h3>
  480. <div class="res">
  481. <div class="module-content">
  482. <form action="/for-beginners" method="post" id="login-form">
  483. <fieldset class="userdata">
  484. <p id="form-login-username">
  485. <label for="modlgn-username">Логин</label>
  486. <input id="modlgn-username" name="username" class="inputbox" size="18" type="text">
  487. </p>
  488. <p id="form-login-password">
  489. <label for="modlgn-passwd">Пароль</label>
  490. <input id="modlgn-passwd" name="password" class="inputbox" size="18" type="password">
  491. </p>
  492. <p id="form-login-remember">
  493. <label for="modlgn-remember">Запомнить меня</label>
  494. <input id="modlgn-remember" name="remember" class="inputbox" value="yes" type="checkbox">
  495. </p>
  496. <input name="Submit" class="button" value="Войти" type="submit">
  497. <input name="option" value="com_users" type="hidden">
  498. <input name="task" value="user.login" type="hidden">
  499. <input name="return" value="aW5kZXgucGhwP29wdGlvbj1jb21fY29udGVudCZ2aWV3PWFydGljbGUmY2F0aWQ9MTAmaWQ9MTEmSXRlbWlkPTEwOA==" type="hidden">
  500. <input name="7e65820915caf822baa45130272018ad" value="1" type="hidden"> </fieldset>
  501. <ul>
  502. <li>
  503. <a href="http://easystm32.ru/component/users/?view=reset">
  504. Забыли пароль?</a>
  505. </li>
  506. <li>
  507. <a href="http://easystm32.ru/component/users/?view=remind">
  508. Забыли логин?</a>
  509. </li>
  510. </ul>
  511. </form>
  512. </div>
  513. </div><div class="modul"></div></div>
  514. </div>
  515. </div>
  516. </div>
  517. </div>
  518. <div id="footer">
  519. <div class="copy">
  520. Copyright &nbsp;© 2012 <a href="http://easystm32.ru/component/xmap/xml?option=com_xmap&amp;view=xml&amp;id=1">EasySTM32.</a> All Rights Reserved. Запрещено копирование материалов без активной ссылки на этот сайт.<br>
  521. Реклама: <script type="text/javascript">
  522. <!--
  523. var _acic={dataProvider:10};(function(){var e=document.createElement("script");e.type="text/javascript";e.async=true;e.src="//www.acint.net/aci.js";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})()
  524. //-->
  525. </script> <a href="http://ekaterinburg.viberu.ru/banki/sberbank-rossii/ipoteka/" target="_blank">Ипотека Сбербанк</a> воспользуйтесь предложениями, которые разработали наши специалисты. . <a href="http://www.absolutss.ru/Products/videonabludenie/videoregistratori/DSSL/tek_865/" target="_blank">TRASSIR QuattroStation</a> </div>
  526. <!-- Yandex.Metrika counter -->
  527. <script type="text/javascript">
  528. (function (d, w, c) {
  529. (w[c] = w[c] || []).push(function() {
  530. try {
  531. w.yaCounter14614684 = new Ya.Metrika({id:14614684});
  532. } catch(e) {}
  533. });
  534. var n = d.getElementsByTagName("script")[0],
  535. s = d.createElement("script"),
  536. f = function () { n.parentNode.insertBefore(s, n); };
  537. s.type = "text/javascript";
  538. s.async = true;
  539. s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js";
  540. if (w.opera == "[object Opera]") {
  541. d.addEventListener("DOMContentLoaded", f);
  542. } else { f(); }
  543. })(document, window, "yandex_metrika_callbacks");
  544. </script>
  545. <noscript><div><img title="[yandex.ru]" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" style="position: absolute; left: -9999px; border: 1px solid rgb(255, 204, 204); background-repeat: no-repeat; background-position: center center; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gMFRANL5LXnioAAAJWSURBVDjLnZI/ixtXFMV/972ZNzPSrmTtalexlsWBGMfEYOzaVciXyKdIkW/hFKnS22WafIDUxk0g2AQSgm0csIPWK42ktaSRNPP+pRBK5SLOqS7cew7ccw4xxrPJ+8XdHx4+7AE8e3Cj++zLm71fvrqT8x+QAK35dJr2n/x89urTa+eDm/cS+eI2y3eT+Lx/bt8u1vNqfDH++teXdk/6ThAfUUBIgL9ku75z/8WL7LOlhXIGJ0Pyw75wMcnGv//xSQ2DH4ddu9k01dXWsWzcofhYaiiViLjiWi9UWQa1gzcjWF7hgfzzW5ydnXB62JLjg0PTLfJertNepnQSIA+gE4Cs03UuNYYQYP4e5jPogmSG9vA6rrjC+0AxN2i5Qk0DpXVJhCQB0EVRrzqdFgB1DZfvCDHixiV2NqO6LHHKIKnQMoaWbFBgIrQVgIXaDc+JCHgP5QRZr4jzGWFbo6yncRYviiiQKUhBRch3Lyix4bgPWsAkcDkmZAV2OiE0DaI1WoEShRKF3sWnmt01pFBnJydEpZDEwHSGt47lYsls43AIXjTWV9R1Qx0DGahqLyAhbqrj0/ib0nRzXNoyCo0Kkor2llV0eKOwdUMg4pSQA7JPQXvnJv1B+GlwOvrGlaXB6fV2lb5t6qOtike56DSJgYDGBQcOAsQAfueBMeHR48fhadb1j/58HWARdt6yBv7+/vpBe2o5OogxlcaKdt5aKCNsk309W0WxKQjmQ33/9mJVAdWHdmo/tNvtRZIkfCz+ZQwGg6rT6Zj/LTAajTbD4bD5WIF/AAseEisPFO8uAAAAAElFTkSuQmCC");" alt="" height="50" width="50"></div></noscript>
  546. <!-- /Yandex.Metrika counter -->
  547. <div id="dummy"></div>
  548. <div id="debug">
  549. </div>
  550. </div>
  551. </div>
  552. </div>
  553. </div>
  554. <script type="text/javascript" src="EasySTM32%20-%20%D0%9F%D0%BE%D1%80%D1%82%D1%8B%20%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%BB%D0%B5%D1%80%D0%B0_files/jquery.js"></script>
  555. <script type="text/javascript">
  556. $(document).ready(function(){
  557. //When you click on a link with class of poplight and the href starts with a #
  558. $('a.poplight[href^=#]').click(function() {
  559. var popID = $(this).attr('rel'); //Get Popup Name
  560. var popURL = $(this).attr('href'); //Get Popup href to define size
  561. //Pull Query & Variables from href URL
  562. var param= popURL.substr(1);
  563. var data = "<iframe width=\"500\" height=\"438\" src=\"http://easystm32.ru/getreg.php" + param + "\"></iframe>";
  564. document.getElementById('popup_name').innerHTML=data;
  565. //Добавить кнопку "Закрыть" в наше окно, прописываете прямой путь к картинке кнопки
  566. $('#' + popID).fadeIn().css({ 'width': Number( 500 ) }).prepend('<a href="#" class="close"><img src="/templates/shoplab/images/close_pop.png" class="btn_close" title="Закрыть окно" alt="Закрыть" /></a>');
  567. //Определяет запас на выравнивание по центру (по вертикали по горизонтали)мы добавим 80px к высоте / ширине, значение полей вокруг содержимого (padding) и ширину границы устанавливаем в CSS
  568. var popMargTop = ($('#' + popID).height() + 80) / 2;
  569. var popMargLeft = ($('#' + popID).width() + 80) / 2;
  570. //Применяем отступы в всплывающем окне
  571. $('#' + popID).css({
  572. 'margin-top' : -popMargTop,
  573. 'margin-left' : -popMargLeft
  574. });
  575. //Фон слоя затемнения
  576. $('body').append('<div id="fade"></div>'); //Добавляем слой затемнения.
  577. $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn(); //Постепенное исчезание слоя - .css({'filter' : 'alpha(opacity=80)'}) используется для фиксации в IE, фильтр для устранения бага тупого IE
  578. return false;
  579. });
  580. //Закрыть всплывающее окно и слой затемнения
  581. $('a.close, #fade').live('click', function() { //При нажатии рядом, окно и слой затемнения закрываются
  582. $('#fade , .popup_block').fadeOut(function() {
  583. $('#fade, a.close').remove();
  584. }); //fade them both out
  585. return false;
  586. });
  587. });
  588. </script>
  589. </body></html>