上位机图像处理和嵌入式模块部署(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.mzph.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;损失&…

【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;先来看看效果图。点击在线体验 实现的功能…

受限玻尔兹曼机浅析

受限玻尔兹曼机&#xff08;Restricted Boltzmann Machine&#xff0c;简称RBM&#xff09;是一种特殊的随机生成神经网络&#xff0c;能够学习并发现数据的复杂规则分布。以下是关于受限玻尔兹曼机算法的详细介绍&#xff1a; ⭐️ 定义与起源 定义&#xff1a; 受限玻尔兹…

深入剖析Tomcat(十四) Server、Service 组件:如何启停Tomcat服务?

通过前面文章的学习&#xff0c;我们已经了解了连接器&#xff0c;四大容器是如何配合工作的&#xff0c;在源码中提供的示例也都是“一个连接器”“一个顶层容器”的结构。并且启动方式是分别启动连接器和容器&#xff0c;类似下面代码 connector.setContainer(engine); try …

小程序的运行机制、更新机制、生命周期介绍保姆级教程全解

一、小程序运行机制 1. 小程序冷启动 小程序启动可以分为两种情况&#xff0c;一种是冷启动&#xff0c;一种是热启动- 冷启动&#xff1a;如果用户首次打开&#xff0c;或小程序销毁后被用户再次打开&#xff0c;此时小程序需要重新加载启动- 热启动&#xff1a;如果用户已经打…

HSP_12章 Python面向对象编程oop_多态

文章目录 P128 多态问题的引出P129 多态细节和使用1. 多态介绍&特别说明2. 多态的好处3. 特别说明: Python多态的特点4. 使用多态的机制来解决主人喂食物的问题 P128 多态问题的引出 先看一个问题 # 说明: 先试用传统的方式完成 class Food:name Nonedef __init__(self,…

4.Android逆向协议-详解二次打包失败解决方案

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;微尘网校 上一个内容&#xff1a;3.Android逆向协议-APP反反编译及回编译 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.…

#笔记# 写给自己用的小爬虫

最近完成了一个文旅行业信息聚合的小应用&#xff0c;实现仅从一个入口了解全行业的信息动态&#xff0c;不用一个一个翻看各网站&#xff0c;节省了不少检索时间。 一、基本思路 明确数据来源。基于前述目标&#xff0c;确定数据源为文化和旅游部管理部门官网&#xff0c;比…

【办公类-21-18】20240701 养老护理员初级选择题488,制作PyQt5图形界面GUI

背景需求&#xff1a; 6月16日育婴师高级考完了。运气好&#xff0c;抽到的是”护理患腹泻的幼儿”&#xff0c;“晨检与家长沟通”&#xff0c;“4个月婴儿喂蛋黄”&#xff0c;“21个月食谱”&#xff0c;都是我背过的题目&#xff08;没有抽到感统&#xff09; 于是一放假&…

【C语言】解决C语言报错:Invalid Pointer

文章目录 简介什么是Invalid PointerInvalid Pointer的常见原因如何检测和调试Invalid Pointer解决Invalid Pointer的最佳实践详细实例解析示例1&#xff1a;未初始化的指针示例2&#xff1a;已释放的指针示例3&#xff1a;返回局部变量的指针示例4&#xff1a;野指针 进一步阅…

《化学工程与装备》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《化学工程与装备》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《化学工程与装备》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;福建石油化工集团有限责任公司 …