amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 42090|回复: 239

STC免手动下载程序电路图(自动断电冷启动) + 程序,有需要的就进来看看吧

  [复制链接]
发表于 2011-12-15 00:30:29 | 显示全部楼层 |阅读模式
基于STC15F104E制作的 STC免手动下载程序控制电路

原理详见:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4855735&bbs_page_no=1&search_mode=1&search_text=自动下载&bbs_id=1006

电路图如下:

(原文件名:STC免手动烧写电路图(最佳版).jpg)

实物图:

(原文件名:实物图1.jpg)


(原文件名:实物图2.jpg)

注意事项:

(原文件名:注意事项.jpg)

源程序:
/***************************************************************
        作品:STC免手动烧写控制程序
  单片机:STC15F104E(A版)
    晶振:11.0592M
编译环境:Keil uVision4 V9.00
    注意:宏定义BAUD的波特率 要与 STC-ISP软件中的“最低波特率” 一致
***************************************************************/
#define uint8 unsigned char       
#include "STC15F104E.H"

//#define BAUD     0xF400      // 1200bps @ 11.0592MHz
//#define BAUD     0xFA00      // 2400bps @ 11.0592MHz
  #define BAUD     0xFD00      // 4800bps @ 11.0592MHz

sbit RXB   = P3^4;
sbit Key   = P3^1;                            //自动/手动开关(根据需要使用)
sbit Relay = P3^3;
sbit LED   = P3^0;

uint8 RBUF;        //接收缓存
uint8 RDAT;        //接收数据暂存
uint8 RCNT;        //接收计数器
uint8 RBIT;        //接收比特数
bit   RING;        //开始接收标志
bit   REND;        //接收完成标志

uint8 cnt;        //重启计数器
bit   START;//重启标志

void YS100ms(uint8 n)
{
  uint8 i,a,b,c;
  for(i=n;i>0;i--)
  for(c=89;c>0;c--)
  for(b=230;b>0;b--)
  for(a=12;a>0;a--);
}

void UART_INIT()
{
   RING = 0;
   REND = 0;
   RCNT = 0;
}

void main()
{
   P3M1 = 0x00;
   P3M0 = 0x09;                 //P3.0、P3.3推挽输出
   Relay = 0;                 //断开继电器
   LED  = 0;                 //关LED

   
   TMOD = 0x00;      //T0处于16位自动重装模式
   AUXR = 0x80;      //T0工作在1T模式
   TL0 = BAUD;
   TH0 = BAUD>>8;    //初始化Timer0和设定重载值
   TR0 = 1;         
   ET0 = 1;         
   PT0 = 1;          //提高Timer0的中断优先级
   EA  = 1;           

   UART_INIT();

   while(1)
   {                                   
      if(START)
          {
                 START = 0;
                 if(Key)
                 {
                    ET0 = 0;
                    Relay = 1;                 //继电器吸合
                    LED = 1;
                    YS100ms(50);         //从『加载HEX』到『提示上电』有5秒
                    Relay = 0;
                    LED = 0;
                    YS100ms(15);
                    ET0 = 1;
                    UART_INIT();
                 }
          }
   }
}

void tm0() interrupt 1 using 1
{
   if(RING)
   {
      if(--RCNT == 0)
      {
         RCNT = 3;             //复位接收波特率计数器
         if(--RBIT == 0)
         {
            RBUF = RDAT;       //保存数据到RBUF
            RING = 0;          //停止接收
            REND = 1;          //接收完成标志
         }
         else
         {
            RDAT >>= 1;
            if(RXB)RDAT |= 0x80; //RX数据转移到RX缓冲区
         }
      }
   }
   else if(!RXB)                           //是否检测到低电平
   {
      RING = 1;                //设置开始接收标志
      RCNT = 4;                //初始接收波特率计数器
      RBIT = 9;                //初化始接收比特数(8个数据位+1个停止位)
   }

   if(REND)
   {
      REND = 0;
      if(RBUF == 0x7F){ if(++cnt > 30)START=1; } //“0x7F”连续 > 30次,则打开重启标志
          else cnt = 0;
   }
}





※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※



用STC-ISP V6.03、STC-ISP V4.88默认的最低波特率不同,
懒得每次修改,
重新写了个程序,
自动适应3种最低波特率:1200bps/2400bps/4800bps

/***************************************************************
        作品:STC免手动烧写控制程序
  单片机:STC15F104E(A版)
    晶振:11.0592M
编译环境:Keil uVision4 V9.00
   
        注意:STC-ISP软件中的“最低波特率” 可选“1200bps/2400bps/4800bps”,
              本程序自动检测适应。
***************************************************************/
#define uint8  unsigned char
#define uint16 unsigned int       
#include "STC15F104E.H"

sbit RXB   = P3^4;
sbit Key   = P3^1;   //自动/手动开关(根据需要使用)
sbit Relay = P3^3;         //继电器
sbit LED   = P3^0;

uint8 RBUF;         //接收缓存
uint8 RDAT;         //接收数据暂存
uint8 RCNT;         //接收计数器
uint8 RBIT;         //接收比特数
bit   RING;         //开始接收标志
bit   REND;         //接收完成标志

uint8 cnt;         //重启计数器
bit   START; //重启标志

uint16 cn;          //波特率切换计数器
uint8  Status;//波特率状态
bit    NEW;          //波特率更新标志

void YS100ms(uint8 n)
{
  uint8 a,b,c;
  while(n--)
  {
     for(c=89;c>0;c--)
     for(b=230;b>0;b--)
     for(a=12;a>0;a--);
  }
}

void UART_INIT()
{
   RING = 0;
   REND = 0;
   RCNT = 0;

   cnt = 0;
   cn  = 0;
}

void main()
{
   P3M1 = 0x00;
   P3M0 = 0x09;                 //P3.0、P3.3推挽输出
   Key        = 1;
   Relay= 0;                 //断开继电器
   LED  = 0;                 //关LED

   
   TMOD = 0x00;      //T0处于16位自动重装模式
   AUXR = 0x80;      //T0工作在1T模式
   TL0 = 0x00;                 //初始化Timer0和设定重载值
   TH0 = 0xFA;       //默认 2400bps @ 11.0592MHz
   TR0 = 1;         
   ET0 = 1;         
   PT0 = 1;          //提高Timer0的中断优先级
   EA  = 1;           

   UART_INIT();

   while(1)
   {                                   
      if(START)
          {
                 START = 0;
                 if(Key)
                 {
                    ET0 = 0;
                    Relay = 1;                 //继电器吸合
                    LED = 1;
                    YS100ms(50);         //从『加载HEX』到『提示上电』有5秒
                    Relay = 0;
                    LED = 0;
                    YS100ms(30);
                    UART_INIT();
                        ET0 = 1;
                 }
          }

          if(NEW)
          {
                 NEW = 0;
                 TR0 = 0;
                 if(++Status > 2)Status=0;
                 switch(Status)
         {
                    case 0:TL0=0x00; TH0=0xFA;           // 2400bps @ 11.0592MHz
                                   //P31=0;P32=1;P35=1;          //状态指示灯(根据需要使用)
                                   break;
                        case 1:TL0=0x00; TH0=0xFD;           // 4800bps @ 11.0592MHz
                   //P31=1;P32=0;P35=1;          //状态指示灯(根据需要使用)
                                   break;
                        case 2:TL0=0x00; TH0=0xF4;          // 1200bps @ 11.0592MHz
                   //P31=1;P32=1;P35=0;          //状态指示灯(根据需要使用)
                                   break;
                 }
                 UART_INIT();
                 TR0 = 1;
          }
   }
}

