上位機圖像處理和嵌入式模塊部署(mcu 項目1:固件編寫)

【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱:feixiaoxing @163.com】

? ? ? ? 說完了上位機的開發,接下來就是固件的開發。前面我們說過,目前使用的開發板是極海apm32f103的開發板。它自身包含了iap示例,里面既有bootloader的代碼,也有app的代碼。所以,我們需要做的就是在app的基礎之上,添加自己需要的功能就可以了,bootloader就不用處理了。這也是大部分mcu模塊的開發方式。

1、修改中斷向量基地址和鏈接地址

? ? ? ? 這部分代碼如果不修改的話,我們需要每次通過bootloader來加載app的bin文件。這對于開發來說,不是很方便,所以這部分還是建議修改一下,等到最后部署的時候再改回來。其實,修改的地方就兩處,

#define FLASH_APP1_ADDR 0x0000

? ? ? ? 還有一處就是鏈接的地方,

2、添加新的串口

? ? ? ? 之前我們使用了debug串口,可以寫數據、讀數據。實際上開發的時候需要兩個串口,最好分開來。一個串口用于debug調試,一個用于和上位機之間的通信。現在是這么安排的,之前的debug串口,也就是pa9、pa10用于串口通信使用。這里重新添加一個usart3,用于調試使用,對應的pin腳是pb10、pb11,這部分可以通過廠家的芯片手冊查找到。其中,頭文件的定義如下所示,

#ifndef __USART3_H
#define __USART3_H#include "./SYSTEM/sys/sys.h"
#include "apm32f10x_usart.h"
#include <stdio.h>#define USART3_TX_GPIO_PORT          GPIOB
#define USART3_TX_GPIO_PIN           GPIO_PIN_10
#define USART3_TX_GPIO_CLK_ENABLE()  do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB); }while(0)     #define USART3_RX_GPIO_PORT          GPIOB
#define USART3_RX_GPIO_PIN           GPIO_PIN_11
#define USART3_RX_GPIO_CLK_ENABLE()  do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB); }while(0)     #define USART3_UX                    USART3
#define USART3_UX_IRQn               USART3_IRQn
#define USART3_UX_IRQHandler         USART3_IRQHandler
#define USART3_UX_CLK_ENABLE()       do{ RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART3); }while(0)    void usart3_init(uint32_t baudrate);            
int sendChar(int ch);                            
void sendString(char* str);                      
void sendNumber(int num);                       #endif

? ? ? ? 具體的c實現代碼如下所示,

#include "./SYSTEM/usart3/usart3.h"
#include "apm32f10x_rcm.h"
#include "apm32f10x_gpio.h"
#include "apm32f10x_misc.h"void usart3_init(uint32_t baudrate)
{GPIO_Config_T gpio_init_struct = {0};USART_Config_T usart_init_struct = {0};USART3_UX_CLK_ENABLE();USART3_TX_GPIO_CLK_ENABLE();USART3_RX_GPIO_CLK_ENABLE();gpio_init_struct.pin = USART3_TX_GPIO_PIN;gpio_init_struct.speed = GPIO_SPEED_50MHz;gpio_init_struct.mode = GPIO_MODE_AF_PP;GPIO_Config(USART3_TX_GPIO_PORT, &gpio_init_struct);gpio_init_struct.pin = USART3_RX_GPIO_PIN;gpio_init_struct.speed = GPIO_SPEED_50MHz;gpio_init_struct.mode = GPIO_MODE_IN_PU;GPIO_Config(USART3_RX_GPIO_PORT, &gpio_init_struct);usart_init_struct.baudRate = baudrate;                    usart_init_struct.wordLength = USART_WORD_LEN_8B;         usart_init_struct.stopBits = USART_STOP_BIT_1;         usart_init_struct.parity = USART_PARITY_NONE;            usart_init_struct.mode = USART_MODE_TX_RX;              usart_init_struct.hardwareFlow = USART_HARDWARE_FLOW_NONE; USART_Config(USART3_UX, &usart_init_struct);USART_Enable(USART3_UX);
}int sendChar(int ch)
{while (USART3_UX->STS_B.TXCFLG == 0);    USART3_UX->DATA_B.DATA = (uint16_t)ch;   return ch;
}void sendString(char* str)
{char* pStart = str;while(*pStart){sendChar(*pStart);pStart++;}
}static void _sendNumber(int num)
{if(num > 9){sendNumber(num / 10);}num = num % 10;switch(num){case 0:sendChar('0');break;case 1:sendChar('1');break;case 2:sendChar('2');break;case 3:sendChar('3');break;case 4:sendChar('4');break;case 5:sendChar('5');break;case 6:sendChar('6');break;case 7:sendChar('7');break;case 8:sendChar('8');break;case 9:sendChar('9');break;default:break;}
}void sendNumber(int num)
{unsigned int val;if(num < 0){sendChar('-');val = -num;}else{val = num;}_sendNumber(val);
}

