{"id":2961,"date":"2024-11-03T04:07:37","date_gmt":"2024-11-03T04:07:37","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2961"},"modified":"2024-11-03T04:07:39","modified_gmt":"2024-11-03T04:07:39","slug":"getting-started-with-stm32h5-arm-cortex-m33-adc-single-channel-continuous-conversion-with-interrupt","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2961","title":{"rendered":"Getting Started with STM32H5 ARM Cortex M33: ADC Single Channel Continuous Conversion with Interrupt"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"725\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-1024x725.webp\" alt=\"\" class=\"wp-image-2962\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-1024x725.webp 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-300x212.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-768x544.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-750x531.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-400x283.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-250x177.webp 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1.webp 1141w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall use the interrupt of the ADC to acquire the ADC data without waiting for the conversion to be completed.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Modification to STM32CubeMX configuration.<\/li>\n\n\n\n<li>Modification to the source code.<\/li>\n\n\n\n<li>Results.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Modification to STM32CubeMX:<\/h2>\n\n\n\n<p>Open adc_single.ioc file as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"572\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1024x572.jpg\" alt=\"\" class=\"wp-image-2963\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1024x572.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-300x167.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-768x429.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1536x857.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-2048x1143.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1150x642.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-750x419.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-400x223.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-250x141.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, in ADC parameter configuration, set the clock divider to be 16. This will reduce the ADC clock and slow down the interrupt generation significantly. Hence, the CPU shall no spend too much time processing the ADC data. <\/p>\n\n\n\n<p>Set the ADC clock divider as following:<\/p>\n\n\n\n<p>Set the prescaller to Asynchronous clock mode divided by 16.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"839\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-839x1024.jpg\" alt=\"\" class=\"wp-image-2964\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-839x1024.jpg 839w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-246x300.jpg 246w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-768x937.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-1259x1536.jpg 1259w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-1679x2048.jpg 1679w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-1150x1403.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-750x915.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-400x488.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39-250x305.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-45-39.jpg 1764w\" sizes=\"(max-width: 839px) 100vw, 839px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, from NVIC settings, enable the ADC interrupt as following (make sure it is marked):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"916\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-916x1024.jpg\" alt=\"\" class=\"wp-image-2965\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-916x1024.jpg 916w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-268x300.jpg 268w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-768x858.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-1374x1536.jpg 1374w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-1150x1285.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-750x838.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-400x447.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28-250x279.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-46-28.jpg 1736w\" sizes=\"(max-width: 916px) 100vw, 916px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for the configuration. Save the project and that will generate the new configuration.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Modification to the Source Code:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin PV part of the main declare the following variable:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint16_t adc_value;<\/pre><\/div>\n\n\n\n<p>The variable to store the ADC shall be global since it will be modified outside the main loop.<\/p>\n\n\n\n<p>Next, in the user code begin 2 of the main function, start the ADC in the interrupt mode as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_ADC_Start_IT(&amp;hadc1);<\/pre><\/div>\n\n\n\n<p>In the while 1 loop:<\/p>\n\n\n\n<p>We shall simply print the value and delay by 500ms between each printed data as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t printf(&quot;ADC Value =%d\\r\\n&quot;,adc_value);\n\n\t HAL_Delay(500);<\/pre><\/div>\n\n\n\n<p>As you can see, no need to poll for end of conversion like in the previous guide since the ADC will generate an interrupt each time the ADC has finished the conversion.<\/p>\n\n\n\n<p>In user code begin 4 (in the bottom of the main.c file), we shall handle the ADC interrupt.<\/p>\n\n\n\n<p>In STM32H5xx_hal_adc.c source file, there is a function that can be called each time the ADC generate interrupt as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"714\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1024x714.jpg\" alt=\"\" class=\"wp-image-2966\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1024x714.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-300x209.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-768x536.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1536x1071.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-2048x1428.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1150x802.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-750x523.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-400x279.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-250x174.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The function called:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)<\/pre><\/div>\n\n\n\n<p>Since it is defined as weak function, the user shall implement it in his firmware.<\/p>\n\n\n\n<p>Hence, in user code begin 4 of the main.c file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)\n{\n\t adc_value=HAL_ADC_GetValue(&amp;hadc1);\n}<\/pre><\/div>\n\n\n\n<p>The function shall store the ADC value in the adc_value variable which has been defined globally.<\/p>\n\n\n\n<p>That all for the guide.<\/p>\n\n\n\n<p>Save, build and run the project on your STM32H563Zi Nucleo-144 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"28\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-1024x28.png\" alt=\"\" class=\"wp-image-2958\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-1024x28.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-300x8.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-768x21.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-1536x43.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-1150x32.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-750x21.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-400x11.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1-250x7.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/image-1.png 1734w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Results:<\/h2>\n\n\n\n<p>Open your serial terminal application, set the baud rate 115200 and you should get the following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"733\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-1024x733.jpg\" alt=\"\" class=\"wp-image-2959\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-1024x733.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-1150x823.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-750x537.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-400x286.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-24_07-17-00-2.jpg 1168w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall use the interrupt of the ADC to acquire the ADC data without waiting for the conversion to be completed. In this guide, we shall cover the following: 1. Modification to STM32CubeMX: Open adc_single.ioc file as following: Next, in ADC parameter configuration, set the clock divider to be 16. This will [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2961","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2961"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2961"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2961\/revisions"}],"predecessor-version":[{"id":2968,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2961\/revisions\/2968"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2961"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2961"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2961"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}