当前位置: 首页 > news >正文

上位机图像处理和嵌入式模块部署(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软件好使。

相关文章:

  • py黑帽子学习笔记_burp
  • 【js】数组元素拼接、数组元素类型转换
  • Android调用onNewIntend的时刻
  • RPM包管理-rpm命令管理
  • 【linux/shell实战案例】在shell中插入Python代码及EOF解析
  • Linux中进程和线程区别
  • vue实现一个简单的审批绘制功能
  • 数据提取的奥秘
  • c++初级-2-引用
  • uniapp 使用cavans 生成海报
  • 使用docker搭建squid和ss5
  • Docker Compose 一键快速部署 RocketMQ
  • SpringBoot3集成MyBatisPlus
  • 【鸿蒙学习笔记】Image迭代完备
  • 难道 Java 已经过时了?
  • 11111111
  • HTML5新特性总结
  • java中的hashCode
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • maven工程打包jar以及java jar命令的classpath使用
  • npx命令介绍
  • PHP面试之三:MySQL数据库
  • SQLServer之创建数据库快照
  • 阿里云Kubernetes容器服务上体验Knative
  • 设计模式 开闭原则
  • 实现菜单下拉伸展折叠效果demo
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #etcd#安装时出错
  • #QT(智能家居界面-界面切换)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm高校实验室 毕业设计 800008
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (已解决)Bootstrap精美弹出框模态框modal,实现js向modal传递数据
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转载)OpenStack Hacker养成指南
  • .net CHARTING图表控件下载地址
  • .net core 依赖注入的基本用发
  • .NET 服务 ServiceController
  • .Net面试题4
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • .net与java建立WebService再互相调用
  • .Net中的设计模式——Factory Method模式
  • .net中应用SQL缓存(实例使用)
  • .Net组件程序设计之线程、并发管理(一)
  • @WebService和@WebMethod注解的用法
  • [ 数据结构 - C++]红黑树RBTree
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [20190401]关于semtimedop函数调用.txt