? ? ? ? 為了調試的方便,我們還實現了sendChar、sendString、sendNumber三個函數,到時候可以直接利用這幾個打印函數調試即可。

3、添加內部flash讀寫代碼

? ? ? ? 因為涉及到參數的保存,所以勢必涉及到內部flash的讀寫。這部分內容可以直接從對應的示例代碼中copy即可,

uint16_t apmflash_read_halfword(uint32_t faddr);
void apmflash_read(uint32_t raddr, uint16_t *pbuf, uint16_t length); 
void apmflash_write_nocheck(uint32_t waddr, uint16_t *pbuf, uint16_t length);
void apmflash_write(uint32_t waddr, uint16_t *pbuf, uint32_t length);  
void test_write(uint32_t waddr, uint16_t data);                 

4、添加adc代碼

? ? ? ? 和內部flash讀寫一樣,目前adc也有現成的case可以參考,所以相關代碼直接copy即可,

void adc_init(void);
uint16_t adc_get_result(uint8_t ch); 
uint16_t adc_get_result_average(uint8_t ch, uint8_t times); 

5、確認之前的串口接收協議

? ? ? ? 除了上面4點之外,還要確認下當前之前debug串口是否包含有接收功能,相關的邏輯是什么。通過仔細閱讀代碼,正好在中斷處理里面發現了相關的邏輯,

void USART_UX_IRQHandler(void)
{if (USART_ReadIntFlag(USART_UX, USART_INT_RXBNE) == SET){     g_rx_buffer[0] = USART_RxData(USART_UX);   if ((g_usart_rx_sta & 0x8000) == 0)      {if (g_usart_rx_sta & 0x4000)         {if (g_rx_buffer[0] != 0x0A){g_usart_rx_sta = 0;            }else{g_usart_rx_sta |= 0x8000;      }}else                                   {if (g_rx_buffer[0] == 0x0D){g_usart_rx_sta |= 0x4000;}else{g_usart_rx_buf[g_usart_rx_sta & 0x3FFF] = g_rx_buffer[0];g_usart_rx_sta++;if (g_usart_rx_sta > (USART_REC_LEN - 1)){g_usart_rx_sta = 0;       }}}}USART_ClearIntFlag(USART_UX, USART_INT_RXBNE);}
}

6、gpio高低電平設定

? ? ? ? 這部分之前的demo已經設定好,直接skip即可。

7、總結

? ? ? ? 等我們想好要實現哪些功能的時候,其實做起來并不麻煩,關鍵是前面要規劃好。還有一點,就是要善于復用廠家給出的demo代碼,以及閱讀廠家的芯片手冊,這些第一手的資料不一定文檔上能找到,只能自己通過文檔閱讀的方法一點、一點去挖掘,總是可以解決的。

? ? ? ? 最后要提及的就是版本管理,非常推薦大家在本地用git把代碼管起來。不管過分相信自己的記憶力,好記憶不如爛筆頭。回到代碼本身,就是好記憶不如git軟件好使。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37924.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37924.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37924.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一些迷你型信息系統

只有一個表&#xff0c;比較簡單易用&#xff1b; 1 博物館信息查詢系統 信息錄入&#xff0c;瀏覽&#xff0c;添加&#xff0c;更新&#xff0c;刪除&#xff1b; 下載&#xff0c; https://download.csdn.net/download/bcbobo21cn/89505217