void tm0() interrupt 1
{
   if(RING)
   {
      if(--RCNT == 0)
      {
         RCNT = 3;             //复位接收波特率计数器
         if(--RBIT == 0)
         {
            RBUF = RDAT;       //保存数据到RBUF
            RING = 0;          //停止接收
            REND = 1;          //接收完成标志
         }
         else
         {
            RDAT >>= 1;
            if(RXB)RDAT |= 0x80; //RX数据转移到RX缓冲区
         }
      }
   }
   else if(!RXB)                           //是否检测到低电平
   {
      RING = 1;                //设置开始接收标志
      RCNT = 4;                //初始接收波特率计数器
      RBIT = 9;                //初化始接收比特数(8个数据位+1个停止位)
   }

   if(REND)
   {
      REND = 0;
      if(RBUF == 0x7F)
          {
             cnt++;
             if(cnt > 1)cn=0;           //“0x7F”连续 > 1,则清切换计数器
                 if(cnt > 100)START=1; //“0x7F”连续 > 100,则打开重启标志
          }
          else cnt = 0;
   }

   if(++cn>600){ cn=0; NEW=1; }//切换计数器 > 600,则打开更新标志
}
//有一旧时期的STC-ISP_4.88版的引导信号间隔时间有差异( 需要切换计数器 > 800 ),建议用最新时期的
 楼主| 发表于 2012-1-1 23:04:49 | 显示全部楼层
最新版本:

(原文件名:STC免手动烧写+逻辑分析仪电路图(初始版).jpg)


(原文件名:STC免手动烧写+逻辑分析仪电路图(改进版).jpg)


(原文件名:a.jpg)


(原文件名:20111229019.jpg)

// 作品:STC免手动烧写(自适应波特率自动冷启) + 简易逻辑分析仪
// 芯片:STC15F104E
// 晶振:45MHz
// 编译:Keil uVision4 V9.00
//
// 说明:自适应STC-ISP软件最低波特率(1200bps/2400bps/4800bps)
//                 3种模式:①自动烧写  (默认)           【LED_key不亮:模式① ,LED亮:通电 ,LED不亮:关电】
//                          ②逻辑分析仪(正向波形) 【LED_key亮  :模式② ,LED亮:预备 ,LED不亮:采样】
//                          ③逻辑分析仪(反向波形) 【LED_key闪烁:模式③ ,LED亮:预备 ,LED不亮:采样】
//       ①②③模式下,系统板都可以正常串口通信。
//       ②③模式下,也可以烧写程序(手动烧写),不过正在“采样”时请不要烧写程序以及系统板串口通信。
//
//          注:建议烧写程序时启动看门狗(预分频数256,约2.2S @ 45MHz)
//
//         另:关于STC-ISP V4.88版本,发现用PL2303HX芯片烧写STC15系列很难成功,最低/高波特率都选用4800bps才可以烧写。
//                 关于STC-ISP V6.06版本,用PL2303HX芯片烧写STC15系列非常好(直接用默认的最低/高波特率),
//       但V6.06版本内部R/C振荡器最高只可以选33.1776MHz。
//                 用FT232芯片烧写,则通杀STC-ISP所有版本(直接用默认的最低/高波特率)。
//

#include "STC15F104E.H"
#include "MY_SET.h"

sbit LED   = P3^0;         //指示灯
sbit KEY   = P3^1;   //按键
sbit RXB   = P3^2;                       
sbit TXB   = P3^3;
sbit PNP   = P3^4;         //PNP三极管
sbit IO_in = P3^5;         //分析仪采样引脚

uint8   Mode;                 //模式
bit                B_init;                 //初始化标志
uint8   KEY_Value;          //按键消抖计数
bit            ON;                         //按键标志
bit     Over;
bit                LED_key;         //模式指示灯(在按键上扩展)
uint16  Count;                 //闪烁计数
bit     P_N;                 //正向标志
uint8   BIT8,cnt,Dat;
uint16  Time;

uint8 TBUF,RBUF;         //发送/接收缓存
uint8 TDAT,RDAT;         //发送/接收数据暂存
uint8 TCNT,RCNT;         //发送/接收计数器
uint8 TBIT,RBIT;         //发送/接收比特数
bit   TING,RING;         //开始发送/接收标志
bit   TEND,REND;         //发送/接收完成标志

