分享

51单片机一键下载相关

 昵称11763061 2017-05-28
最新版本最新版本:

(原文件名: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; //指示灯开
}

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)
}
}

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;
}
}
}
}

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一次
}【主位的电路,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下载程序前的串口命令流
这个程序构思不完善,主要是自动适应波特率部分有些BUG,
如果是固定程序中的最低波特率(对应STC-ISP的最低波特率选项,最高波特率选项任意),这个程序就运行很好,
但这样就不方便了,因为STC-ISP不同版本及不同型号默认最低波特率选项不同,懒得每次更换都改下STC-ISP的最低波特率选项。

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

上面这个方案几近完美,负责监控的STC15F104E也不需要超频到45M了,22.1184M就可以,
同时自动适STC-ISP的最低波特率选项范围更宽1200bps/2400bps/4800bps/9600bps,
完美版的方案就是这样,挺简单的,程序就不传了













    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多