中國網絡安全審查認證和市場監管大數據中心數據合規官CCRC-DCO

關于CCRC-DCO證書的頒發機構&#xff0c;它是由中國網絡安全審查認證與市場監管大數據中心&#xff08;簡稱CCRC&#xff09;負責。 該中心在2006年得到中央機構編制委員會辦公室的批準成立&#xff0c;隸屬于國家市場監督管理總局&#xff0c;是其直轄的事業單位。 依據《網絡…

計算機的錯誤計算(十八)

摘要 計算機的錯誤計算&#xff08;四&#xff09;指出一元二次方程的計算精度問題。本節給出其一種解決方案。 計算機的錯誤計算&#xff08;四&#xff09;與&#xff08;十七&#xff09;分別指出一元二次方程的求解是具有挑戰性的難題&#xff0c;其出錯原因是因為相減相消…

YOLOv10(7):YOLOv10訓練(以訓練VOC數據集為例)

YOLOv10&#xff08;1&#xff09;&#xff1a;初探&#xff0c;訓練自己的數據_yolov10 訓練-CSDN博客 YOLOv10&#xff08;2&#xff09;&#xff1a;網絡結構及其檢測模型代碼部分閱讀_yolov10網絡結構圖-CSDN博客 YOLOv10&#xff08;4&#xff09;&#xff1a;損失&…

汽車之家論壇評論全面采集實戰指南:Python爬蟲篇

聚焦汽車之家&#xff0c;解鎖評論寶藏 在這個數據為王的時代&#xff0c;每一個角落的信息都可能成為寶貴的洞察來源。汽車之家&#xff0c;作為汽車行業內的權威論壇&#xff0c;其海量的用戶評論不僅是消費者購車的重要參考&#xff0c;也是汽車品牌與市場研究者不可忽視的…

【Android面試八股文】在你之前的Android項目中,你是如何進行性能優化的?

在之前的Android項目中,優化和提升性能是一個重要且常見的任務。 以下是一些常用的性能優化方法和策略: 分析和測量: 使用Android Studio中的Profiling工具(如Profiler、Trace等)進行性能分析,識別CPU、內存和網絡使用情況。使用第三方工具(如Systrace)來分析系統層面…

iOS 練習項目 Landmarks (四):添加 AutoLayout 約束

iOS 練習項目 Landmarks &#xff08;四&#xff09;&#xff1a;添加 AutoLayout 約束 iOS 練習項目 Landmarks &#xff08;四&#xff09;&#xff1a;添加 AutoLayout 約束新增 topLabel圖片視圖圓形裁切陰影使用 AutoLayout 為詳情頁的組件添加約束DetailViewControllerDe…

如何在 Logback 和 Log4j 中獲取日志:一個開發者指南

日志記錄是軟件開發中的關鍵實踐&#xff0c;它幫助我們監控應用程序的行為&#xff0c;定位問題并優化性能。在 Java 生態系統中&#xff0c;Logback 和 Log4j 是兩個廣泛使用的日志框架&#xff0c;它們都基于 SLF4J API 提供日志服務。本文將指導你如何在這兩個框架中獲取日…

7-490 將字符串“software“賦給一個字符指針,并從第一個字母開始間隔地輸出該串(簡單字符串)

編程將字符串"software"賦給一個字符指針 然后從第一個字母開始間隔地輸出該串 請用指針法完成。 輸入樣例: 在這里給出一組輸入。例如&#xff1a; 無輸入輸出樣例: 在這里給出相應的輸出。例如&#xff1a; sfwr #include <stdio.h> #include <stri…

Linux環境下快速部署Spring Boot應用:高效命令組合實踐

概要&#xff1a; 本文旨在介紹一種高效的Linux命令組合&#xff0c;用于簡化Spring Boot項目的部署與管理流程。通過結合使用nohup、java -jar、輸出重定向以及進程管理命令&#xff0c;我們能夠實現Spring Boot應用的快速后臺啟動及便捷的進程控制&#xff0c;尤其適合于自動…