bit   START;         //重启标志
uint8 Correct_nums;         //『连续正确』计数器
uint8 Error_nums;         //错误累加计数器
uint8 Status;        //波特率状态

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:延时
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void YS(uint8 n)
{
  uint8 a,b,c;

  while(n--)
  {
         for(c=66;c>0;c--)
     for(b=100;b>0;b--)
     for(a=100;a>0;a--);
  }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:串口初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void UART_INIT()
{
   TING = 0;
   RING = 0;
   TEND = 1;
   REND = 0;
   TCNT = 0;
   RCNT = 0;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:逻辑分析仪初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Analyzer_Init()               
{
   TR1 = 0;
   TF1 = 0;
   Time = 0;
   BIT8 = 0;
   TL0 = 0x7E;          //初始化T0和设定重载值
   TH0 = 0xFF;         //修改成 115200bps
   LED = 0;                 //指示灯开
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:自动烧写模式下波特率切换(定时器0模拟)
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void UART_Change()
{
   if(++Status > 2)Status=0;
   switch(Status)
   {
         case 0: TL0=(65536-15000000/1200); TH0=(65536-15000000/1200)>>8; break; // 1200bps
         case 1: TL0=(65536-15000000/2400); TH0=(65536-15000000/2400)>>8; break; // 2400bps
         case 2: TL0=(65536-15000000/4800); TH0=(65536-15000000/4800)>>8; break; // 4800bps
   }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:重启程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Restart()
{                          
  if(START)
  {
         START = 0;
                                 
         TR0 = 0;
         PNP = 1;                    //关电
         LED = 1;
         YS(10);                //从『加载HEX』到『提示上电』有5秒,但不必等到『提示上电』
         WDT_CONR |= 0x10;  //清看门狗(预分频数256,约2.2S @ 45MHz)
         PNP = 0;                    //通电
         LED = 0;
         YS(30);
         WDT_CONR |= 0x10;  //清看门狗(预分频数256,约2.2S @ 45MHz)

         TR0 = 1;
         RING = 0;
     REND = 0;
     RCNT = 0;
  }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main()
{
   uint8 i;
       
   P33         = 1;
   WDT_CONR |= 0x10; //清看门狗(预分频数256,约2.2S @ 45MHz)       
   PNP = 0;                     //通电
   LED  = 0;
   LED_key = 1;                 //关
   
   for(i=0;i<30;i++){ YS(1); LED = ~LED; } //冷启/低压复位 指示
   WDT_CONR |= 0x10; //清看门狗(预分频数256,约2.2S @ 45MHz)
                     
   TMOD = 0x00;      //T0、T1处于16位自动重装模式
   AUXR = 0xC0;      //T0、T1工作在1T模式
   TL1 = (65536-903);
   TH1 = (65536-903)>>8;                                      
   UART_Change();
   TR0 = 1;  
   EA  = 1;        
   ET0 = 1;  
   PT0 = 1;          //提高T0的中断优先级
   ET1 = 1;                                           
   UART_INIT();

   Mode = 0;

   while(1)
   {                             
         switch(Mode)
     {
            case 0: if(B_init)
                        {
                                   B_init=0;
                                   TR1=0;
                   PNP = 0;                     //通电
                                   LED=0;
                                   UART_Change();
                                   UART_INIT();
                                }
                                Restart();       
                            LED_key = 1;                                           
                        break;  

            case 1: if(B_init){ B_init=0; P_N=1; Analyzer_Init(); }
                        if(!IO_in){ TR1=1; LED=1;  }        //启动定时器1,采样开始
                    if(Over)  
                                {
                                   Over=0;
                                   if(++Time > 3320)Analyzer_Init();//约16.6秒(5ms * 3320),即每次采集完,过4秒(16.6S-12.6S)后重新工作
                                }
                                LED_key = 0;                                             
                        break;

                case 2: if(B_init){ B_init=0; P_N=0; Analyzer_Init(); }
                        if(!IO_in){ TR1=1; LED=1;  }        
                    if(Over)
                                {
                                   Over=0;
                                   if(++Time > 3320)Analyzer_Init();
                                }
                                if(++Count >10000){ Count=0; LED_key=!LED_key;} //闪烁
                        break;
       
                default:Mode=0;
                        break;               
     }
         
         //按键检测
         KEY = 1;                  //拉高电平
         NOP12();                  //稍微延时
         if(!KEY)
         {
                if(ON==0)KEY_Value++;
                if(KEY_Value > 200)
            {
               KEY_Value = 0;
                   ON = 1;              //按键标志置“1”          
                   if(++Mode > 2)Mode=0;
                   B_init = 1;          //『初始化标志』置“1”
            }
         }
         else { KEY_Value=0; ON=0; }
                                                    
         //恢复指示灯状态
         if(LED_key)KEY=1;
         else       KEY=0;

         WDT_CONR |= 0x10;     //清看门狗(预分频数256,约2.2S @ 45MHz)
   }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:定时器0中断程序,模拟串口
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void tm0() interrupt 1 using 1
{                                       
   if(RING)
   {
      if(--RCNT == 0)
      {
         RCNT = 3;             //复位接收波特率计数器
         if(--RBIT == 0)
         {                  
            RBUF = RDAT;       //保存数据到RBuf管理
            RING = 0;          //停止接收
            REND = 1;          //设置接收完成标志
         }
         else
         {
            RDAT >>= 1;
            if(RXB) RDAT |= 0x80; //RX数据转移到RX缓冲区
         }
      }
   }
   else if(!RXB)                           //是否检测到低电平
   {
      RING = 1;                //设置开始接收标志
      RCNT = 4;                //初始接收波特率计数器
      RBIT = 9;                //初化始接收比特数(8个数据位+1个停止位)
   }
   
   if(--TCNT == 0)
   {
      TCNT = 3;                //复位发送波特率计数器
      if(TING)                 //判断是否发送
      {
         if(TBIT == 0)
         {
            TXB = 0;           //发送起始位
            TDAT = TBUF;       //加载数据从TBUF至TDAT
            TBIT = 9;          //初化始发送比特数(8位数据位+1个停止位)
         }
                 else
         {
            TDAT >>= 1;        //位移数据至CY
            if(--TBIT == 0)
            {
               TXB = 1;
               TING = 0;       //停止发送
               TEND = 1;       //设置发送完成标志
            }
            else
            {
               TXB = CY;       //写CY至TX端口
            }
         }
      }
   }
                                          
   if((Mode==0) && REND)                       
   {                                  
      REND = 0;
      if(RBUF == 0x7F)
          {                                        
                 if(++Correct_nums > 10)
                 {                                 
                    START=1;            
                        Correct_nums=0;       
                        Error_nums=0;
                 }
          }
          else                   
          {
             Correct_nums=0;
                 if(++Error_nums > 6)
                 {
                    TR0 = 0;
                        Error_nums=0;
                        Correct_nums=0;       
                        UART_Change();
            RING = 0;
            REND = 0;
            RCNT = 0;
                        TR0 = 1;
                 }
          }
   }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:定时器1中断程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void tm1() interrupt 3         
{                                                  
        if(IO_in)Dat |= 0x01;   
        if(++BIT8 == 8)                  //每采集8次发送一次
        {
          if(P_N)TBUF =  Dat;         //正向输出
          else         TBUF = ~Dat;         //反向输出
      TING = 1;
          BIT8 = 0;
          }
        Dat <<= 1;                         
        if(++cnt == 0)Over=1;     //约5ms置1一次
}
 楼主| 发表于 2012-2-4 20:26:31 | 显示全部楼层
回复【60楼】ppc888
-----------------------------------------------------------------------
【主位的电路,11.0592M】
那个是旧版本,电路图也有些不妥(应该把10Ω电阻去掉),下载“最低波特率”固定,而且没有逻辑分析仪功能

【32楼的电路,11.0592M】
在旧版上改进:自动适应STC-ISP软件中的“最低波特率” 3种波特率,可选“1200bps/2400bps/4800bps”
但也没有逻辑分析仪功能

【49楼的电路,45M】
程序全新修改;
自动适应STC-ISP软件中的“最低波特率” 3种波特率,可选“1200bps/2400bps/4800bps”;
增加简易单路逻辑分析仪。

PS:
STC-ISP软件中选用不同型号的STC时,默认的下载“最低波特率”不同,比如:
STC89系列:默认 最低波特率 1200bps
STC12系列:默认 最低波特率 2400bps
STC15系列:默认 最低波特率 4800bps
懒得每次选择,所以增加自适应3种最低波特率“1200bps/2400bps/4800bps”功能




另:   
        在STC单片机中有两个程序区,用户程序区与ISP程序区。单片机上电后(冷启动,并非外部手动复位或看门狗复位),先会运行ISP程序,检测是否有合法的下载命令流,占时几十毫秒到几百毫秒,如果没有合法的下载命令流,则立即运行用户程序。
       如果有合法的下载命令流,则ISP监控程序开始与ISP下载软件通信,软件也会进入编程模式,向监控程序发送程序码,监控程序接收程序码,并将其写入用户程序区中。在编程完毕,对程序校验成功后,用户程序立即生效,开始运行用户程序。
        STC-ISP尝试与MCU握手连接的时候,是以“最低波特率”设置项中的波特率不断的从串口发送“0x7F”信号,直到MCU上电冷启(或者软复位至ISP)经几十毫秒到几百毫秒检测下载命令流后,MCU做出响应,STC-ISP才停止发送“0x7F”信号开始烧写。

用简易单路逻辑分析仪捕捉,STC-ISP下载程序前的串口命令流

(原文件名:STC-ISP串口命令流.jpg)
 楼主| 发表于 2012-5-9 22:32:37 | 显示全部楼层
本帖最后由 BXAK 于 2012-5-9 22:33 编辑

这个程序构思不完善,主要是自动适应波特率部分有些BUG,
如果是固定程序中的最低波特率(对应STC-ISP的最低波特率选项,最高波特率选项任意),这个程序就运行很好,
但这样就不方便了,因为STC-ISP不同版本及不同型号默认最低波特率选项不同,懒得每次更换都改下STC-ISP的最低波特率选项。

所以使用新方案解决:
不再用硬件串口/模拟串口捕捉数据,先直接用计时器捕捉TXD上一定数量的连续电平数据,然后分析电平数据(比如:低电平时间相等,0x7F次数,……等等多重验证),
如果符合条件就重启(断电几百ms后上电,隔>1.5S恢复监测);
如果不符合条件则重新监测。

上面这个方案几近完美,负责监控的STC15F104E也不需要超频到45M了,22.1184M就可以,
同时自动适STC-ISP的最低波特率选项范围更宽1200bps/2400bps/4800bps/9600bps,
完美版的方案就是这样,挺简单的,程序就不传了
 楼主| 发表于 2012-7-27 14:14:28 | 显示全部楼层
本帖最后由 BXAK 于 2012-7-27 14:49 编辑
zyyn123 发表于 2012-7-27 13:58
我的USB转TTL下载线烧写程序正常,按您提供的图接线只能手动下载,不能自动下载。按我改过的那张图接线可 ...


发现问题所在了,电路图、连接图没错,是程序的引脚定义弄反了,

sbit RXB   = P3^2;                       
sbit TXB   = P3^3;
改成
sbit TXB   = P3^2;                       
sbit RXB   = P3^3;
就对了
【已修正】STC免手动烧写 逻辑分析仪.rar (707.56 KB, 下载次数: 921)
发表于 2011-12-15 01:15:19 | 显示全部楼层
标记
发表于 2011-12-15 06:57:01 | 显示全部楼层
图文并茂,支持一下
发表于 2011-12-15 07:13:39 | 显示全部楼层
牛人.用继电器控制,哪触点容易失效吧,
发表于 2011-12-15 08:20:34 | 显示全部楼层
stc不是可以自定义下载吗?
发表于 2011-12-15 08:27:31 | 显示全部楼层
哈哈。。好像有一块开发板上面有类似的功能。。看看哈
发表于 2011-12-15 08:31:18 | 显示全部楼层
老妖要给楼主版权费了
发表于 2011-12-15 09:26:43 | 显示全部楼层
mark
 楼主| 发表于 2011-12-15 09:32:20 | 显示全部楼层
回复【4楼】wenjin0386  
-----------------------------------------------------------------------

自定义下载占用串口、占用定时器,而且每个程序都要加入代码,麻烦
发表于 2011-12-15 10:05:34 | 显示全部楼层
那个板其实是不需要的,只修改在通讯程序里监控有没有7F,就给IAP_CONTR=0x60就可以了,如果你的波特率是9600,将STC_ISP软件的最低波特率改为9600就可以,做一块板,多一个成本!
发表于 2011-12-15 11:54:43 | 显示全部楼层
MARK
发表于 2011-12-15 12:55:58 | 显示全部楼层
不错,我的开发板已经用上了,是stm8+mos管
发表于 2011-12-15 13:06:24 | 显示全部楼层
观注!
发表于 2011-12-15 15:37:07 | 显示全部楼层
为什么不用光耦或者MOS或者三极管做开关呢???
头像被屏蔽
发表于 2011-12-15 15:40:10 | 显示全部楼层
不错,改天我做个,改成mos管控制的。
发表于 2011-12-15 16:09:27 | 显示全部楼层
回复【4楼】wenjin0386
-----------------------------------------------------------------------
一开始以为stc15F100系列无法 自动isp,其它自带串口的都可以,现在看来lz有心了!不错!

建议lz修改下标题,改为“STC15系列免手动下载程序。。。。。”为宜
发表于 2011-12-15 16:13:00 | 显示全部楼层
仔细看了下,还是要靠一个“外部断电”来实现,原以为lz实现了纯软件不断电下载stc15F100系列呐。

虽然不算纯软件方式,但很不错了!
 楼主| 发表于 2011-12-15 16:13:02 | 显示全部楼层
回复【13楼】fyx710
-----------------------------------------------------------------------

三极管有0.几的压降,手头MOS管一个也没有,多余的5V继电器倒是搁了老久,就干脆用上,也算是清仓了
 楼主| 发表于 2011-12-15 16:14:14 | 显示全部楼层
回复【15楼】zaixian 来来
-----------------------------------------------------------------------

好像你理解错了诶,

是用某一单片机(图中用的是STC15F104)来实现自动断电冷启动,免手动烧写各种型号的STC单片机
发表于 2011-12-15 17:23:32 | 显示全部楼层
这个有问题:
硬件有问题如果usb口不够输出电流当你连上要下载的单片机时会不能启动继电器,
还有如果你使用被下载的单片机P3.0口有可能收不到0x7f。经验之谈,交流交流。
 楼主| 发表于 2011-12-15 17:55:49 | 显示全部楼层
回复【20楼】downtoearth
-----------------------------------------------------------------------

1、驱动5V继电器需要60mA左右的电流,USB驱动能力500mA。
   再说了USB下载线主要是用来烧写程序用的,不是用来做大功率实验的

2、STC-ISP尝试与MCU握手连接的时候,是以“最低波特率”设置项中的波特率不断的向单片机发送“0x7F”信号,
   直到上电冷启(或者软复位至ISP)才停止发送“0x7F”信号。


被下载的单片机P3.0口有可能收不到0x7f,你是指那个10Ω电阻短路 被下载单片机VCC与GND 的原因吗?

但我这段时间一直用着没问题,目前还没有下载失败过
发表于 2011-12-15 18:10:56 | 显示全部楼层
5v继电器电流蛮大的
 楼主| 发表于 2011-12-15 19:15:51 | 显示全部楼层
回复【22楼】dzng11 原子3号
-----------------------------------------------------------------------

是蛮大的,用三极管、COMS管、还用是继电器,反正根据个人需要就好了
发表于 2011-12-15 19:26:47 | 显示全部楼层
回复【23楼】BXAK
-----------------------------------------------------------------------

主要是继电器的体型比较让人感觉不爽...



不错, 一开始我还是为是网上流传的把软件复位的代码嵌入到单片机程序里的那种, 呵呵, 赞一个~
发表于 2011-12-15 19:36:38 | 显示全部楼层
回复【8楼】BXAK
回复【4楼】wenjin0386   
-----------------------------------------------------------------------
自定义下载占用串口、占用定时器,而且每个程序都要加入代码,麻烦
-----------------------------------------------------------------------

其实我觉得这个也不麻烦
STC有独立的波特率发生器, 所以占用的只是一个串口, 要做的只是在单片机一开始的初始化工作
不过对于没有专用仿真器的STC来说, 占了个串口关系是挺大的, 我的程序基本上都是要借助串口来调试的

我现在用方法是的是单片机一启动检测RXD引脚, 如果有低电平立刻ISP启动, 也就是要手动按复位键来下载的方案,
这个是比较不占用资源的, 不过还是需要手动去按复位键, 只是免了断电
发表于 2011-12-15 19:49:51 | 显示全部楼层
我可以结合你的方案, 不使用继电器, 不过代价就是mian函数的一开始要检测RXD引脚
只要把继电器改成给目标单片机复位引脚一个复位信号, 这样也可以实现自动下载了, 呵呵

其实核心就是监听串口的内容了~
发表于 2011-12-15 20:46:40 | 显示全部楼层
usb口台机有500mA有可能,但笔记本就一定没有了。如果被下载方有使用P3.0口,stc15f104e有可能收不到0x7f,
干扰了stc15f104e的接收端。
 楼主| 发表于 2011-12-15 21:36:14 | 显示全部楼层
回复【27楼】downtoearth
-----------------------------------------------------------------------
如果被下载方有使用P3.0口,stc15f104e有可能收不到0x7f,干扰了stc15f104e的接收端。

能再具体点吗,举个例子
发表于 2011-12-15 22:09:06 | 显示全部楼层
最近也想搞个这个,通过监听串口数据来自动上电、断电。。。
 楼主| 发表于 2011-12-15 22:15:15 | 显示全部楼层
回复【28楼】BXAK
-----------------------------------------------------------------------

刚做了个实验,
被下载方烧写了个程序:P3.0口输出38KHz脉冲,
stc15f104e也由原先需要“连续”0x7f到30次才重启(中间有 != 0x7f作废)也改为要连续0x7f到100次才重启……

没有出现“如果被下载方有使用P3.0口,stc15f104e有可能收不到0x7f,干扰了stc15f104e的接收端”
发表于 2011-12-16 12:18:47 | 显示全部楼层
学习!
 楼主| 发表于 2011-12-16 14:01:03 | 显示全部楼层
最终的程序如下:

/***************************************************************
        作品:STC免手动烧写控制程序(STC15F104E监控串口数据流)
  单片机:STC15F104E(A版)
    晶振:11.0592M
编译环境:Keil uVision4 V9.00
        注意:STC-ISP软件中的“最低波特率” 可选“1200bps/2400bps/4800bps”,本程序自动检测适应。
    原理:    在STC单片机中有两个程序区,用户程序区与ISP程序区。单片机上电后(冷启动,  
         并非外部手动复位或看门狗复位),先会运行ISP程序,检测是否有合法的下载命令流,占  
         时几十毫秒到几百毫秒,如果没有合法的下载命令流,则立即运行用户程序。如果有合法的  
         下载命令流,则ISP监控程序开始与ISP下载软件通信,软件也会进入编程模式,向监控程  
         序发送程序码,监控程序接收程序码,并将其写入用户程序区中。在编程完毕,对程序校验  
         成功后,用户程序立即生效,开始运行用户程序。
                       STC-ISP尝试与MCU握手连接的时候,是以“最低波特率”设置项中的波特率不断的从串口
         发送“0x7F”信号,直到上电冷启(或者软复位至ISP)经几十毫秒到几百毫秒检测下载命令流后,
         才停止发送“0x7F”信号。
***************************************************************/

#define uint8  unsigned char
#define uint16 unsigned int       
#include "STC15F104E.H"

sbit RXB   = P3^4;
sbit Key   = P3^1;   //自动/手动开关(根据需要使用)
sbit Relay = P3^3;         //继电器(可用三极管、MOS管代替)
sbit LED   = P3^0;

uint8 RBUF;         //接收缓存
uint8 RDAT;         //接收数据暂存
uint8 RCNT;         //接收计数器
uint8 RBIT;         //接收比特数
bit   RING;         //开始接收标志
bit   REND;         //接收完成标志

uint8 cnt;         //重启计数器
bit   START; //重启标志

uint16 CN;          //波特率切换计数器
uint8  Status;//波特率状态
bit    NEW;          //波特率更新标志

void YS100ms(uint8 n)
{
  uint8 a,b,c;
  while(n--)
  {
     for(c=89;c>0;c--)
     for(b=230;b>0;b--)
     for(a=12;a>0;a--);
  }
}

void UART_INIT()
{
   RING = 0;
   REND = 0;
   RCNT = 0;

   cnt = 0;
   CN  = 0;
}

void main()
{
   P3M1 = 0x00;
   P3M0 = 0x09;                 //P3.0、P3.3推挽输出
   Key        = 1;
   Relay= 0;                 //断开继电器
   LED  = 0;                 //关LED

   
   TMOD = 0x00;      //T0处于16位自动重装模式
   AUXR = 0x80;      //T0工作在1T模式
   TL0 = 0x00;                 //初始化Timer0和设定重载值
   TH0 = 0xFA;       //默认 2400bps @ 11.0592MHz
   TR0 = 1;         
   ET0 = 1;         
   PT0 = 1;          //提高Timer0的中断优先级
   EA  = 1;           

   UART_INIT();

   while(1)
   {                                   
      if(START)
          {
                 START = 0;
                 if(Key)
                 {
                    ET0 = 0;
                    Relay = 1;                 //继电器吸合
                    LED = 1;
                    YS100ms(10);         //从『加载HEX』到『提示上电』有5秒,但不必等到『提示上电』
                    Relay = 0;
                    LED = 0;
                    YS100ms(10);
                    UART_INIT();
                        ET0 = 1;
                 }
          }

          if(NEW)
          {
                 NEW = 0;
                 TR0 = 0;
                 if(++Status > 2)Status=0;
                 switch(Status)
         {
                    case 0:TL0=0x00; TH0=0xFA;           // 2400bps @ 11.0592MHz
                                 //P32=0;P35=1;                  //状态指示灯(根据需要使用)
                                   break;
                        case 1:TL0=0x00; TH0=0xFD;           // 4800bps @ 11.0592MHz
                                     //P32=0;P35=0;                  //状态指示灯(根据需要使用)
                                   break;
                        case 2:TL0=0x00; TH0=0xF4;          // 1200bps @ 11.0592MHz
                                     //P32=1;P35=0;                  //状态指示灯(根据需要使用)
                                   break;
                 }
                 UART_INIT();
                 TR0 = 1;
          }
   }
}

void tm0() interrupt 1
{
   if(RING)
   {
      if(--RCNT == 0)
      {
         RCNT = 3;             //复位接收波特率计数器
         if(--RBIT == 0)
         {
            RBUF = RDAT;       //保存数据到RBUF
            RING = 0;          //停止接收
            REND = 1;          //接收完成标志
         }
         else
         {
            RDAT >>= 1;
            if(RXB)RDAT |= 0x80; //RX数据转移到RX缓冲区
         }
      }
   }
   else if(!RXB)                           //是否检测到低电平
   {
      RING = 1;                //设置开始接收标志
      RCNT = 4;                //初始接收波特率计数器
      RBIT = 9;                //初化始接收比特数(8个数据位+1个停止位)
   }

   if(REND)
   {
      REND = 0;
      if(RBUF == 0x7F)
          {
             cnt++;
             if(cnt > 1)CN=0;           //“0x7F”连续 > 1,则清切换计数器
                 if(cnt > 100)START=1; //“0x7F”连续 > 100,则打开重启标志
          }
          else cnt = 0;
   }

   if(++CN > 600){ CN=0; NEW=1; }//切换计数器 > 600,则打开更新标志
}
//有一旧时期的STC-ISP_4.88版的引导信号间隔时间有差异( 需要切换计数器 > 800 ),建议用最新时期的
发表于 2011-12-16 14:26:07 | 显示全部楼层
刷次先   看看
发表于 2011-12-16 20:47:33 | 显示全部楼层
发表于 2011-12-17 03:24:12 | 显示全部楼层
感谢楼主的帮助!
我也借鉴了你的做了一个,
只用了一个STC15F104来监听串口
代价就是目标单片机的主函数里的第一句要加一行代码:
IAP_CONTR |= (0x01<<6); //设置复位后从ISP启动
这样算是比较环保的了, 呵呵


(原文件名:1.jpg)


(原文件名:2.jpg)


(原文件名:3.jpg)
发表于 2011-12-17 03:31:56 | 显示全部楼层
不好意思, 代码就不上传了, 因为牵扯到我最近在做的库代码, 是打算共享的, 可是还在完善中, 就不好意思拿出来献丑了...
方案我在25, 26楼有讲的

25楼------------------
我现在用方法是的是单片机一启动检测RXD引脚, 如果有低电平立刻ISP启动, 也就是要手动按复位键来下载的方案,  
这个是比较不占用资源的, 不过还是需要手动去按复位键, 只是免了断电
26楼----------------
我可以结合你的方案, 不使用继电器, 不过代价就是mian函数的一开始要检测RXD引脚
只要把继电器改成给目标单片机复位引脚一个复位信号, 这样也可以实现自动下载了, 呵呵

其实核心就是监听串口的内容了~


其实就是楼主的代码稍微改动一下就可以变成这样了

另外我还做了点小优化, 其实无关紧要的, 就是开外部中断4(串口接收脚), 一段时间没收到串口信息后就进入掉电模式, 省点电, 环保环保~
发表于 2011-12-17 22:28:19 | 显示全部楼层
不上程序好像不太厚道, 好吧...
首先要感谢楼主, 因为STC给的软件串口那部分代码要不是因为楼主这里有注释, 我就看不懂了~
因为有一小部分代码是直接从我的STC12C5A60S2的库代码移植过来的, 所以有些地方的注释还有代码不太恰当, 也懒得改了...将就着看吧
先来一段说明:
//说明:
//        STC单片机免手动下载的串口监视器程序,
//        只使用了一个单片机STC15F104E制作
//        为了安全第因素可以在P33(目标机复位控制脚), P31脚串联一个100欧的限流电阻
//        P31(串口发送)脚如果不引出线来的话也不需要串联电阻, 引出来是为了以后更新这个串口监视程序的方便
//        还可以给串口监视器的单片机STC15F104E加一个复位电路, 因为程序里没有使用看门狗, 有复位电路方便复位
//        可以自适应波特率1200, 2400, 4800, 9600
//注意:
//        第一次下载目标机程序的时候还是需要冷启动的,
//        而且每次下载的目标机程序的代码的主函数第一句要写上一条语句:  IAP_CONTR |= (0x01<<6);
//        这条语句是用来设置目标机下次复位的时候从ISP启动的, 如果使用 BXAK 大哥的继电器的方案就不需要这样了
要想提高可靠性的还可以使用内部看门狗, 呵呵, 我就懒得加了~
上程序 ourdev_705672V00AFI.zip(文件大小:86K) (原文件名:STC15_AutoDownLoader.zip)


做得太简陋, 然后又改了下, 有个电路板还是实在一点, 然后又加了个复位按键, 手上居然只有贴片的, 麻烦死了... 还在TXD和控制复位的脚串了个100欧的电阻, 因为试的时候不小心接错差点把芯片给烧了, 然后就接个电阻保险一点...

(原文件名:1.jpg)




(原文件名:2.jpg)


(原文件名:3.jpg)
不知道有没有人注意到芯片座好像有点缺口, 因为我手上没有8脚的芯片座, 所以就用手钻从一个18脚的芯片座锯出了一个~
发表于 2011-12-17 22:53:02 | 显示全部楼层
谢谢楼主分享^
发表于 2011-12-17 23:19:37 | 显示全部楼层
STC15的定时器的新的16位自动重装的工作方式不错, 可是没了硬件串口就是个悲剧...
发表于 2011-12-18 01:01:08 | 显示全部楼层
楼主, 程序里还有一点我不太明白
  else if(!RXB)    //是否检测到低电平
   {
      RING = 1;                //设置开始接收标志
      RCNT = 4;                //初始接收波特率计数器
      RBIT = 9;                //初化始接收比特数(8个数据位+1个停止位)
   }
这里的RCNT = 4;
为什么不是RCNT = 3?
我有点怀疑是老妖写错了...唉, datasheet上只写是initial receive baudrate counter, 就没再解释了...
测试了RCNT = 3的, 也可以用
发表于 2011-12-18 01:22:25 | 显示全部楼层
我明白了, 看来我错怪老妖了

因为定时器的溢出率是波特率的3倍, 所以第一次检测到起始信号的时间一定是发送端发送一个位的
前三分之一个周期, 所以RCNT初始化为3 + 1, 那么下一次采样的时候就在下一位发送后的半个周期左右了, 这样可以有效的
减小数据传输中因为双方的时钟不是理想同步造成的误差
发表于 2011-12-18 20:17:39 | 显示全部楼层
记号下
发表于 2011-12-19 15:24:50 | 显示全部楼层
学习!
发表于 2011-12-19 18:18:02 | 显示全部楼层
我终于看明了,谢谢你楼主!
发表于 2011-12-19 19:10:46 | 显示全部楼层
记号
发表于 2011-12-19 20:15:20 | 显示全部楼层
mark
发表于 2011-12-21 15:35:09 | 显示全部楼层
MARK
发表于 2011-12-28 00:59:25 | 显示全部楼层
MARK
发表于 2012-1-5 12:06:13 | 显示全部楼层
回复【楼主位】BXAK
-----------------------------------------------------------------------

感谢楼主的无私奉献
发表于 2012-1-6 13:47:20 | 显示全部楼层
这个方案挺不错的,有时间回去自己也做个,方便很多了。
发表于 2012-1-28 12:21:10 | 显示全部楼层
回复【49楼】BXAK  
-----------------------------------------------------------------------
请问BXAK
#include "MY_SET.h"
MY_SET.h这个文件我没有啊、、麻烦您能发上来么?谢谢您了!
发表于 2012-2-4 11:47:42 | 显示全部楼层
千山万水 终于找到了这个资料了···
发表于 2012-2-4 12:01:17 | 显示全部楼层
哇~原来还有新内容~顶一下楼主~
发表于 2012-2-4 12:21:56 | 显示全部楼层
弱弱的问一下,楼主的上位机程序咋整的?能提供源码吗?
PS:用MOS管还好,三极管的压降真的会让人不放心的
发表于 2012-2-4 12:45:22 | 显示全部楼层
记得STC-ISP有个"Re-Down重复下载",板子一插就自动下了。
 楼主| 发表于 2012-2-4 14:14:10 | 显示全部楼层
回复【55楼】Pony279 霍斯
-----------------------------------------------------------------------

物尽其用,单纯自动冷启下载太浪费了,就添加了个简易逻辑分析仪



回复【56楼】Pony279 霍斯
-----------------------------------------------------------------------
上位机程序论坛里面就有,有很多人发过的,

PNP三极管也够用了,几十mA不到0.1V的压降,160mA约0.3V的压降

逻辑分析器115200bps,采样20.0736us,源码网上有:
点击此处下载 ourdev_715994QQ50A8.zip(文件大小:80K) (原文件名:逻辑分析器(115200bps,采样20.0736us).zip)
发表于 2012-2-4 19:23:52 | 显示全部楼层
学习了,我是用51做的  只检测7F。。似乎简单了很多 也浪费了很多
发表于 2012-2-4 20:10:51 | 显示全部楼层
谢谢楼下
45M晶振  明白了  4.88版本才能选择这个频率

49楼的代码 我编译错误呢···
compiling 104E.C...
104E.C(2): warning C318: can't open file 'MY_SET.h'
104E.C(12): error C129: missing ';' before 'Mode'
104E.C - 1 Error(s), 1 Warning(s).
 楼主| 发表于 2012-2-4 20:53:02 | 显示全部楼层
回复【60楼】ppc888
-----------------------------------------------------------------------
少了MY_SET.h,这个只是我的习惯配置罢了,你可以去掉不用,不过要宏定义一下
#define   uint8     unsigned char
#define   uint16    unsigned int




MY_SET.h内容如下:

#ifndef __MY_SET_H__
#define __MY_SET_H__

// data   固定指片内RAM:0x00~0x7F
// bdata  固定指片内RAM:0x20~0x2F
// idata  固定指片内RAM:0x00~0xFF
// xdata  一般指扩展RAM:0x0000~0xFFFF,也指STC内部扩展RAM:0x0000~0xFFFF
// code          指程序存储区ROM:0x0000~0xFFFF

//静态局部变量
#define   s_bit     static bit
#define   s_uint8   static unsigned char

//无符号类型
#define   uint8     unsigned char                       
#define   uint8b    unsigned char bdata               
#define   uint8i    unsigned char idata               
#define   uint8x    unsigned char xdata               
#define   uint8c    unsigned char code

#define   uint16    unsigned int
#define   uint16i   unsigned int  idata
#define   uint16x   unsigned int  xdata
#define   uint16c   unsigned int  code

#define   uint32    unsigned long
#define   uint32i   unsigned long idata
#define   uint32x   unsgined long xdata
#define   uint32c   unsgined long code

//有符号类型
#define   int8      char
#define   int8x     char xdata
#define   int8c     char code

#define   int16     int
#define   int16x    int  xdata
#define   int16c    int  code

#define   int32     long
#define   int32x    long xdata
#define   int32c    long code

//类汇编
#include  <intrins.h>
#define   NOP       _nop_()       
#define   NOP3()    {_nop_();_nop_();_nop_();}
#define   NOP12()   {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}

#endif

/* intrins.h
_crol_ 字符循环左移   
_cror_ 字符循环右移   
_irol_ 整数循环左移   
_iror_ 整数循环右移   
_lrol_ 长整数循环左移   
_lror_ 长整数循环右移   
_nop_ 空操作8051 NOP 指令
_testbit_ 测试并清零位8051 JBC 指令

(_crol_,_irol_,_lrol_)以位形式将val 循环左移n 位,该函数与8051“RLA”指令相关,上面几个函数不同于参数类型。
(_cror_,_iror_,_lror_)以位形式将val 循环右移n 位,该函数与8051“RRA”指令相关,上面几个函数不同于参数类型。
(_nop_)    产生一个NOP 指令,该函数可用作C 程序的时间比较。C51 编译器在_nop_函数工作期间不产生函数调用,即在程序中直接执行了NOP 指令。
(_testbit_)产生一个JBC 指令,该函数测试一个位,当置位时返回1,否则返回0。如果该位置为1,则将该位复位为0。
             8051 的JBC 指令即用作此目的。_testbit_只能用于可直接寻址的位;在表达式中使用是不允许的。
*/
发表于 2012-2-4 23:20:17 | 显示全部楼层
这个东西很不错啊。好东西
发表于 2012-2-5 09:27:31 | 显示全部楼层
好东西,谢谢楼主了,顺便问一下楼主,那个 WDT_CONR |= 0x10; //清看门狗(预分频数256,约2.2S @ 45MHz) 是不是少了个字母T呀.
 楼主| 发表于 2012-2-5 14:04:15 | 显示全部楼层
回复【65楼】zyyn123
-----------------------------------------------------------------------

你的STC15F104E.H头文件中是WDT_CONRT,就用WDT_CONRT。

我用的STC15F104E.H是对照STC的SFRs自己弄的
发表于 2012-2-6 14:52:57 | 显示全部楼层
MARK
发表于 2012-2-8 15:08:34 | 显示全部楼层
关注
发表于 2012-2-12 21:43:44 | 显示全部楼层
MARK  学习
发表于 2012-2-14 14:11:49 | 显示全部楼层
mark下,以后用
发表于 2012-2-17 15:01:41 | 显示全部楼层
楼主你好,这个东西我也做过,就是用15检测7F,但是在烧写过程中经常会损坏MCU,导致芯片烧写不进去。还有我不是用继电器切换的,使用的是MOS管,体积可以做的非常小。加下我QQ434978960,我想和你一起交流心得。
 楼主| 发表于 2012-2-17 18:39:54 | 显示全部楼层
回复【71楼】soldiers 阿坚
-----------------------------------------------------------------------

我也不用继电器了,那吸合/断开声挺久了——烦啊,改用三极管了,等找到MOS了再换上,

请看“49楼”的最新版本:

// 作品:STC免手动烧写(自适应波特率自动冷启) + 简易逻辑分析仪
// 芯片:STC15F104E
// 晶振:45MHz
// 编译:Keil uVision4 V9.00
//  
// 说明:自适应STC-ISP软件最低波特率(1200bps/2400bps/4800bps)
//  3种模式:①自动烧写  (默认)    【LED_key不亮:模式① ,LED亮:通电 ,LED不亮:关电】
//           ②逻辑分析仪(正向波形) 【LED_key亮  :模式② ,LED亮:预备 ,LED不亮:采样】
//           ③逻辑分析仪(反向波形) 【LED_key闪烁:模式③ ,LED亮:预备 ,LED不亮:采样】
//       ①②③模式下,系统板都可以正常串口通信。
//       ②③模式下,也可以烧写程序(手动烧写),不过正在“采样”时请不要烧写程序以及系统板串口通信。
//
//   注:建议烧写程序时启动看门狗(预分频数256,约2.2S @ 45MHz)
//
//  另:关于STC-ISP V4.88版本,发现用PL2303HX芯片烧写STC15系列很难成功,最低/高波特率都选用4800bps才可以烧写。
//  关于STC-ISP V6.06版本,用PL2303HX芯片烧写STC15系列非常好(直接用默认的最低/高波特率),
//       但V6.06版本内部R/C振荡器最高只可以选33.1776MHz。
//  用FT232芯片烧写,则通杀STC-ISP所有版本(直接用默认的最低/高波特率)。
//
发表于 2012-2-21 23:11:43 | 显示全部楼层
mark
发表于 2012-2-21 23:14:40 | 显示全部楼层
标记
发表于 2012-2-21 23:19:01 | 显示全部楼层
mark
发表于 2012-2-21 23:21:15 | 显示全部楼层
做实验的时候实用,但量产的话,重复烧录时几秒钟就自动等待烧写,目标板同时要接上下载线,这个时候能自动识别并接通电源么?
发表于 2012-2-21 23:57:09 | 显示全部楼层
原来这样,不过我的开发板烧录不用手动的
 楼主| 发表于 2012-2-22 00:24:50 | 显示全部楼层
回复【76楼】GDYJ
-----------------------------------------------------------------------

当然可以,1~9秒重复下载都没问题,其实点击“重复下载”也和编译后目标代码变化自动下载差不多
发表于 2012-5-9 11:53:28 | 显示全部楼层
BXAK 发表于 2011-12-16 14:01
最终的程序如下:

/***************************************************************

版主能不能把头文件STC15F104E.H上传一下呢。
 楼主| 发表于 2012-5-9 12:02:00 | 显示全部楼层
曹世鹏 发表于 2012-5-9 11:53
版主能不能把头文件STC15F104E.H上传一下呢。

STC免手动烧写 逻辑分析仪.rar (549.17 KB, 下载次数: 820)
发表于 2012-5-9 12:54:10 | 显示全部楼层
BXAK 发表于 2012-5-9 12:02

版主,谢谢你。
发表于 2012-5-9 13:01:46 | 显示全部楼层
关注一下
发表于 2012-5-9 21:33:59 | 显示全部楼层
不错哦。今天我照楼主给的程序做了一个。自动下载程序时可以将继电器吸合的时间延时一下。然后下载间隔时间不能太近。也就是说不能下载完一个程序以后不能紧接着再次下载。如果下载间隔太小,就可能造成15F104E不动作。但是并没有死机。不知为什么。
发表于 2012-5-10 14:20:00 | 显示全部楼层
BXAK 发表于 2012-5-9 22:32
这个程序构思不完善,主要是自动适应波特率部分有些BUG,
如果是固定程序中的最低波特率(对应STC-ISP的最 ...

楼主真的好用心呀。谢谢楼主。
发表于 2012-5-10 14:23:58 | 显示全部楼层
发表于 2012-5-21 20:44:10 | 显示全部楼层
你好,我用从宏晶申请的STC-ISP下载器,链接按照您的电路和程序做的下载器,成功。但是链接我用CH341T做的USB下载器,就不行了。能帮我分析一下原因吗?谢谢~~
 楼主| 发表于 2012-5-21 22:48:50 | 显示全部楼层
friends369 发表于 2012-5-21 20:44
你好,我用从宏晶申请的STC-ISP下载器,链接按照您的电路和程序做的下载器,成功。但是链接我用CH341T做的U ...

单独用CH341T做的USB下载器正常可以下载程序吗
发表于 2012-5-22 10:17:26 | 显示全部楼层
BXAK 发表于 2012-5-21 22:48
单独用CH341T做的USB下载器正常可以下载程序吗

谢谢你的回复!单独用CH341T的USB下载器可以下载程序。
 楼主| 发表于 2012-5-22 10:31:10 | 显示全部楼层
friends369 发表于 2012-5-22 10:17
谢谢你的回复!单独用CH341T的USB下载器可以下载程序。

如果方便,画个简单的连线图看看(CH341与自动下载转接板、目标单片机之间VCC、GND、TXD、RXD的连接情况)
发表于 2012-5-22 13:49:59 | 显示全部楼层
不错   
发表于 2012-5-22 16:42:00 | 显示全部楼层
这个不错,值得学习一下。。。
发表于 2012-5-23 19:36:52 来自手机 | 显示全部楼层
用继电器?电流有点大了吧。
发表于 2012-5-23 21:26:43 | 显示全部楼层
本帖最后由 friends369 于 2012-5-23 21:29 编辑
BXAK 发表于 2012-5-22 10:31
如果方便,画个简单的连线图看看(CH341与自动下载转接板、目标单片机之间VCC、GND、TXD、RXD的连接情况 ...


谢谢你,下面是我的电路图:

图片4.jpg

图片4.jpg

Micro Core board(MCB)-STC.pdf

814.85 KB, 下载次数: 1532

 楼主| 发表于 2012-5-23 23:49:39 | 显示全部楼层
friends369 发表于 2012-5-23 21:26
谢谢你,下面是我的电路图:

3.3V供电,板上怎么是用STC12C5A60S2(5V单片机)?
发表于 2012-5-24 10:20:10 | 显示全部楼层
BXAK 发表于 2012-5-23 23:49
3.3V供电,板上怎么是用STC12C5A60S2(5V单片机)?

后来将其换成STC15L104E,效果一样。
 楼主| 发表于 2012-5-24 12:14:58 | 显示全部楼层
friends369 发表于 2012-5-24 10:20
后来将其换成STC15L104E,效果一样。

只是想问目标板是STC12C5A60S2(5V单片机),还是STC12L5A60S2(3V单片机)?

修改.jpg
发表于 2012-5-24 20:36:42 | 显示全部楼层
顶了
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2019-10-23 09:22

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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