打印
[嵌入式硬件开发基础与MCU选型]

MCU引脚不够用,那就把烧录脚也用上吧!

[复制链接]
441|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dffzh|  楼主 | 2025-8-1 14:35 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dffzh 于 2025-8-1 14:38 编辑

之前做过一个项目,因为是降本方案,所以对芯片选型要求比较高,特别是其中的MCU主控,综合评估后,最后选了STM32G431KBU3,一款带26个GPIO引脚的M4核芯片。可是让我没有想到的是,最后这个芯片的普通GPIO引脚居然不够用,没办法,只能把烧录脚SWCLK和SWDIO也用上了,主控原理图如下图所示:
其中烧录脚SWCLK和SWDIO用作模拟I2C功能,读写外部EEPROIM芯片。
那这样在代码仿真调试I2C功能时就会比较麻烦了,因为如果烧录脚SWCLK和SWDIO配置为普通GPIO模式后,就无法正常仿真了,只能下载程序到板子上实际运行看结果了。因此为了调试方便一些,代码上就最后再调试I2C了,并加上一个宏定义来使能或禁止烧录脚SWCLK和SWDIO的GPIO配置,如下图所示:
需要仿真的时候,就手动把I2C_ENABLE的定义屏蔽掉;需要实测I2C功能时,就手动把I2C_ENABLE的定义打开。这里还有个问题需要注意,就是如果配置为GPIO模式后,如果烧录信号线不接RESET脚,是无法正常下载程序的,不知道其他MCU是不是也是如此。
像这种GPIO复用的设计,其实不是很好,后面有时候因为出现Bug需要仿真时,操作半天进不了仿真,以为代码有问题,结果排查后才发现,原来是没有关闭I2C配置,因为时间长了,容易忘记;还有就是修改Bug后生成固件,结果测试发现参数无法掉电保存,结果是生成固件时没有使能I2C配置。反正就是这种复用操作,很可能会遇到意想不到的问题,结果我们还认为是不可思议的。
因此,除非真的没有办法了,类似这种用烧录脚来做普通GPIO功能的设计,看上去似乎很高端很优秀,其实稍微不小心,就容易出问题,而且可能会影响芯片的二次烧录。
大家有木有做过类似的开发设计?欢迎分享一下心得~~。

使用特权

评论回复
评论
xch 2025-8-4 09:29 回复TA
看样子外挂HC595,还占用3只GOIO,不如外挂个MCU。价格差不多,顺便扩了GPIO,可能还省一个GPIO。 
沙发
丙丁先生| | 2025-8-1 22:16 | 只看该作者
那怎么烧录啊?

使用特权

评论回复
评论
dffzh 2025-8-4 08:53 回复TA
这种操作一般都得加上boot程序,通过OTA或者串口进行固件升级。 
板凳
大大财迷| | 2025-8-4 08:09 | 只看该作者
建议:芯片在上电开机后,时钟初始化之后,要延时3S左右,再将SWD设置为GPIO,否则,量产时将引起程序无法烧录的问题。

使用特权

评论回复
评论
dffzh 2025-8-4 08:53 回复TA
是个不错的办法,对于有些应用场景,确实可以这么操作的。 
地板
大大财迷| | 2025-8-4 08:11 | 只看该作者
还有一个办法:将SWD的RST引出来,烧录时接到烧录器,下载时烧录器强制复位MCU,也可以实现烧录口占用暂时解除。

使用特权

评论回复
评论
dffzh 2025-8-4 08:54 回复TA
是的,我这个就是接上RESET引脚到烧录器才能正常下载。 
5
hp860629| | 2025-8-4 09:02 | 只看该作者
可以的

使用特权

评论回复
6
xch| | 2025-8-4 09:25 | 只看该作者
我不用宏定义。自动切换调试模式和运行模式。
几行代码的工作。

使用特权

评论回复
评论
dffzh 2025-8-4 14:00 回复TA
分享一下代码。 
7
zjk103| | 2025-8-4 09:55 | 只看该作者
能不用最好不要用,后面烧录很麻烦

使用特权

评论回复
评论
dffzh 2025-8-4 14:00 回复TA
确实如此。 
8
dukedz| | 2025-8-4 10:05 | 只看该作者
串口打印调试啊

使用特权

评论回复
评论
dffzh 2025-8-4 14:01 回复TA
是可以用串口打印调试,就是没有仿真调试和排查的快。 
9
xch| | 2025-8-4 14:23 | 只看该作者
/********************************
在初始化时检测一下SWD 仿真器是否接入;
复位后先按照SWD 功能配置 PA13,14。
检测SWD 接口函数也增加了启动的延时。
*****************************/
uint8_t JlinkOnline(void)
{
  uint16_t cnt =0;
  uint16_t tmp =  PinInput(SWCLK);
  do{
    if( tmp != PinInput(SWCLK)) //读IO电平函数,检测SWCLK 是否翻转
    {
      return 1; //发现仿真器
    }
  }while(++cnt<60000);
  return 0; //未接入仿真器返回0.
}

int main()
{
;;;;;;;
  if(0 == JlinkOnline () )
{
    ConfigSwdPinFucntionRatherThanSwd();
   // DisableWatchDog();
  //DisableDeepSleepMode();
}
;;;;;;;;;;
while(1)
  {
  ;;;;;;;;;;;;
  }
}

使用特权

评论回复
评论
dffzh 2025-8-4 14:37 回复TA
我还确实没这么玩过,一定要试试,感谢兄弟! 
10
xch| | 2025-8-4 14:27 | 只看该作者
其实,还有其他功能没有一一列出。比如加密功能。未连接仿真器就把MCU 加密。
下次调试下载时会自动全片擦除。免得忘记加密就出货了。

使用特权

评论回复
11
xch| | 2025-8-4 14:51 | 只看该作者
#define PA(x) P(A,x)
#define P(GpioName,PinNum) (tPin){GPIO##GpioName,PinNum}

typedef struct{
    GPIO_TypeDef *GPIO  ;
    const uint8_t PinNum;
}tPin;

#define SWDIO   PA(13)
#define SWCLK   PA(14)

uint16_t PinInput (tPin pin)
{
  //return  (pin.GPIO->IDR )& (1<<pin.PinNum);
  return  (pin.GPIO->IDR >>pin.PinNum)& 1;
}

使用特权

评论回复
评论
dffzh 2025-8-4 14:57 回复TA
好的,代码都已下载,非常感谢。 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

1118

帖子

20

粉丝