什么是 JVM( Java 虛擬機),它在 Java 程序執行中扮演什么角色?

JVM&#xff0c;全稱Java Virtual Machine&#xff0c;中文譯作“Java虛擬機”&#xff0c;它是運行Java程序的軟件環境&#xff0c;也是Java語言的核心部分之一。 想象一下&#xff0c;如果你是一位環球旅行家&#xff0c;每到一個新的國家&#xff0c;都需要學習當地的語言才…

【Linux】初識操作系統

一、馮?諾依曼體系結構 在學習操作系統之前&#xff0c;我們先來認識一下馮?諾依曼體系結構&#xff0c;我們常見的計算機&#xff0c;如筆記本。我們不常見的計算機&#xff0c;如服務器&#xff0c;大部分都遵守馮諾依曼體系。 截至目前&#xff0c;我們所認識的計算機&am…

神經網絡訓練(一):基于殘差連接的圖片分類網絡(ResNet18)

目錄 一、簡介:二、圖片分類網絡1.記載訓練數據(torch自帶的cifa10數據集)2.數據增強3.模型構建4.模型訓練三、完整源碼及文檔一、簡介: 基于殘差連接的圖片分類網絡,本網絡使用ResNet18作為基礎模塊,根據cifa10的特點進行改進網絡,使用交叉熵損失函數和SGD優化器。本網…

使用pyqt5編寫一個七彩時鐘

使用pyqt5編寫一個七彩時鐘 效果代碼解析定義 RainbowClockWindow 類初始化用戶界面顯示時間方法 完整代碼 在這篇博客中&#xff0c;我們將使用 PyQt5 創建一個簡單的七彩數字時鐘。 效果 代碼解析 定義 RainbowClockWindow 類 class RainbowClockWindow(QMainWindow):def _…

【TB作品】溫濕度監控系統設計,ATMEGA16單片機,Proteus仿真

題2:溫濕度監控系統設計 功能要求: 1)開機顯示時間(小時、分)、時分可修改; 2)用兩個滑動變阻器分別模擬溫度傳感器(測量范 圍0-100度)與濕度傳感器(0-100%),通過按鍵 可以在數碼管切換顯示當前溫度值、濕度值; 3)當溫度低于20度時,紅燈長亮; 4)當濕度高于70%時,黃燈長亮; 5)當…

安卓實現微信聊天氣泡

一搜沒一個能用的&#xff0c;我來&#xff1a; 布局文件&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xml…

Tech Talk:智能電視eMMC存儲的五問五答

智能電視作為搭載操作系統的綜合影音載體&#xff0c;以穩步擴大的市場規模走入越來越多的家庭&#xff0c;成為人們生活娛樂的重要組成部分。存儲部件是智能電視不可或缺的組成部分&#xff0c;用于保存操作系統、應用程序、多媒體文件和用戶數據等信息。智能電視使用eMMC作為…

vue3中使用Antv G6渲染樹形結構并支持節點增刪改

寫在前面 在一些管理系統中&#xff0c;會對組織架構、級聯數據等做一些管理&#xff0c;你會怎么實現呢&#xff1f;在經過調研很多插件之后決定使用 Antv G6 實現&#xff0c;文檔也比較清晰&#xff0c;看看怎么實現吧&#xff0c;先來看看效果圖。點擊在線體驗 實現的功能…

服務端開發過程中常見的安全性問題

身份驗證與授權 密碼加密 加密傳輸 Https DDoS SQL注入 SQL注入的本質:數據和代碼未分離&#xff0c;即數據當做了代碼來執行。 解決辦法 檢查輸入的數據是否符合預期&#xff0c;不能直接放入數據庫中進行查詢字符串長度驗證mybatis具有防sql注入的方式 使用#{}代替${…

深入探討光刻技術:半導體制造的關鍵工藝

前言 光刻&#xff08;Photolithography&#xff09;是現代半導體制造過程中不可或缺的一環&#xff0c;它的精度和能力直接決定了芯片的性能和密度。本文將詳細介紹光刻技術的基本原理、過程、關鍵技術及其在半導體制造中的重要性。 光刻技術的基本原理 光刻是一種利用光化…