找回密码
 立即注册
查看: 66|回复: 0

USB转串口不断电烧录ADC方案-老baby新手篇

[复制链接]
已绑定手机

1

主题

0

回帖

7

积分

新手上路

积分
7
发表于 2026-8-7 13:19:56 来自手机 | 显示全部楼层 |阅读模式
说明一下,这方案偏向于新手玩家。
         对于不断电烧录,官方也出有很多方案,但对新手都不太友好,涉及到通讯,很多新手照搬出现很多问题,用的不顺。
          我也算入门不久,也为烧录问题烦恼过,烧录器也坏过不少,官方方案也试过,感觉不太适合自己用,为了方便自己使用,研究出了一套自己的不断电烧录方案,用的挺好,屡试屡成,这个方案最大的优点就是不分芯片类型,只要有ADC功能都可以实现,完全可以照搬到其他芯片直接用,缺点还是有的,占用一个ADC端口,合理利用这个端口,并联多个按键分阻,实现多按键组合也不算浪费。
        主要思路就是利用串口的TXD的电压变化来判断是否进入ISP,据我所知我手上的CH340N在空闲时TXD引脚电压接近VCC,当在下载时TXD引脚有一个0.2V压降,利用这一特点来识别是否有下载信号,其他串口下载器有没有这一特点有待验证。
以下是单个测试
          以下是代码main.c,根据不同芯片不同接线修改相应配置,硬件连接把串口和芯片连接好,只需把P3.0引脚接一根导线到对应的ADC通道引脚,直接移植套用
  1. #include "STC8H.H"
  2. #include "ADCISP.H"
  3. // 用户自定义延时(用于主循环)
  4. void Delay_ms(unsigned int ms)
  5. {
  6.     unsigned int i, j;
  7.     for (i = ms; i > 0; i--)
  8.         for (j = 1100; j > 0; j--);
  9. }
  10. void main(void)
  11. {
  12.     while (1)
  13.     {
  14.         ADCISP_CH3();      // 检测P1.3,若满足条件则复位进入ISP
  15.         Delay_ms(1000);    // 每秒检测一次
  16.         // 其他任务...
  17.     }
  18. }
复制代码

         以下是ADCISP.H头文件
  1. #ifndef __ADCISP_H__
  2. #define __ADCISP_H__
  3. /******************** 用户可配置区(可在包含前重定义) ********************/
  4. #ifndef VCC_MV
  5. #define VCC_MV      5000        // 单片机供电电压(mV),5V或3.3V
  6. #endif
  7. #ifndef DROP_THRESH
  8. #define DROP_THRESH 10          // 压降对应的ADC值(8位),0.2V/5V*255≈10
  9. #endif
  10. #ifndef THRESHOLD
  11. #define THRESHOLD   245         // 触发下限(255 - DROP_THRESH)
  12. #endif
  13. #ifndef SAMPLE_CNT
  14. #define SAMPLE_CNT  5           // 确认采样次数(取平均)
  15. #endif
  16. #ifndef BASE_SAMPLES
  17. #define BASE_SAMPLES 10         // 上电基准采样次数
  18. #endif
  19. #ifndef DELAY_MS_LOOP
  20. #define DELAY_MS_LOOP 1100      // 延时循环系数(24MHz下约1ms)
  21. #endif
  22. /*************************************************************************/
  23. #include "STC8H.H"
  24. #include <intrins.h>
  25. // 私有:粗延毫秒
  26. static void ADCISP_Delay_ms(unsigned int ms)
  27. {
  28.     unsigned int i, j;
  29.     for (i = ms; i > 0; i--)
  30.         for (j = DELAY_MS_LOOP; j > 0; j--);
  31. }
  32. // 私有:读取一次ADC(指定通道)
  33. static unsigned char ADCISP_Read(unsigned char ch)
  34. {
  35.     ADC_CONTR = 0x80 | (ch & 0x07);   // 开启电源,选择通道
  36.     ADC_CONTR |= 0x40;                // 启动转换
  37.     while (!(ADC_CONTR & 0x20));      // 等待完成
  38.     ADC_CONTR &= ~0x20;               // 清除标志
  39.     return ADC_RES;                   // 8位左对齐,ADC_RES即为高8位
  40. }
  41. // 私有:多次平均
  42. static unsigned char ADCISP_ReadAvg(unsigned char ch, unsigned char times)
  43. {
  44.     unsigned int sum = 0;
  45.     unsigned char i;
  46.     for (i = 0; i < times; i++)
  47.         sum += ADCISP_Read(ch);
  48.     return (unsigned char)(sum / times);
  49. }
  50. // 私有:配置指定通道引脚为高阻,并初始化ADC
  51. static void ADCISP_InitChannel(unsigned char ch)
  52. {
  53.     // 设置P1.x高阻
  54.     switch (ch)
  55.     {
  56.         case 0: P1M0 &= ~0x01; P1M1 |= 0x01; break;
  57.         case 1: P1M0 &= ~0x02; P1M1 |= 0x02; break;
  58.         case 2: P1M0 &= ~0x04; P1M1 |= 0x04; break;
  59.         case 3: P1M0 &= ~0x08; P1M1 |= 0x08; break;
  60.         case 4: P1M0 &= ~0x10; P1M1 |= 0x10; break;
  61.         case 5: P1M0 &= ~0x20; P1M1 |= 0x20; break;
  62.         case 6: P1M0 &= ~0x40; P1M1 |= 0x40; break;
  63.         case 7: P1M0 &= ~0x80; P1M1 |= 0x80; break;
  64.         default: while (1); // 非法通道
  65.     }
  66.     ADCTIM = 0x3F;   // 最长采样时间
  67.     ADCCFG = 0x00;   // 左对齐,ADC_RES为8位结果
  68.     ADCISP_Delay_ms(1);
  69. }
  70. // 宏:生成一个通道的检测函数
  71. #define ADCISP_DEFINE_CH(ch) \
  72.     static unsigned char base_ch##ch = 0; \
  73.     static unsigned char init_ch##ch = 0; \
  74.     void ADCISP_CH##ch(void) { \
  75.         if (!init_ch##ch) { \
  76.             ADCISP_InitChannel(ch); \
  77.             base_ch##ch = ADCISP_ReadAvg(ch, BASE_SAMPLES); \
  78.             init_ch##ch = 1; \
  79.         } \
  80.         unsigned char cur = ADCISP_Read(ch); \
  81.         if (base_ch##ch > cur && (base_ch##ch - cur) > DROP_THRESH) { \
  82.             unsigned char avg = ADCISP_ReadAvg(ch, SAMPLE_CNT); \
  83.             if (avg < THRESHOLD) { \
  84.                 IAP_CONTR = 0x60; \
  85.                 while (1); \
  86.             } \
  87.         } \
  88.     }
  89. // 生成8个通道函数:ADCISP_CH0() ~ ADCISP_CH7()
  90. ADCISP_DEFINE_CH(0)
  91. ADCISP_DEFINE_CH(1)
  92. ADCISP_DEFINE_CH(2)
  93. ADCISP_DEFINE_CH(3)
  94. ADCISP_DEFINE_CH(4)
  95. ADCISP_DEFINE_CH(5)
  96. ADCISP_DEFINE_CH(6)
  97. ADCISP_DEFINE_CH(7)
  98. #endif
复制代码

        也可以自己写,只需懂得ADC即可,上电-ADC稳定采样-下载时ADC稳定采样-比较-软件进入ISP-下载烧录程序。
欢迎大家交流讨论学习QQ1757289803,有什么不足有望大佬们指点斧正
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-9-23 15:05 , Processed in 0.064460 second(s), 41 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表