avr单片机_avr单片机例程 - CSDN
精华内容
参与话题
  • AVR单片机原理及应用(高清PDF中文版)

    热门讨论 2020-07-21 09:57:58
    本书在概述ATMEL公司开发的AT89系列、AT90系列、AT91M系列单片机之后,详细介绍了AVR增强型RISC单片机的结构、指令系统、90系列多种单片机、实用程序设计以及AVR单片机的应用实例,最后介绍了AVR单片机的开发工具,...
  • AVR单片机仿真100例-

    2020-07-17 17:51:11
    PROTEUS仿真AVR单片机仿真100例-基于AVR+PROTEUS仿真
  • AVR单片机EEPROM学习

    千次阅读 2016-05-29 12:55:07
    学完51单片机时,我以为小小的单片机无非就是进行一些IO口的控制罢了,但今天在进行AVR系列单片机学习的时候,才发现原来单片机还有很多的不同,自己原来掌握的东西还远远不足,所以无论到什么时候只有虚心学习,...

    生活中我们经常会犯眼高手低的毛病,很多东西看着别人弄很容易,但轮到自己的时候就会发现其实没有想象中的简单。学完51单片机时,我以为小小的单片机无非就是进行一些IO口的控制罢了,但今天在进行AVR系列单片机学习的时候,才发现原来单片机还有很多的不同,自己原来掌握的东西还远远不足,所以无论到什么时候只有虚心学习,不断努力才能真正的掌握一门技术,学习的过程也是自己人格丰富的过程。下面来说说对EEPROM学习的一些感受。

    AVR单片机内部已集成了512kb的EEPROM,对EEPROM的操作比51单片机相对简单一些。写EEPROM操作:

    操作:

    主函数将记录打开开发板的次数,将开机数送EEPROM保存,开机后使用LED显示开发板的启动次数。

    书写主函数时出现了一些错误:

    由于变量i,每次启动时不能记录上一次的数据,导致写入EEPROM中的数据错误,最终导致程序错误,因此不能随便修改程序执行顺序。所有问题调试通过后,下载到开发板运行时,发现开发板根本就不会执行程序,很奇怪。咨询厂家客服后,给出的建议是设置程序的优化度,于是将优化度设置为2后程序运行正常。

    展开全文
  • AVR单片机资源(很丰富,很详细,有源码,带解释,适合初学者使用) 有以下(很多,列不完,先列一些) AD转换 AT24C02的实验 DS1302实验 DS18B20实验 EEPROM实验 PWM实验 看门狗实验 串口SPI实验 外部中断0实验 ...
  • 几种AVR单片机的中文数据手册,特别详细,是最好的单片机教程
  • AVR单片机

    2019-06-11 17:18:54
    单片机## #include <iccioavr.h> #include <macros.h> #include<stdio.h> void Show(); void Shift(unsigned char tmp); void Delay(int num); unsigned char tmp,flg=0; unsigned char seg[10]=...

    单片机##


    #include <iccioavr.h>
    #include <macros.h>
    #include<stdio.h>
    void Show();
    void Shift(unsigned char tmp);
    void Delay(int num);
    unsigned char tmp,flg=0;
    unsigned char seg[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};
    unsigned char buf[4]={0x9f,0x25,0x0d,0x99};   //预设学号数组: 1234 
    unsigned char en[4]={0x7f,0xbf,0xdf,0xef};   //数码管扫描数组
    unsigned int count;
    
    void main()
    {
     DDRA=DDRA|0x01;	  			  //设定PA0为输出   					  								  
     PORTA=PORTA|0x01;				  //起始时所有SER=PA0="Hi"
     DDRB=DDRB|0x03;                  //设定RCLK=PB0,SRCLK=PB1输出
     PORTB=PORTB&0xfc;				  //起始时使PB0=PB1="Lo"
     DDRD=0xf7;	  			          //设定PORT D为输出 
     PORTD=0xff;					  //起始时PB4~PB7="Hi"  					  								  
     GICR=GICR|0x80;
     MCUCR=MCUCR|0x08;
     SREG=SREG|0x80;
     
    do{
     	Show();
       }while(1);
    
    }
    void Show()
    {
     int i;
     
     for(i=0;i<=3;i++)
        {
         Shift(buf[i]);					//将显示数组送至该数码管
    	 PORTB=PORTB|0x01;
    	 PORTB=PORTB&0xfe;
         PORTD=PORTD&en[i];					//开启该位数码管
         Delay(80);						    //延迟5ms
         PORTD=PORTD|0xf0;					//关闭所有数码管
        }
    }
    
    void Shift(unsigned char tmp)
    {
     int i;
     
     for(i=0;i<8;i++)
        {
    	 if((tmp&(0x01<<i))==0)    //移位
    	    PORTA=PORTA&0xfe;
         else
    	    PORTA=PORTA|0x01;	
         PORTB=PORTB|0x02;
         PORTB=PORTB&0xfd;
    	} 
    }
    
    void Delay(int num)                  //时间延迟子程序 
    {
     int i,j;
         
     for(j=0;j<=num;j++);
         for(i=0;i<50;i++);
    }
    复制代码

    1. 关键的地方
     if((tmp&(0x01<<i))==0)    //移位
            PORTA=PORTA&0xfe;
    复制代码

    <<移位操作


    2.这些不知道是干嘛的

    GICR=GICR|0x80;
     MCUCR=MCUCR|0x08;
     SREG=SREG|0x80;
    复制代码

    3.Shitft函数

    unsigned char en[4]={0x7f,0xbf,0xdf,0xef};   //数码管扫描数组
    
    Shift(buf[i]);
    复制代码

    入口:一个16进制的显示数码管数字。 如Shift(buf[0])为Shift(0x7f)送到数码管显示为1


    4.74HC595

    转载于:https://juejin.im/post/5ce4fc756fb9a07ea4205431

    展开全文
  • AVR单片机C语言

    2020-07-15 23:32:04
    关于AVR,C语言开发的书籍,属于硬件类型,比较合适初学者入门使用
  • 原文: 关于AVR单片机熔丝位的设置和拯救方法大全 AVR单片机熔丝位的设置和详细的拯救方法  熔丝位是ATMEL公司AVR单片机比较独到的特征。在每一种型号的AVR单片机内部都有一些特定含义的熔丝位,其特性表现为...

    原文: 关于AVR单片机熔丝位的设置和拯救方法大全 AVR单片机熔丝位的设置和详细的拯救方法

        熔丝位是ATMEL公司AVR单片机比较独到的特征。在每一种型号的AVR单片机内部都有一些特定含义的熔丝位,其特性表现为多次擦写的E²PROM。用户通过配置(编程)这些熔丝位,可以固定地设置AVR的一些特性,参数以及I/O配置等,当然也包括对片内运行代码的锁定(加密)。

        用户使用并行编程方式、ISP编程方式、JTAG编程方式都可以对AVR的熔丝位进行配置,但不同的编程工具软件提供对熔丝位的配置方式(指人机界面)也是不同的。有的是通过直接填写熔丝位位值(如:CVAVR、PonyProg2000和SLISP等),有的是通过列出表格选择(如AVR STUDIO、BASCOM-AVR)。前者程序界面比较简单,但是需要用户在仔细查询操作,会引起一些意想不到的后果,如造成芯片无法正常运行,无法再次定入ISP编程模式等。建议用户对AVR的熔丝位进行配置时,选择用户表格选择方式界面的编程软件,如BASCOM-AVR。不过版主使用的是前者PonyProg2000。 对AVR熔丝位的配置操作是比较细致的工作,用户往往忽视其重要性,或感到不易掌握。看到这么多的人对AVR的熔丝位不会使用和误操作,结合本人的使用实践,给出以下方面的意见和参考。 下面给出对AVR熔丝位的配置操作时的一些要点和需要注意的相关事项以及相应的拯救方法。

         (一)设置方法 1.1.1 正确配置AVR熔丝位 对AVR熔丝位的配置是比较细致的工作,用户往往忽视其重要性,或感到不易掌握。下面给出对AVR熔丝位的配置操作时的一些要点和需要注意的相关事项。有关ATmega128熔丝位的具体定义和功能请查看本书相关章节,在附录中将给出一个完整的汇总表。

    (1)在AVR的器件手册中,对熔丝位使用已编程(Programmed)和未编程(Unprogrammed)定义熔丝位的状态,“Unprogrammed”表示熔丝状态为“1”(禁止);“Programmed”表示熔丝状态为“0”(允许)。因此,配置熔丝位的过程实际上是“配置熔丝位成为未编程状态“1”或成为已编程状态“0””。

    (2)在使用通过选择打钩“√”方式确定熔丝位状态值的编程工具软件时,请首先仔细阅读软件的使用说明,弄清楚“√”表示设置熔丝位状态为“0”还是为“1”。

    (3)使用CVAVR中的编程下载程序时应特别注意,由于CVAVR编程下载界面初始打开时,大部分熔丝位的初始状态定义为“1”,因此不要使用其编程菜单选项中的“all”选项。此时的“all”选项会以熔丝位的初始状态定义来配置芯片的熔丝位,而实际上其往往并不是用户所需要的配置结果。如果要使用“all”选项,应先使用“read->fuse bits”读取芯片中熔丝位实际状态后,再使用“all” 选项。

    (4)新的AVR芯片在使用前,应首先查看它熔丝位的配置情况,再根据实际需要,进行熔丝位的配置,并将各个熔丝位的状态记录备案。

    (5)AVR芯片加密以后仅仅是不能读取芯片内部Flash和E2PROM中的数据,熔丝位的状态仍然可以读取但不能修改配置。芯片擦除命令是将Flash和E2PROM中的数据清除,并同时将两位锁定位状态配置成“11”,处于无锁定状态。但芯片擦除命令并不改变其它熔丝位的状态。

    (6)正确的操作程序是:在芯片无锁定状态下,下载运行代码和数据,配置相关的熔丝位,最后配置芯片的锁定位。芯片被锁定后,如果发现熔丝位配置不对,必须使用芯片擦除命令,清除芯片中的数据,并解除锁定。然后重新下载运行代码和数据,修改配置相关的熔丝位,最后再次配置芯片的锁定位。

    (7)使用ISP串行方式下载编程时,应配置SPIEN熔丝位为“0”。芯片出厂时SPIEN位的状态默认为“0”,表示允许ISP串行方式下载数据。只有该位处于编程状态“0”,才可以通过AVR的SPI口进行ISP下载,如果该位被配置为未编程“1”后,ISP串行方式下载数据立即被禁止,此时只能通过并行方式或JTAG编程方式才能将SPIEN的状态重新设置为“0”,开放ISP。通常情况下,应保持SPIEN的状态为“0”,允许ISP编程不会影响其引脚的I/O功能,只要在硬件电路设计时,注意ISP接口与其并接的器件进行必要的隔离,如使用串接电阻或断路跳线等。

    (8)当你的系统中,不使用JTAG接口下载编程或实时在线仿真调试,且JTAG接口的引脚需要作为I/O口使用时,必须设置熔丝位JTAGEN的状态为“1”。芯片出厂时JTAGEN的状态默认为“0”,表示允许JTAG接口,JTAG的外部引脚不能作为I/O口使用。当JTAGEN的状态设置为“1”后,JTAG接口立即被禁止,此时只能通过并行方式或ISP编程方式才能将JTAG重新设置为“0”,开放JTAG。

    (9)一般情况下不要设置熔丝位把RESET引脚定义成I/O使用(如设置ATmega8熔丝位RSTDISBL的状态为“0”),这样会造成ISP的下载编程无法进行,因为在进入ISP方式编程时前,需要将RESET引脚拉低,使芯片先进入复位状态。

    (10)使用内部有RC振荡器的AVR芯片时,要特别注意熔丝位CKSEL的配置。一般情况下,芯片出厂时CKSEL位的状态默认为使用内部1MHz的RC振荡器作为系统的时钟源。如果你使用了外部振荡器作为系统的时钟源时,不要忘记首先正确配置CKSEL熔丝位,否则你整个系统的定时都会出现问题。而当在你的设计中没有使用外部振荡器(或某钟特定的振荡源)作为系统的时钟源时,千万不要误操作或错误的把CKSEL熔丝位配置成使用外部振荡器(或其它不同类型的振荡源)。一旦这种情况产生,使用ISP编程方式则无法对芯片操作了(因为ISP方式需要芯片的系统时钟工作并产生定时控制信号),芯片看上去“坏了”。此时只有使用取下芯片使用并行编程方式,或使用JTAG方式(如果JTAG为允许时且目标板上留有JTAG接口)来解救了。另一种解救的方式是:尝试在芯片的晶体引脚上临时人为的叠加上不同类型的振荡时钟信号,一旦ISP可以对芯片操作,立即将CKSEL配置成使用内部1MHz的RC振荡器作为系统的时钟源,然后再根据实际情况重新正确配置CKSEL。

    (11)使用支持IAP的AVR芯片时,如果你不使用BOOTLOADER功能,注意不要把熔丝位BOOTRST设置为“0”状态,它会使芯片在上电时不是从Flash的0x0000处开始执行程序。芯片出厂时BOOTRST位的状态默认为“1”。关于BOOTRST的配置以及BOOTLOADER程序的设计与IAP的应用请参考本章相关内容。

        1.1.2 ATmega128中重要熔丝位的配置 上一小节介绍了配置AVR熔丝位的要点和注意事项,本小节把在一般情况下使用ATmega128时,几个重要的熔丝位配置情况进行说明。

    (1)熔丝位M103C。M103C的配置将设定ATmega128是以ATmega103兼容方式工作运行还是以ATmega128本身的方式工作运行。ATmega128在出厂时M103C默认状态为“0”,即默认以ATmega103兼容方式工作。当用户系统设计使芯片以ATmega128方式工作时,应首先将M103C的状态配置为“1”。

    (2)CLKSEL0..3。CLKSEL0、CLKSEL1、CLKSEL2、CLKSEL3用于选择系统的时钟源。有五种不同类型的时钟源可供选择(每种类型还有细的划分)。芯片出厂时的默认情况为CLKSEL3..0和SUT1..0分别是“0001”和“10”。即使用内部1MHz RC振荡器,使用最长的启动延时。这保证了无论外部振荡电路是否工作,都可以进行最初的ISP下载。对于CLKSEL3..0熔丝位的改写需要十分慎重,因为一旦改写错误,会造成芯片无法启动,见上一小节第10点说明。

    (3)JTAGEN。如果不使用JTAG接口,应将JTAGEN的状态设置为“1”,即禁止JTAG,JTAG引脚用于I/O口。

    (4)SPIEN。SPI方式下载数据和程序允许,默认状态为允许“0”。一般保留其状态。

    (5)WDTON。看门狗的定时器始终开启。WDTON默认为“1”,即禁止看门狗的定时器始终开启。如果该位设置为“0”后,看门狗的定时器就会始终打开,不能被内部程序控制了,这是为了防止当程序跑飞时,未知代码通过写寄存器将看门狗定时器关断而设计的(尽管关断看门狗定时器需要特殊的方式,但它保证了更高的可靠行)。

    (6)EESAVE。执行擦除命令时是否保留E2PROM中的内容,默认状态为“1”,表示E2PROM中的内容同Flash中的内容一同擦除。如果该位设置为“0”,对程序进行下载前的擦除命令只会对FLASH代码区有效,而对E2PROM区无效。这对于希望在系统更新程序时,需要保留E2PROM中数据的情况下是十分有用的。

    (7)BOOTRST。决定芯片上电起动时,第一条执行指令的地址。默认状态为“1”,表示起动时从0x0000开始执行。如果BOOTRST设置为“0”,则起动时从BOOTLOADER区的起始地址处开始执行程序。BOOTLOADER区的大小由BOOTSZ1和BOOTSZ0决定,因此其首地址也随之变化。

    (8)BOOTSZ1和BOOTSZ0:这两位确定了BOOTLOADER区的大小以及其起始的首地址。默认的状态为“00”,表示BOOTLOADER区为4096字,起始首地址为0xF000。

    (9)推荐用户使用ISP方式配置熔丝位。配置工具选用BASCOM-AVR (网上下载试用版,它对ISP下载无限制),和STK200/STK300兼容的下载电缆(见第四章内容)。

    注:不同AVR的熔丝也不同,使用前必须仔细查看芯片手册。 要重视手册学习,不仅是掌握如何使用,也是从根本上认识和掌握原理和结构。对于硬件工程师来将,数据手册是真正的“经书”,其它都是“修练经验”。不熟读“经书”,你无法修炼成“仙”的。这也是《M128》、《M8》的目的之一!

        (二)AVR熔丝位拯救方法详细攻略

      1.1.3 AVR芯片的ISP全攻略 当然你在配置熔丝位时要小心从事,防止芯片锁死。有不少网友屡屡遭此不幸。其实你在熔丝位配置时,只要方法正确,一般是不会出错的。如果当你改动了AVR的熔丝位配置,重新加电后,想再用ISP下载,提示:“进入编程模式失败”等,极有可能是你搞错了熔丝位,导致芯片不知道使用何种外部主频而无法正常工作(仅限于使用内部RC振荡的情况)。不过,不用太担心,其实拯救的办法还是有很多的,操作起来也是很容易的,具体解决方法为:

    1。进入JTAG模式修改SPIEN熔丝位 需要使用JTAGICE调试器,不过一般情况下调试模式也进不去,JTAGEN(值为1)锁死了。

    2。并行编程器恢复 需要你有USB或COM1口制作的并行HVPROG编程器,STK200/STK300

    3。通过外加有源晶振 需要你有外部有源振荡晶体(石英或晶振1-4M) 这个方法最简单,速度最快(强烈推荐)

    4。使用通用编程器将芯片恢复到出厂状态 这个方法,需要你有市场上的通用编程器,可以修改三个熔丝位寄存器数据。

    5。寄回给芯片服务商,让他们帮忙将芯片恢复 这是最省事,但是最费时间,最无可奈何的方法。 先介绍一下基本恢复理论 ISP(In System Programmability) 在系统编程,简称为 串行下载 IAP(In Application Programing) 在应用编程,BootLoader也是类似的意思

    1. ISP虽然利用了SPI接口(例外:M64/M128为UASRT0接口,Tiny13等没有SPI接口)的引脚,但只在复位时起作用,而且下载完成后合格的下载器会自动断开端口的连接,对正常工作时没有影响的( 在产品应用中,下载器一定是不会一直粘在上面的)。

    2. 虽然高压并行下载能修复任何熔丝位,但对于贴片封装来说是很不现实的,所以添加ISP10标准插座接口后就是最常用的ISP下载方式了

    3. 虽然IAP是一种新的升级方法,但IAP程序本身也是要先用高压并行下载或ISP来烧进芯片里面才行

    4. Tiny13等少管脚AVR芯片因为管脚实在太少了,有ISP,但没有[高压并行编程]而特制了[高压串行编程] 所以,产品上一般都留有ISP10标准接口插座,或更省位置的ISP6标准插座----留6个焊盘就行了

        ISP的工作前提 1. 芯片没有物理损坏

    2. 芯片的SPIEN熔丝位=0 使能ISP功能

    3. 芯片的RSTDISBL熔丝位=1 RESET引脚有效 (假如芯片有这个熔丝位)

    4. 线路正常--接错线? 短路?

    5. ISP下载器正常-------特别要考虑 连线的接触不良问题

    6. 电源正常 (一) 并行编程器恢复,最早的编程方法, 功能最强大,通常需要12V~24V的高压,以示区别,下面称为 高压并行编程。制作方式也有:

    1.USB或COM1口制作的并行HVPROG编程器,软件例如USBASP的ISP上位机软件AVR_fighter.exe(zhb2000)和USBAVRISP(ZHIFENG),但需要AVR MCU连接较多的引脚 (一般20脚);


    2.并行编程器STK200/STK300,串行编程器软件PonyProg2000. 但需要电脑留有LPT打印机接口,AVR MCU留有ISP6-10标准烧写口。


    1.以我们常用的小马PonyProg2000串行编程器下载软件为例,在Command菜单中选Security and Configuration Bits,(或者点Security and Configuration Bits按钮)在接着出现的熔丝位配置窗口的下面,有几个按钮,千万不要乱按。正确的方法是先按“Read”按钮,读出原来芯片中熔丝位的配置,然后再以此为基础,按你的需要进行局部修改,确定无误后再按“Write”按钮,就OK了。一般不会出现锁死的问题。如果万一由于操作不当,出现锁死也不必惊慌。

    2.除了用并行编程器恢复的方法以外,对于没有并行编程器的朋友,还可以用外接有源振荡器的方法解锁,方法是用一个1MHz的振荡信号接到ATmega16L的 13脚XTAL1,接通单片机的电源,正常的话你会看到原来单片机中的程序已经可以正常运行了。说明外接振荡器已经使单片机恢复工作了。这下来就好办了,仍然用PonyProg2000,点Security andConfiguration Bits按钮,进入熔丝位配置窗口,这时你会看到所有的熔丝位都没打√,连灰色的SPIEN前面那个模糊不清的√也没了,不过没关系Don’t worry,你只要按照下图中ATmega16L出厂时熔丝位的设置打√,然后按“Write”按钮,如果屏幕轻轻的闪一下,OK,恭喜你已经好了,再按“Read”按钮,你会看到除了你打√的地方以外,SPIEN前面那个模糊不清的√也出来了。锁死的芯片已经解锁了。


    要注意的是外接的信号幅度不可太大,以免损毁芯片,我开始用一个51单片机的震荡信号接过来,结果不行,可能是驱动能力不够。后来换了一个信号发生器输出的1MHz的信号,就成功了。也可以用NE555芯片搭个振荡器做信号源。 (二)外加有源晶振


    运行时钟 ISP时钟(必须低于运行时钟的1/4) 4096Hz <1024Hz //很变态的用法,外接32.768KHz晶体+CKDIV8 ,不过AVRISP还是提供了603Hz这个速度了 //另一简易解决办法是 下载时在32.768KHz晶体并联一个1MHz晶体,双龙的下载线就配有一个8MHz的石英晶体 32768Hz <8192Hz 128KHz < 32KHz //内部RC128KHz 1.0MHz <250KHz //默认值(包括8MHz+CKDIV8),所以AVRISP的ISP速度多为230KHz 8.0MHz <2000KHz 16.0MHz <4000KHz 运行时钟不等于震荡器的频率,因为部分AVR芯片有系统时钟预分频器,可以对震荡器进行1~256分频

    CKDIV8熔丝位决定CLKPS位的初始值。 若CKDIV8未编程,CLKPS位复位为“0000”;若CKDIV8 已编程,CLKPS 位复位为“0011”,给出启动时分频因子为8 AVRISP可提供的ISP时钟 921.6KHz,230.4KHz, 57.6KHz,28.8KHz,4.0KHz, 603Hz STK500可提供的ISP时钟 1.845MHz,460.8KHz,115.2KHz,57.6KHz,4.0KHz,1206Hz 时钟设定 ISP方案 内部RC 选择合适的ISP速度 外部RC 接上合适的电阻和电容,选择合适的ISP速度。------补救: 外部时钟源接到XTAL1 外部RC 根本就没有什么意义,频率精度/稳定度不高,成本也没有降低,所以新的AVR芯片已经没有这个选项了。

     各位网友要注意的是错误设定后补救方法 外部晶体 接上合适的晶体,选择合适的ISP速度。 ------补救: 外部时钟源接到XTAL1 外部时钟 接上合适的时钟源,选择合适的ISP速度。 ------补救: 外部时钟源接到XTAL1 外部时钟源可以是 外部(4MHz)有源晶体输出,其他MCU的XTAL2脚,各种方波振荡电路(NE555)输出等 大部分AVR芯片的ISP端口是 SCK,MOSI,MISO,RESET 而M64/M128的ISP端口是 SCK, PDI, PDO,RESET</font> 而且M64/M128出厂默认兼容M103----熔丝位M103C=0,很多新特性不能使用,程序也可能不能正常运行 ----因为C编译器通常默认自动把SP指向SRAM的末端,M103=0x0FFFH, M64/M128=0x10FFH,必然出错! AVR的所有熔丝位均是: 1 未编程,多为不起作用的意思。 0 编程,多为 起作用的意思。 基于可编程工艺的都是这样: PROM/EEPROM/FLASH都是出厂时和擦除后变为全1(0xFF)的,要编程才能变成0。 反过来就是了,跟CE/OE/INT都是[低电平有效]一样,都是很常见。 在ISP模式下永远不能访问(修改)SPIEN位,这是AVR芯片的硬件保护 有独立RESET脚的M16/M32/M64/M128等,在ISP模式下根本就就不会令ISP无效,无论如何修改熔丝位,都能恢复正常。 M8/M48/M88/M168/Tiny系列有RSTDISBL熔丝位可以令导致RESET失效而令ISP无法工作外,其他情况都能恢复正常。

     一般来说,只要满足ISP的工作前提,再把XTAL1接到一个4MHz有源晶体的输出,基本是万试万灵的。 通过外加有源晶振的办法,让其恢复, 这个方法最可行。它可以恢复大部分熔丝位搞错的芯片。(重点推荐) 接法如下


    打点的口子对应1号脚依次逆时针1 NC2 GND3 CLK4 VCC 1脚不接,2脚接地,3脚接输出,4脚接电源。恢复方法:

    接上上图的有源晶振,重新通电,可以看到芯片又重新正常工作了,这时就能用ISP或JTAG下载线修改错误的熔丝位了。修改完成后,断电,将有源晶振拆走,看看是否已经恢复正常。

        还有一个办法,如果没有有源晶振的话可以用其他工作正常的单片机的时钟作为外部晶振,只要将工作正常的单片机的XTAL2脚连接熔丝设置错误的单片机的XTAL1引脚即可。像我使用AVR910下载线的可直接把AT90S2313的时钟输出连到被设置错的芯片就可恢复了,很方便。

         不要忘记,并行高压编程的时钟信号也是从XTAL1导入方波信号的。 如果有源晶振的方法不行(除了ISPEN=0,RSTDISBL=0情况外),恐怕高压编程也未必能奏效。 其他一些功能操作对ISP熔丝位的影响

    1. JTAG的影响(M16,M32,M128等): JTAG能访问 SPIEN 和 JTAGEN,要是不小心同时改成SPIEN=1,JTAGEN=1,将会导致MCU锁死,需要高压并行编程才能恢复。

    2. DebugWIRE的影响:(M48,M88,M168,T2313等,数据手册里面的资料不是很详细) 由于DebugWIRE使用RESET脚来通讯,所以跟ISP有所冲突 可以通过ISP或并行高压编程来使能DebugWIRE功能[即DWEN=0],使能DebugWIRE功能后,ISP功能失效。 可以通过DebugWIRE来关闭DebugWIRE功能[即DWEN=1],关闭DebugWIRE功能后,如果RSTDISBL=1,SPIEN=0,ISP功能有效。 比较特殊的是 DebugWIRE调试中,断点的使用会降低Flash 数据记忆时间 DebugWIRE调试用的器件不能发给最终客户。

    3.JTAG MKII同时具备JTAG/DeubgWIRE/ISP三种功能,可以轻松实现DebugWIRE/ISP的切换。 (软件需要升级到1.09版以后 即对应AVRstudio 4.12以后版本) <ahref=http://218.16.124.196/bbs/bbs_content.jsp?bbs_sn=551225&bbs_page_no=1&sub_kind_id=1205&bbs_id=1000>最新版本 JTAG MK2使用说明中文pdf(20051125) 设计使用debugWIRE 的系统时,必须进行下面的检查: • dW/(RESET) 的上拉电阻不得小于10kΩ。debugWIRE 并不需要上拉电阻 • 将 RESET 引脚与 VCC 直接连接将无法工作 • 使用debugWIRE 时必须断开与RESET 引脚连接的电容 • 必须断开所有的外部复位源

        end

     

    展开全文
  • AVRStudio&Proteus 8 Professional:traffic_light引语题目实现过程系统框图流程图以及操作说明电路原理图代码 引语 记录学习路程,抛砖引玉。如有更好的算法或者出现错误,欢迎指点。 题目 实现十字路口交通灯...

    引语

    记录学习路程,抛砖引玉。如有更好的算法或者出现错误,欢迎指点。

    题目

    1. 实现十字路口交通灯控制运行(包括白天模式、夜间模式、紧急模式三种情况)
    2. 红绿灯运行时间可通过按键实时修改,修改后的运行时间可通过两位数码管显示, 并实际保存下来(即断电后再上电,依然能保存最新修改的红绿灯运行时间)
    3. 创新地自行设计了光敏实现白天模式与夜间模式的自动切换

    实现过程

    步骤如下:

    1. 初步构思出功能实现的系统框图
    2. 根据构思画出流程图,进一步设计实现题目要求,根据需求拟出按键操作说明
    3. 探索电路原理图
    4. 把功能细化,有序进行设计以及代码编写
    5. 查漏补缺进一步完善项目

    系统框图

    在这里插入图片描述

    流程图以及操作说明

    在这里插入图片描述

    一共设计了8个按键,序号代表按键序号

    1. 在时间调节时进行减一操作。
    2. 在时间调节时进行加一操作。
    3. 进入南北方向(上下两个模块)的时间调整状态,数码管显示需要调节的时间,调整的相应的灯亮(例如:调整黄灯为5s,数码管显示5,黄灯亮)
    4. 进入东西方向(左右两个模块)的时间调整状态,数码管显示需要调节的时间,调整的相应的灯亮(例如:调整红灯为15s,数码管显示15,红灯亮)
    5. 模式间的切换,按照(普通模式、夜间模式、紧急模式)顺序进行循环切换
    6. 在紧急模式情况下按照(禁止通行、东西通行、南北通行)顺序进行循环切换
    7. 待定(无功能)
    8. 储存设定的时间,切断电源后重启将会是设定后的时间

    在使用过程中的调节环节,由于是同个按键根据顺序进行调节,为避免调节重复所以添加了笑脸^^确认项来确认已完成调整,然后再进一步进行其他操作。

    电路原理图

    在这里插入图片描述
    选用的单片机是atmega128单片机,其中的PB端控制数码管显示,PC端控制灯的显示,PD端控制按键输入,PE1端口连接位移寄存器,PF0端口作为光敏控制端。74HC595是一款漏极开路输出的CMOS位移寄存器,输出端口为可控三态输出端,所以通过使用74HC595串行输出控制数码管显示。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    元件清单:
    7SEG-MPX2-CC、74HC595、7404、ATMEGA128、BUTTON、LED-GREEN
    LED-RED、LED-YELLOW、RES、TORCH_LDR、[7404]

    代码

    #include  <avr/io.h>
    #include  <util/delay.h>
    #define   delay_ms(x)   _delay_ms(x)
    #include  <avr/interrupt.h>
    
    const unsigned char disp[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    unsigned char ledbuf[]={0x00,0x00,0x00,0x00};// 显示缓冲区,分别存放的是南北和东西方向的十位、个位段码
    
    int ms10=0,sec=0,x1,x2;
    
    
    int a1=10,b1=6,c1=4,a2=10,b2=7,c2=3;
    int nbred,nbgreen,nbyellow,dxred,dxgreen,dxyellow;  
    
    
    int x=0,dx=-1,nb=-1,shanshuo=1,k=-1,turn=-1,save=0,STOP_music=0,T=-1,CLOCK=0,led=0,sos=-1;
    
    
    
    
    
    
    
    
    
    
    /******定时器1的初始化,CTC模式,8分频,中断周期5ms******/
    void  disp_init(void)
    {
    	OCR1A = 4999;		//100Hz=8MHz/(2*8*(1+OCR1A))
    	TCCR1A = 0x00;
    	TCCR1B = (1 << WGM12);        //CTC模式
    	TCCR1B |= (1 << CS11);	//8分频
    	TIMSK |= (1 << OCIE1A);	//开比较匹配中断A
    }
    
    
    
    
    /******数码管显示函数 ******/
    void display(char num,char pos)
    { 	SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);
    	PORTB &= 0x0F; 		//关位选
    	PORTB &=~(1<<0);
    	SPDR=num;
    	while(0==(SPSR&0X80)); 	//等待 SPIF中断结束置位
    	PORTB|=(1<<0);
    	PORTB |= 1<<(7-pos);
    }
    
    
    
    
    
    
    /********数码管控制IO初始化*******/
    void io_init(void)
    
    {
    	PORTC = 0x00;   //灯
    	DDRC  = 0xFF;	//灯
    	
    	
    	DDRD = 0X00;	//八位独立按键
    	PORTD = 0XFF;	//PD口8个按键端口输入,上拉
    	
    	DDRE=0xFF;
    	PORTE&=~(1<<1); //74HC595使能
    	
    	PORTB = 0xFF;	//PB4\5\6\7控制数码管位码
    	DDRB |= 0xFF;   //(1<<PB7) | (1<<PB6) | (1<<PB5) | (1<<PB4);
    }
    	
    
    
    
    
    
    
    //扫描键盘,获得键码
    void key_read(void)
    {
    	unsigned char i,j; 	 	 	 	 	 	//键码记录
    	unsigned char key_num;
    	i=PIND; 	 	 	 					//按键表示的数字 并记录
    	delay_ms(20);  	 	 					//去按键颤抖
    	j = PIND; 								//j=除抖后的按键情况
    	if(i == j) 	 	 	 	//二次对比确定按键操作,且有按键按下
    	{
    		switch (i) 							 //将按键码转换成键值
    		{
    			case  0x7F: 	save=(++save)%2;      break;    //8  灯时间调整完成后的存档 数据写入EEPROM 
    			case  0xBF:   CLOCK=(++CLOCK)%3;
    			STOP_music=0;  		break;    //7  
    			case  0xDF:  sos=(++sos)%3; 	break;	  	  //6  紧急模式 0禁止通行    1南北通行      2东西通行 
    		
    			
    								 
    			case  0xEF: 	x=(++x)%3;		break;	  	  //5  模式切换 0为普通模式  1为夜间模式    2为紧急模式 
    			
    			
    			
    			case  0xF7: 	dx=(++dx)%5;	break;	   	  //4  时间调整,0东西红灯 1东西绿灯 2东西黄灯   3笑脸确认设置
    			case  0xFB:   nb=(++nb)%5;      break;   	//3  时间调整,0南北红灯 1南北绿灯 2南北黄灯    3笑脸确认设置
    		
    		
    			case  0xFE: 								//1
    			if(nb==0) a1--;       	//南北的红黄绿灯  第一键对应减一      
    			if(nb==1) b1--;
    			if(nb==2) c1--;
    			
    			if(dx==0) a2--;       	//东西的红黄绿灯  第一键对应减一      
    			if(dx==1) b2--;
    			if(dx==2) c2--;
    			
    			break;
    			
    			
    			
    			
    			case  0xFD: 			//2 
    			if(nb==0) a1++;		  //南北的红黄绿灯  第二键对应加一
    			if(nb==1) b1++;
    			if(nb==2) c1++;
    		
    		
    			if(dx==0) a2++;		  //东西的红黄绿灯  第二键对应加一
    			if(dx==1) b2++;
    			if(dx==2) c2++;
    			break;
    		
    		
    		
    		
    			default:      break;
    		}
    			while(PIND!=0xFF)  ; 				//等待按键松开
    	}
    }
    
    
    
    /******中断服务程序的功能******/
    ISR(TIMER1_COMPA_vect)
    
    {
    		static unsigned char j=0,c=0; //显示刷新标志
    	j++;c++;
    	k=(++k)%4; 				     	//k 实现轮流刷新数码管
    
    
        
    
    
    	if(j>99)  {shanshuo ^= 1;j=0;}  //小数点闪烁周期设置   1s=0.05*100*2
    	
    	
    	
    	
    	
    	/*************交通灯时间写操作**************/
    	if(c>199)
    	{
    		c=0;
    		if(save==1)      //将交通灯时间数据写入EEPROM
    		{
    			
    			
    			
    			
    		    EEPROM_write(100,a1);
    		    EEPROM_write(101,b1);
    		    EEPROM_write(102,c1);
    		    EEPROM_write(103,a2);
    		    EEPROM_write(104,b2);
    		    EEPROM_write(105,c2);
    		}	
    		
    	}
    	
    	
    	
    		/*******时间调整范围及数字变换*******/
    	if(ms10>99)   
    	{
    	    ms10=0;
    	    
    		  
    		
    		x1=nbred;nbred--;
    		x2=dxgreen;dxgreen--;  //100 * 10 =1s
    		PORTC = 0x0A;
    	   
    	
    	    if(nbred<0)     
    		{
    		    x1=nbgreen;nbgreen--;//南北红绿黄变换 
    		    PORTC = PORTC + 0x08;
    		    
         	    if(nbgreen<0)      
    			{
    			    x1=nbyellow;nbyellow--;
    			    PORTC = PORTC + 0x10;
    			    
    	            if(nbyellow<0)      
    			    {nbred=a1;nbgreen=b1;nbyellow=c1;x1=nbred;PORTC = PORTC - 0x18;}
    			}
    	    }
    	
    	 
    	    if(dxgreen<0)      
    		{
    		    x2=dxyellow;dxyellow--;//东西绿黄红变换 
    		    PORTC = PORTC + 0x02;
    		    
    	        if(dxyellow<0)      
    			{
    			    x2=dxred;dxred--;
    			    PORTC = PORTC - 0x03;
    			    
    	            if(dxred<0)          
    			    {dxgreen=b2;dxred=a2;dxyellow=c2;x2=dxgreen;PORTC = PORTC + 0x01;}
    			}
    	    }
    	    
    	    
    	}	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    		/******时间调整显示*******/
    	if(nb==0)     //南北红灯调整
    	{
            
    
    	    dx=-1;x=-1;
    		PORTC = 0x08;
    		if(shanshuo==1)
    		ledbuf[1] = disp[a1%10];
    		else
    		ledbuf[1] = 0x00;
    		
    		ledbuf[0] = disp[a1/10];
    		ledbuf[2] = 0x00;
    		ledbuf[3] = 0x00;
    		display(ledbuf[k],k);
    	}
    
    	if(nb==1)   //南北绿灯调整
    	{
    
    	    dx=-1;x=-1;
    		PORTC = 0x10;
    		if(shanshuo==1)
    		ledbuf[1] = disp[b1%10];
    		else
    		ledbuf[1] = 0x00;
    
    		ledbuf[0] = disp[b1/10];
    		ledbuf[2] = 0x00;
    		ledbuf[3] = 0x00;
    		display(ledbuf[k],k);
    		
    	}
    
    	if(nb==2)		//南北黄灯调整
    	{
    	    dx=-1;x=-1;
    		PORTC = 0x20;
    		if(shanshuo==1)
    		ledbuf[1] = disp[c1%10];
    		else
    		ledbuf[1] = 0x00;
    		
    		ledbuf[0] = disp[c1/10];
    	    ledbuf[2] = 0x00;
    	    ledbuf[3] = 0x00;
    		display(ledbuf[k],k);
    	}
    	
    	if(nb==3)		//设置确认 
    	{
    	    dx=-1;x=-1;
    		PORTC = 0x00;
    		ledbuf[1] = 0x23;
    		
    		ledbuf[0] = 0x23;
    	    ledbuf[2] = 0x23;
    	    ledbuf[3] = 0x23;
    		display(ledbuf[k],k);
    	}
    	
    	
    	
    	
    	
    	
    	
    	if(dx==0)     //东西红灯调整
    	{
    	    nb=-1;x=-1;
    		PORTC = 0x01;
    		if(shanshuo==1)
    		ledbuf[3] = disp[a2%10];
    		else
    		ledbuf[3] = 0x00;
    		
    		ledbuf[2] = disp[a2/10];
    		ledbuf[1] = 0x00;
    		ledbuf[0] = 0x00;
    		display(ledbuf[k],k);
    	}
    
    	if(dx==1)   //东西绿灯调整
    	{
    	    nb=-1;x=-1;
    		PORTC = 0x02;
    		if(shanshuo==1)
    		ledbuf[3] = disp[b2%10];
    		else
    		ledbuf[3] = 0x00;
    
    		ledbuf[2] = disp[b2/10];
    		ledbuf[1] = 0x00;
    		ledbuf[0] = 0x00;
    		display(ledbuf[k],k);
    		
    	}
    
    	if(dx==2)		//东西黄灯调整
    	{
    	    nb=-1;x=-1;
    		PORTC = 0x04;
    		if(shanshuo==1)
    		ledbuf[3] = disp[c2%10];
    		else
    		ledbuf[3] = 0x00;
    		
    		ledbuf[2] = disp[c2/10];
    	    ledbuf[1] = 0x00;
    	    ledbuf[0] = 0x00;
    		display(ledbuf[k],k);
    	}
    
    	if(dx==3)		//设置确认 
    	{
    	    nb=-1;x=-1;
    		PORTC = 0x00;
    		ledbuf[1] = 0x23;
    		
    		ledbuf[0] = 0x23;
    	    ledbuf[2] = 0x23;
    	    ledbuf[3] = 0x23;
    		display(ledbuf[k],k);
    	}
    	
    	
           if(save==1)
    	      {  
    			nb=-1;dx=-1;sos=-1;
    		    PORTC = 0x00;
    		    ledbuf[1] = 0x23;
    		    ledbuf[0] = 0x23;
    	        ledbuf[2] = 0x23;
    	        ledbuf[3] = 0x23;
    		    display(ledbuf[k],k);
    	      }
    	
    	
    	
    	
    	
    	
    	display(ledbuf[k],k);      //数码管显示函数
    }
    
    
    
    
    
    
    /************AD测电压值实现光控开启夜间模式************/
    unsigned int get_ad(void) 
    { 
       long int i;  
       ADMUX = (1 << REFS0);  //参考电压AVCC
       ADCSRA = (1<< ADEN) | (1 << ADSC) | (1 << ADPS1) | (1 << ADPS0); //ADC使能,开始转换,8分频 
       while(!(ADCSRA & (1 << ADIF))); //等待转换结束中断标志置位 
       i = ADC; //取转换结果
       ADCSRA &= ~(1 << ADIF); //清除中断标志 
       ADCSRA &= ~(1 << ADEN); //关闭ADC 
       return i; 
    }
     
    
    
    
    	
    	
    	
    	
    	
    	
    /************EEPROM写操作************/
    
    void EEPROM_write(unsigned int Address,unsigned char Data)
    {
    	while(EECR&(1<<EEWE));			//等待上一次写操作结束
    	EEAR = Address;  				//地址
    	EEDR = Data;  					//数据
    	EECR |= (1<<EEMWE);  			//置位EEMWE
    	EECR |= (1<<EEWE);				//置位EEWE启动写操作
    }
    
    
    
    
    
    /************EEPROM读操作************/
    int EEPROM_read(unsigned int Address)
    {
    	while(EECR&(1<<EEWE));			//等待上一次写操作结束
    	EEAR = Address;  				//地址
    	EECR |= (1<<EERE); 				//置位EEMWE
    	return EEDR;  					//返回读取结果
    }
    
    
    
    
    
    //主 函 数 
    int main()
    {
    	ledbuf[3] = 0x00;
    	ledbuf[2] = 0x00;
    	ledbuf[1] = 0x00;
    	ledbuf[0] = 0x00; 
    
    
        long int i;
        
        
    	io_init();
    	disp_init();
    	sei();
    	
    	
    	
    
       
    	
    	
    		
    	
    
    
    
    
    
    	
    	
    	
        	/********读设置交通灯时间*********/
    
    	if(save==0)
    	{
    	    T=-1;nb=-1;dx=-1;sos=-1;
    		a1=EEPROM_read(100);
    		b1=EEPROM_read(101);
    		c1=EEPROM_read(102);
    		a2=EEPROM_read(103);
    		b2=EEPROM_read(104);
    		c2=EEPROM_read(105);
    	}
    	
    
    
    
        nbred=a1,nbgreen=b1,nbyellow=c1;
    	dxred=a2,dxgreen=b2,dxyellow=c2;
    	
    
    
    	
    	
    	while (1)
    	{
            
    		key_read(); 	 	//键盘扫描
    		delay_ms(50); 		//键盘扫描间隔
    		
    		
            i = get_ad()/204.8;
    
    
    		
    		if(x==0)//普通模式 
    		{
    			T=-1;sos=-1;			//消除其他功能时间显示干扰
    	
    	      if(i>2)                //光控处检查的电压值作为是否为夜间模式标准
    		  {
    		    ms10++;
    			ledbuf[3] = disp[x2%10];
    			ledbuf[2] = disp[x2/10];
    			ledbuf[1] = disp[x1%10];
    			ledbuf[0] = disp[x1/10];
    	      }
    	      
    	      else
    	      {
    	        ledbuf[3] = 0x00;
    	        ledbuf[2] = 0x00;
            	ledbuf[1] = 0x00;
    	        ledbuf[0] = 0x00;
    
    			if(shanshuo==1)
    			PORTC = 0x24;
    			else
    			PORTC = 0x00;
    		  }
    		  
    		  
           
    	
    			
    		}
    		
    		
    		if(x==1)//夜间模式 
    		{
    
                T=-1;sos=-1;			//消除其他功能时间显示干扰
                ledbuf[3] = 0x00;
    	        ledbuf[2] = 0x00;
            	ledbuf[1] = 0x00;
    	        ledbuf[0] = 0x00;
    
    			if(shanshuo==1)
    			PORTC = 0x24;
    			else
    			PORTC = 0x00;
    			
    		} 
    		
    		
    		
    		if(x==2)//紧急模式 
    		{
    			nb=-1;dx=-1;T=-1;;		//消除其他功能时间显示干扰
    			ledbuf[3] = 0x00;
    	        ledbuf[2] = 0x00;
            	ledbuf[1] = 0x00;
    	        ledbuf[0] = 0x00;
    			PORTC = 0x09;
    			if(sos==0) PORTC = 0x09;
    			if(sos==1) PORTC = 0x0A;
    			if(sos==2) PORTC = 0x11;
    			
    			
    		} 
    			
    	 
    	    
    
        
    
    	      
    	
    	
    	    
    			
    	
    		delay_ms(10); //键盘扫描间隔
    	}
    	
    	
    	
    } 
    	
    	
    	
    	
    	
    	
    
    	
    	
    	
    	
    	
    	
    
    
    展开全文
  • AVR单片机 实验一 单片机基本输入输出(GPIO)实验 1 实验目的 掌握ICCAVR 集成开发环境的使用; 了解ATmega16单片机管脚的输入输出寄存器的使用方法; 2 实验内容 建立一个工程,实现流水灯的功能,并通过ISP下载到...
  • avr单片机定时器控制串口It is also a very simple program, the Simple DC motor can be rotated clockwise when the input is given to the positive terminal and vice versa for Anti-clockwise rotation. ...
  • 一: AVR 单片机实现 LED 灯闪烁.

    千次阅读 2012-10-10 14:07:57
    不同的开发环境, C 语言的语句不同, 主要看头文件里有没... 也可以选用 IAR 或者Code Vision AVR 或 ICC AVR等.  没工夫捣鼓了. ATmega16 有 4 个 8 位的双向 I/O 端口 PA, PB, PC, PD, 他们对外对应 32 个 I/O 引脚
  • avr单片机复位电路

    千次阅读 2014-05-20 10:57:31
    avr单片机复位电路 AVR复位电路的设计  与传统的51单片机相比,AVR单片机内置复位电路,并且在熔丝位里,可以控制复位时间,所以,AVR单片机可以不设外部上电复位电路,依然可以正常复位,稳定工作。   若是...
  • 51单片机与AVR单片机区别

    千次阅读 2010-10-19 01:27:00
    AVR比,51是老掉牙的东西,内部资源少,速度慢,但学习简单,是用的最多最精典的单片机AVR是后来才出来的,工艺上远超过51,内部资源丰富,速度快。 并不是必需得学,但学了最好,学了51再学AVR就快很多了,因为...
  • 51,AVR,PIC,MSP430,STM32单片机比较

    万次阅读 2014-02-03 10:43:24
    这里是几款单片机的对比...如果既要综合考虑价格、功耗、性能,那选择AVR单片机 如果追求高性能,那就用STM32 如果产量很大,那用PIC单片机   我有幸接触了几款单片机,并用它们做了一些项目。现在想做个小总结,
  • AVR单片机寄存器DDR,PORT和PIN之间对应关系(摘)     AVR单片机每一个I/O口都对应3个寄存器DDRx,PORTx和PINx,其中DDRx为数据方向,即输入或输出;PORTx为将内部上拉电阻的状态,PINx为读取...
  • 51单片机程序烧写说明

    千次阅读 2014-12-26 14:52:02
    程序烧写说明 USBASP下载器使用方法 启动下载软件PROGISP1.6.7 烧录步骤: 设置编程器及接口,编程器选择USBASP,接口为USB(如图) 选择芯片,在选择芯片下拉列表可以选择正在使用的单片机型号51或者avr均可(常用...
  • 1.AVR单片机熔丝位锁死简单快捷的解密方法:  在很多AVR单片机的初学者在使用AVR单片机中,很容易把熔丝位弄错而造成单片机锁死,比如说JTAGEN置为1后,单片机的JTAG就不能再下载程序进去了,因此给我们带来很多...
  • 经常有网友说flash校验失败,不知什么原因。现简要说明: 1,电路不稳定,解决办法,对比经典电路修改。 2,未擦除芯片就直接编程flash和校验flash导致校验失败(很多时候就是这个原因)。...
  • 各种单片机的比较(avr 8051 stc 等)

    千次阅读 2010-05-12 21:14:00
    1、AVR单片机与8051的比较: 主要区别是内核不同,指令集不同,io结构不同,外设不同。 优点是速度快,IO强大,性价比高。 AVR单片机比8051的硬件资源多得多,AVR单片中的MEGA系列内部还有AD转换器,在一些简单的...
1 2 3 4 5 ... 20
收藏数 6,147
精华内容 2,458
关键字:

avr单片机