51单片机一键下载相关

发布者:SereneJourney最新更新时间:2015-08-21 来源: eefocus关键字:51单片机  一键下载 手机看文章 扫描二维码
随时随地手机看文章
  x宝上有很多买51单片机一键下载器的,就是U转串又配了一个stc15的单片机检测下载码,检测到了就断电再启动。
挺巧妙的,就去找了一下原理。
 
电路图如下:

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

实物图:

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


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

注意事项:

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

源程序:

#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();
                 }
          }
   }
}
[page]
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


#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 ),建议用最新时期的
 
 
最新版本最新版本:

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


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


(原文件名:a.jpg) 


(原文件名:20111229019.jpg) 
[page]
// 作品: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,
完美版的方案就是这样,挺简单的,程序就不传了













 

关键字:51单片机  一键下载 引用地址:51单片机一键下载相关

上一篇:基于超声波传感器的车载超重监控报警系统
下一篇:STC51单片机的下载问题相关

推荐阅读最新更新时间:2024-03-16 14:29

AT89C51单片机频率计的C源程序设计
本文是基于AT89C51单片机的频率计的C源程序。该频率计主要实现的功能有如下几个: 1. 测试功能 它表明数字频率计所具备的全部测试功能,一般包括测频,周期,累计脉冲数,频率比,时间间隔及自较等功能。 2. 测量范围 它说明不同功能的有效测量范围。如测频率时,测量范围是数字频率计处于正常工作条件下,被测信号的频率范围,一般用频率的上,下限值表示,低端大部分从10Hz开始;高端因不同的频率计而异。因此高端频率是确定低,中,高速计数器的依据。在测量周期时,测量范围常用周期的最大值,最小值表示。 3. 输入特性 数字频率计一般有2~3个输入通道,测试不同项目时,被测信号可经不同的通道输入仪器。输入特性是表明数字式频率计于被
[单片机]
89S51单片机智能语音拨号报警系统
电话自动报警的主要功能为: 用户根据需要把自己的手机号码、办公室电话或报警监控中心的电话预存入报警主机。报警主机不断地对所监控的设备( 门禁、烟雾探测器、窗磁、摄像头等) 状况进行巡检, 当有不安全情况( 如火灾、非法入室、视频丢失等) 发生时, 报警主机拨通预先存入的电话号码, 播放相应的警情语音。若电话占线或者无人接听,可拨下一个预存的电话号码, 如果所有预存的电话都占线或者无人接听, 则会自动把所有的预存电话重拨一遍, 保证了报警的有效性和可靠性。 1 系统组成和工作原理 系统组成框图如图1 所示。采用AT89C51 单片机 作为控制核心, 外接E2PROM 用于存储电话号码、设置参数( 定时布/撤防、联动、视频等)
[单片机]
89S<font color='red'>51单片机</font>智能语音拨号报警系统
51单片机指令周期,机器周期,时钟周期详解
51单片机有指令周期,机器周期,时钟周期的说法,看似相近,但是又都不太一样,很容易混淆。还是详细分析一下。 时钟周期:单片机外接的晶振的振荡周期就是时钟周期,时钟周期=振荡周期。比方说,80C51单片机外接了一个11.0592M的晶体振荡器,那我们就说这个单片机系统的时钟周期是1/11.0592M,这里要注意11.0592M是频率,周期是频率的倒数。 机器周期:单片机执行指令所消耗的最小时间单位。我们都知道51单片机采用的CISC(复杂指令指令集),所以有很多条指令,并且各条指令执行的时间也可能不一样(有一样的哦),但是它们执行的时间必须是机器周期的整数倍,这就是机器周期的意义所在。8051系列单片机又在这
[单片机]
<font color='red'>51单片机</font>指令周期,机器周期,时钟周期详解
基于51单片机ADC0808自动数字电压表仿真数码管显示
硬件设计 该设计是基于51单片机,ADC采用TI公司的ADC0808,自动数字电压测量表,显示器采用4位数码管,测量范围为0.5~10V,精度约为0.02。 仿真图如下: 程序源码: #include reg52.h unsigned char code dispbitcode ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char dispbuf ; unsigned int i; unsigned int j; unsigned int getdata; unsigned int temp; unsigned int temp1;
[单片机]
基于<font color='red'>51单片机</font>ADC0808自动数字电压表仿真数码管显示
51单片机按键控制舵机
#include reg52.h #define Stop 0 //宏定义,停止 #define Left 1 //宏定义,左转 #define Right 2 //宏定义,右转 sbit ControlPort = P1^0; //舵机信号端口 sbit KeyLeft = P1^1; //左转按键端口 sbit KeyRight = P1^2; //右转按键端口 sbit KeyStop = P1^3; //归位按键端口 unsigned char TimeOutCounter = 0,LeftOrRight = 0; //TimeOutCounter:定时器溢出计数 LeftOrRigh
[单片机]
基于51单片机的带时间显示的红绿灯设计
功能: 带时间显示的红绿灯设计,30秒南北绿灯,东西红灯;3次闪烁黄灯;切换为30秒东西绿灯,南北红灯; 具体定时时间可根据程序自行修改,带有源程序、仿真图。 仿真效果图: 部分程序: #include reg51.h #include intrins.h #define uchar unsigned char uchar led ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar delay(int i) {uchar a,b,c; for(i;i 0;i--) {for(c=167;c 0;c--) for(b=171;b 0;b--) for(
[单片机]
为何MCS-51单片机要中断系统扩展?定时器怎样作外部中断源?
为什么MCS-51单片机要用到中断系统扩展? 答:虽然MCS-51已经提供了两个外部中断申请输入端INT0、INT1,但在外部中断请求源需求仍然较多时,就要用到中断系统扩展。 定时器作为外部中断源时,用什么方法实现? 答:当MCS-51的两个定时/计数器选择为计数方式时,T0或T1引脚上发生的负跳变将使T0或T1计数器加1。利用它,就可以把T0、T1作为外部中断请求输入线,而定时器的溢出中断就可以作为外部中断请求的标志。
[单片机]
基于89C51单片机的环境噪声测量仪
   1 引 言      环境噪声监测,是人类提高生活质量,加强环境保护的一个重要环节,在各大城市的繁华街区和居民区,已有大型环境噪声显示器竖立街头。但目前国内的便携式噪声测试仪,多为价格昂贵的进口专用设备,除卫生、计量等环保专业部门拥有外,无法作为民用品推广普及。本文介绍一种以89C51单片机为核心,采用V/F转换技术构成的低成本、便携式数字显示环境噪声测量仪。该仪器工作稳定、性能良好,经校验定标后能满足一般民用需要,可广泛应用于工矿企业、机关、学校等需要对环境噪声进行测量和控制的场合。 2 声压级的测量机理   人耳的听阈一般是20μPa,痛阈一般是200 Pa,其间相差107倍,这样宽广的声压范围很不易测量,
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved