单片机小灯闪烁教学手段_pic单片机汇编小灯闪烁 - CSDN
  • 51单片机闪烁一个小灯

    千次阅读 2017-02-25 09:45:17
    让灯可以闪烁,通过延时达到目的: /*-------------------------... 该程序是单片机学习中最简单最基础的, 通过程序了解如何控制端口的高低电平 ------------------------------------------------*/ #include //包

    让灯可以闪烁,通过延时达到目的:

    /*-----------------------------------------------
        内容:点亮P1口的1个LED灯闪烁
            该程序是单片机学习中最简单最基础的,
    		通过程序了解如何控制端口的高低电平
    ------------------------------------------------*/
    #include<reg52.h> //包含头文件,一般情况不需要改动,
    //头文件包含特殊功能寄存器的定义
    
    sbit LED0=P1^0;// 用sbit 关键字 定义 LED到P1.0端口,
    //LED是自己任意定义且容易记忆的符号
    
    void Delay(unsigned int t); //函数声明
    /*------------------------------------------------
                        主函数
    ------------------------------------------------*/
    void main (void)
    {
                      //此方法使用bit位对单个端口赋值
    
    
    while (1)         //主循环
      {
      LED0=0;            //将P1.0口赋值 0,对外输出低电平
      Delay(10000);      //调用延时程序;更改延时数字可以更改延时长度;
                         //用于改变闪烁频率
      LED0=1;            //将P1.0口赋值 1,对外输出高电平
      Delay(10000);
                         //主循环中添加其他需要一直工作的程序
      }
    }
    /*------------------------------------------------
     延时函数,含有输入参数 unsigned int t,无返回值
     unsigned int 是定义无符号整形变量,其值的范围是
     0~65535
    ------------------------------------------------*/
    void Delay(unsigned int t)
    {
     while(--t);
    }
    


    展开全文
  • 最简单的STM32入门教程----闪烁LED

    万次阅读 2018-07-10 13:55:00
    本文讲述的是如何从零开始,使用keil建立一个简单的STM32的工程,并闪烁LED灯,给小白看。第零步,当然首先你得有一个STM32的板子,其IO口上接了一个LED。。。第一步,建立一个文件夹0.0第二步,打开keil,建立工程...

    本文讲述的是如何从零开始,使用keil建立一个简单的STM32的工程,并闪烁LED灯,给小白看。

    第零步,当然首先你得有一个STM32的板子,其IO口上接了一个LED。。。

    第一步,建立一个文件夹0.0

    第二步,打开keil,建立工程

    在弹出来的对话框中选择你所用的STM32的芯片。

    在接下来弹出来的对话框中选择是,这样keil就帮我们建立好了启动文件。

     

    第三步,新建一个main.c文件,并添加到工程中。

     

    点击New按钮,建立一个文本文件。

    在建立的文本文件中输入C中的main函数

    点击保存

    保存后,将文件添加到工程中

    第四步,点击编译

    可以看到keil有报错

    错误信息为:没有定义的符号SystemInit,这是因为在启动文件中有调用SystemInit函数,但是我们没有定义它,如下图:

    暂时不用理会上述启动文件中汇编的含义,只需在main.c中添加该函数即可消除该错误。

    修改后再编译,程序没有报错了。至此,一个STM32的工程就建立完成了。

     第五步,将下面的代码复制粘贴

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    #define PERIPH_BASE           ((unsigned int)0x40000000)
    #define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
    #define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
    #define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
    #define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
    #define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
    #define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
    #define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
    #define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)
    #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
    #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
    #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
    #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
    #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
    #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
    #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C 
     
    #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
    #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
     
     
    #define LED0  MEM_ADDR(BITBAND(GPIOA_ODR_Addr,8))
    //#define LED0 *((volatile unsigned long *)(0x422101a0)) //PA8
    typedef struct
    {
      volatile unsigned int CR;
      volatile unsigned int CFGR;
      volatile unsigned int CIR;
      volatile unsigned int APB2RSTR;
      volatile unsigned int APB1RSTR;
      volatile unsigned int AHBENR;
      volatile unsigned int APB2ENR;
      volatile unsigned int APB1ENR;
      volatile unsigned int BDCR;
      volatile unsigned int CSR;
    } RCC_TypeDef;
     
    #define RCC ((RCC_TypeDef *)0x40021000)
     
    typedef struct
    {
    volatile unsigned int CRL;
    volatile unsigned int CRH;
    volatile unsigned int IDR;
    volatile unsigned int ODR;
    volatile unsigned int BSRR;
    volatile unsigned int BRR;
    volatile unsigned int LCKR;
    } GPIO_TypeDef;
     
    #define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
     
    void LEDInit(void)
    {
        RCC->APB2ENR|=1<<2; //GPIOA 时钟开启
        GPIOA->CRH&=0XFFFFFFF0;
        GPIOA->CRH|=0X00000003; 
    }
     
    //粗略延时
    void Delay_ms(volatile unsigned int t)
    {
        unsigned int i,n;
        for(n=0;n<t;n++)
            for(i=0;i<800;i++);
    }
     
    int main(void)
    {
        LEDInit();
        while(1)
        {
            LED0=0;
            Delay_ms(500);
            LED0=1;
            Delay_ms(500);
        }
    }
     
    void SystemInit(void)
    {
         
    }

      

    下面一段是对代码的简单讲解,可不用太深入。

    /

    STM32 GPIO输出高低电平的完整流程如下:

    配置时钟→配置IO口→IO口输出高地电平

    1,STM32的时钟是可以PLL的。但是我这里为了简化操作,就不配置,只使用默认的时钟----内部8MZH振荡器。

    2,硬件上,我的LED灯是接到PA8。那么,我要怎么控制PA8呢?

    STM32不能像单片机一样,一上来就能操作IO口。要操作STM32的IO口,首先要配置IO口。

    void LEDInit(void)

    {

        RCC->APB2ENR|=1<<2;

        GPIOA->CRH&=0XFFFFFFF0;

        GPIOA->CRH|=0X00000003;     

    }

    其中RCC->APB2ENR|=1<<2;是使能GPIOA的时钟。若是要使能GPIOB的时钟则是RCC->APB2ENR|=1<<3;其他的以此类推。

        GPIOA->CRH&=0XFFFFFFF0;

        GPIOA->CRH|=0X00000003;   

    是配置PA8为推挽输出,50MHZ。

    若是要设置PA9则是:

        GPIOA->CRH&=0XFFFFFF0F;

        GPIOA->CRH|=0X00000030;   

    其他的以此类推,若是PA0~PA7则将CRH改为CRL就行。

    若是要配置其他GPIO口,将GPIOA改成GPIOB,GPIOC。。。就行。,

    3,我们知道51单片机是可以单独控制每个IO口的,STM32也可以做到,这个机制叫做Bit-Bond。

    参考《Cortex-M3权威指南》可知道,只要找到PA8输出寄存器在Bit-Bond的地址,即可操作PA8的输出。地址的计算方法如下图:

    《Cortex-M3权威指南》还给出了C语言宏定义的方法,我们可以直接使用。

     /

    将上述代码输入后,点开配置选项,配置如下:

    勾上 Create HEX File

     

     

    选择J-Link下载工具

     

    再次build,然后下载就大功告成啦。

     

    综上可以看出,若是不配置STM32的PLL,那么相对于51单片机,STM32闪烁LED灯只不过多了一个步骤----配置GPIO口为输出而已。

    嵌入式学习交流群:769843038

    参考资料:http://www.makeru.com.cn/

    展开全文
  • 单片机设计经验设计技巧集锦

    千次阅读 2016-03-24 20:21:01
    一、机器人常用的单片机使用经验 一 学习单片机的捷径是什么? 所谓捷径就是少走弯路。我刚开始学单片机时走了不少弯路,很多朋友和我都有相似的经历,刚开始接触单片机,面对琳琅满目的图书教材,不知选择哪...

    一、机器人常用的单片机使用经验

    一 学习单片机的捷径是什么?

    所谓捷径就是少走弯路。我刚开始学单片机时走了不少弯路,很多朋友和我都有相似的经历,刚开始接触单片机,面对琳琅满目的图书教材,不知选择哪本;想实践时不知到哪买单片机;不知如何编程下载程序„„

    A 对于初学者仔细看本文就是学习单片机的捷径之一。

    B 到图书馆或者书店在数十本单片机书中选一本你能看懂,而且觉得案例有趣的“实在、生动、活泼”的单片机书做为你的入门读物。

    C 建议先从51单片机学起。掌握51后再学AVR,然后学ARM、DSP等。

    D 在学习过程中实践非常必要。你需要一台电脑。如果是台式电脑,你可以花十几元购买25针并口下载线,如果是笔记本电脑,你只能购买几十元到几百元的USB ISP编程器。   E 用万用板自己焊一个单片机最小系统,或者购买开发板。没有必要使用昂贵的仿真器。   F 你需要上网下载单片机编程软件,比如51用Keil编程,AVR用CVAVR编程,在编程软件中编好程序,然后生成HEX文件,再上网下载并口烧程序软件或者USB ISP烧程序软件,用烧程序软件加载HEX文件,然后将编程线查到你的单片机电路板上,即可把程序烧到单片机中。

    G 拔下编程线,然后接通单片机板电源,你可以看到单片机系统在运行。

    H 如果系统不能正常运行,首先检查电路是否接错,然后检查程序是否烧错,如果以上都没毛病,研究程序是否编错。有时系统不能正常运行并不意味着有什么地方错了,只是某些参数没设置好,你需要不断运行、修改程序、调试参数、再运行如此往复,直到你对系统运行满意为止。有时这是一个非常艰苦的重复劳动,调整数百次上千次,你无法回避,只能坚定信念,勇往直前。

    I 到淘宝网上买东西更方便、更便宜。

    二 在单片机诞生前人们用什么控制机器人

    1 模拟计算机

    在数字计算机诞生前,人们用电子管、电容器和电感线圈、电阻搭建模拟计算机,能够完成许多简单的计算和控制任务。所谓模拟计算机就是其计算采用的信号不是1、0数字信号,而是电压连续变换的模拟信号,类似于自动控制原理中的各种控制器采用的运算。别小看了模拟计算机,上世纪80年代中东战争时,阿拉伯国家使用的苏制全自动自行防空炮内采用模拟计算机实现计算飞机轨迹并控制火炮射击目标。


    2 齿轮和凸轮组成的控制器

    在模拟计算机诞生前,也就是蒸汽机时代,有些机械天才硬是用数百个齿轮和凸轮搭建出机械计算机,人们通过转动印有数字的各种齿轮,另一些齿轮就将运算结果显示出来。机械计算机在人类史上上曾经是高科技产品,第二次世界大战时,德国著名的密码机就是一种机电混合式计算机,它当时是最保密的通信工具。



    3 发条和秒表和继电器组成的控制器

    在电气时代开始时,人们用钟表内机械的旋转分时控制一些继电器的通断,从而控制一些机床和生产线的运行。这种装置类似于早期洗衣机内的定时器。


    三 入门首选 AT89S51系列单片机

    1 简介

    1980,英特尔公司开发出一种简易的8031CPU,在当时该CPU性能不比8086差很多,但价格较便宜,因此被很多低端应用选中。由于市场看好,ATMEL公司购买了8031的内核,把Flash存储器和加强型IO口融入进去开发出了AT89系列单片机。所有兼容8031指令和内核相似的单片机统称为51单片机,它是目前应用最广泛的8位单片机之一。因51单片机结构简单,指令易学,应用广泛,因此是初学单片机首选机型。如果有人想不学51,直接学AVR,那么此人一定会遇到很多难题,困惑和郁闷将伴随着学习过程。如果学了51再学AVR和其他单片机,人们会发现“所谓单片机都不过如此”。

    2 性能

    根据任务具体需要选择最合适的单片机,使单片机资源充分利用,使系统性价比达到最高,同时兼顾未来扩展需要,不一味追求高性能单片机,这就是选单片机的原则。

    AT89S51有4K的Flash程序存储器,128字节的RAM,32条IO口,中断系统具有6个中断源、5个终端矢量、2个中断优先级的中断结构;串行口是一个全双工的串行通信口;AT89S51的电源电压为4.0-5.5V,AT89LS51的电源电压为2.7-4.0V;振荡器频率

    0-33MHz

    (AT89S51),0-16MHz(AT89LS51); 有ISP 在线编程功能,这个功能的优势在于改写单片机存储器内的程序不需要把芯片从工作环境中剥离。是一个强大易用的功能。   AT89S52程序储存器容量为8KB,还有AT89S55,ROM容量更大。

    有很多公司生产了很多扩展型51系列单片机,有的带有AD转换器,有的带有比较器,有的带有PWM,读者可以根据自身需要选择合适的51单片机,但要注意他们的管脚定义和编程方式。

    3 使用方法

    AT89S51 适于做单片机学习板、电子时钟、超声波测距仪等不需要采集模拟量和控制大功率外部元件的电路。S51与过去的C51的区别在于S51支持ISP在线编程,即C51需要几百元的编程器编程,而S51仅需一条25针并口线和非常简单的转换电路即可接在台式电脑打印机接口烧程序,下载烧程序小软件即实现可对S51单片机编程。对51单片机编程一般选用Keil软件,可采用C语言或者汇编语言,编完程后选择输出HEX文件,然后用烧程序小软件读取HEX文件,再烧写到单片机中。

    4 实践经验

    A 刚开始看书时,按照书上的电路图连线然后通电调试,但总不成功,将自己的电路和书上的电路仔细对照发现不了问题。原因在于很多书上的电路图都是“简化图”,即省略了一些电路,而这些被省略的电路却关乎系统的运行。比如,当单片机书讲到AD转换电路,给出的电路图多省略了晶振和复位电路,按照AD转换电路图搭出来的系统自然不能运行。

    B 51单片机P0口输出信号时需要上拉电阻,我经常忘记加电阻,导致电路不好使。

    C 51单片机31引脚需要接正极,以选择采用内部程序存储器。如果忘记给这个引脚以正确的电压,你的单片机可能不能执行程序。


    4 应用举例



    如此高性能的单片机价格居然和51单片机差不多,比如ATmega8价格为8元左右,ATmega16在13元左右,这是AVR有极高性价比的真实写照。


    2 性能

    AVR家族人丁兴旺,包括ATinyAVR(微小型)、低功耗类、ATmegaAVR高中低档5类单片机。它们都基于同一核心技术,但在内部集成的电路多少上有不同。不论你要做电子手表还是视频处理,都有一款合适的AVR单片机能满足你的需要。

    本文只列出ATmega16中档单片机的性能:

    16KB的FLASH程序存储器;512B的EEPROM;1KB的SRAM;32个快速寄存器;32个大功率IO口;20个中断;2个外部中断口;有SPI、SUART、I2C总线接口;2个8位定时器;1个16位定时器;3个PWM通道;有实时时钟RTC;8个10位AD通道;电压比较器;看门狗;内置时钟振荡器;JTAG接口;ISP在线编程;电压范围为2.7V-5.5V;外部时钟晶振0-16MHz;有PID和多种贴片封装。

    AVR的IO口能输出20mA和吸收40mA的电流,不仅可直接驱动LED,甚至可直接驱动微型直流减速电机。而且AVR的IO口可编程设置成输入、输出、高阻态状态,是真正的3态IO口。和51相比使用AVR开发产品你会发现前所未有的方便和自由。

    AVR单片机可上操作系统,比如UCOS2、Linux等,自主编程实现操作系统功能也很容易。

    根据任务具体需要选择最合适的单片机,使单片机资源充分利用,使系统性价比达到最高,同时兼顾未来扩展需要,不要一味选用高性能单片机,这就是选单片机的原则。

    用ARM+操作系统做超声波测距仪——杀鸡用了牛刀。用AVR中档单片机做机器视觉——有些吃不消。如果把它们调换一下,一切就恰到好处了。

    3 使用方法

    学AVR单片机的好书是《AVR单片机嵌入式系统原理与应用实践》,封面见下图。


    AVR一般采用CVAVR编程软件编程,也可用GUN GCC AVR、AVR Studio软件编程。可采用汇编或C语言编程。烧程序前先输出HEX文件,然后用SLISP(双龙ISP)软件加载,再通过ISP编程线或者25针并口连接线烧入AVR单片机,支持在线编程。

    由于AVR单片机最小系统很简单,就是电源+晶振(可不用)+LED+ISP接口(通电就运行,断电就停止,不用复位电路),因此任何初学者都可以用面包板搭出AVR最小系统,并且编程实践。

    4 实践经验

    使用AVR单片机时注意要正确设置熔丝位,SLISP软件就可设置,熔丝位可决定单片机是采用外部晶振还是采用内部时钟振荡器,如果熔丝位设置为采用外部晶振,而电路中没有接入晶振,则AVR程序不能运行。很多初学者忽视了这一点,他们的AVR系统不能运行却找不到原因。再有就是AVR的IO口在使用前需先编程设置其状态,否则你将发现程序在运行,但IO口没信号。


    4 应用举例



    五 高级机器人控制器 ARM

    1 简介

    ARM是一个公司名,他们基于同一内核设计了很多高性能处理器,这些处理器都叫ARM。该技术被很多公司购买后生产出了集成很多功能电路的ARM芯片,使得ARM成为高性能单片机。ARM一般为32位单片机,适于处理大量复杂数据,很多ARM装上了UCOS2、Windows CE、Linux操作系统,能够同时运行多个程序。ARM广泛应用于手机、MP3、GPS导航仪、吸尘机器人等产品上。


    六 音频视频处理首选 DSP

    1 简介

    DSP数字信号处理(Digital Signal Processing,简称DSP),它是一种独特的微处理器,是以数字信号来处理大量信息的器件。其工作原理是接收模拟信号,转换为0或1

    的数

    字信号,再对数字信号进行修改、删除、强化,并在其他系统芯片中把数字数据解译回模拟数据或实际环境格式。它不仅具有可编程性,而且其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器,是数字化电子世界中日益重要的电脑芯片。它的强大数据处理能力和高运行速度,是最值得称道的两大特色。

    在高速小车巡线、语音识别等领域DSP被广泛应用。但如果仅用DSP检测几个碰撞开关、控制几个电机显得大材小用。

    七 新兴控制器 FPGA

    1简介

    FPGA(Field-Programmable Gate Array),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,系统设计师可以根据需要通过可编辑的连接把FPGA内部的逻辑块连接起来,就好像一个电路试验板被放在了一个芯片里。简单说,如果使用者想开发一个用简单数字逻辑电路就能控制的小车,又嫌搭电路麻烦,他就可用软件给一个FPGA编程让它实现数字电路功能去控制小车。即FPGA可被用来模拟各种电路。有的FPGA甚至能模拟51单片机的运行。因FPGA通过编程即可修改它模拟的电路结构,因此在系统实验、调试中很方便,很多爱好者尝试用FPGA做机器人控制器。

    八 更多可供选择的单片机

    我们选择学一款单片机前首先要考虑自己面对的实际任务需要什么性能的单片机,然后在众多性能满足要求的单片机中作出选择。此时我们还要考虑不同单片机的“应用广泛程度”,比方说:当我们要做一个电子大赛智能小车,有AVR单片机和PIC单片机可满足任务需要,如何在两者中作出选择需要考虑哪种单片机学起来比较容易、学习资料容易获取、可供参考的程序和案例更加丰富、哪种单片机更容易获得编程软件和下载器等。笔者感觉要想做智能小车,AVR单片机的资料比较丰富。

    世界上有种类繁多的单片机,它们当中绝大多数都可用来控制机器人,但存在一个是否合适的问题。比如PLC是可编程控制器,当然可以用来控制爱好者手中的机器人,但PLC多用于工业控制领域,设备庞大价格昂贵,同时不易获得用PLC控制小型机器人的资料。爱好者选择学一种单片机前,首先得明确自己要用单片机干什么,然后再选最合适的单片机学习。学单片机重在学精一两种单片机,如果有人泛泛地学ARM、PLC、PIC、凌阳、DSP、FPGA等所有有名的单片机,那么他将无法拥有真正的深度开发能力。所谓深度开发,以AVR单片机为例,初学者可以用它实现小灯交替闪烁,中级技术人员可以用它控制参加比赛的机器人,而真正的高级开发人员可以用AVR实现机器视觉、无人机自动驾驶、坦克火控系统„„   AVR单片机过时了吗?

    有初学者甚至中级开发人员认为因ARM性能一般比AVR性能高,因此ARM将代替AVR,AVR将退出历史舞台,或者MSP430将代替51系列单片机,或者FPGA将取代所有单片机等。这种看法不对,因为不同单片机都有各自的特点和优点,没有哪种单片机是完美的,在不同场合用最合适的单片机,发挥它们各自的特长,而不存在ARM一统天下,取代所有其他型号单片机的可能性。试想,原本十几元的电子表因为采用ARM控制买到几百元,谁能受得了?

    因此不要觉得AVR已经过时,学完51就直接学ARM,或者觉得学51没用,直接学ARM,否则你将碰壁。

    MSP430系列单片机:比较适于机器人开发,是美国德州仪器推向市场的一种16位、具有精简指令集的、超低功耗的混合信号处理器。具有Flash存储器,中断源较多,并且可以任意嵌套,使用时灵活方便。MSP430系列单片机的电源电压采用的是 1.8~3.6V 电压。因而可使其在1MHz的时钟条件下运行时,芯片的电流会在200~400uA左右,时钟关断模式的最低功耗只有0.1uA。MSP430系列单片机的各成员都集成了较丰富的片内外设。它们分别是看门狗、模拟比较器、定时器、串口0、1、硬件乘法器、液晶驱动器、10位/12位ADC、16位Sigma-Delta AD、直接寻址模块(DMA)、IO端口、基本定时器(Basic Timer)等的一些外围模块的不同组合。MSP430 系列单片机引进了JTAG技术,不仅使开发工具变得简便,而且价格也相对低廉,并且还可以实现在线编程。

    PIC单片机:可用于机器人开发,是8位单片机,产品种类丰富,采用精简指令集,有不错的开发环境,引脚驱动能力强,可直接连接继电器控制强电。自带看门狗,有睡眠和低功耗模式。很多性能不如AVR和MSP430系列单片机,但因其有特殊优点,也被广泛应用。   凌阳单片机:比较适于机器人开发,以16位计算机为核心,集成不同规模的RAM、ROM和其他丰富的功能电路,使用者可以根据自己需要选择集成了特定功能电路的凌阳单片机。凌阳单片机指令系统提供出具有较高运算速度的16位,16位的乘法运算指令和内积运算指令,为其应用添加了DSP功能,因此凌阳适合进行语音识别。在我国凌阳单片机在学校比较常见,应用实例较多,可作为机器人爱好者选用的单片机。

    九 实例:用AVR单片机创造机器生命

    1 什么是机器生命

    机器生命就是一个能自主生存的机器,一个自动为生存下去而奋斗的机器。对于机器生命来说,生存的含义就是不断电,继续运行。机器生命具有完全自主决策、自主行动、活动于未知世界、不需人类参与就能持续运行并且自我维护等特征。影片《终结者》中的天网就是超级机器生命。《霹雳5号》描述了一个机器人从无生命到有生命的过程。

    N.维纳(Norbert Wiener,1894~1964)写《控制论》时创造出第一个机器生命Wiener龟,这个机器龟仅有2个电子管组成的模拟计算机,但它却能实现真正的乌龟觅食、睡觉、探索、逃避等行为,其表现如同一个有生命的生物一样。机器龟上面有太阳能电池,当自身电池快用完前,机器龟乐于寻找一个光线充足的地方充电,充满电后可能找个地方睡懒觉,或者探索未知世界,它有避免碰撞和避免到倾斜地方的趋向,我们无法预知它的行踪,因为它不是按照程序运行的,就如同我们自己一样。后来维纳在他的机器龟上又加了一个电子管,三个电子管连接成简单的神经网络,通过对机器龟训练,维纳通过摇铃可控制机器龟的行为。正如有生物学家训练狗使得狗听到摇铃声后就流口水。

    这个机器生命的技术含量相当于20世纪70年代国际机器人领域的先进水平。当时已经有很多非常精密和复杂的工业机器人被应用,但这种简单的机器人怎么能称作先进呢?因为技术的复杂和技术的先进不是一个概念,复杂+精密不一定等于先进。先进的东西不一定复杂和精密。


    A 寻光

    我们可以用光电二极管来检测光线强弱。当然也可以用光敏电阻。将光敏电阻和一个固定电阻串联接在电源正负极之间,光敏电阻靠近正极一侧。从光敏电阻和固定电阻连接点引出导线接到ATmega16的AD转换输入口。当强光照在光敏电阻时,光敏电阻阻值变小,因此其压降变小,而固定电阻分压增多,引出的AD检测电位升高,被单片机转化为数字量后判断光线增强。机器生命有5个光电传感器,其中4个面向机器人前后左右四个方向,另一个指向太阳能板所面对的方向。通过编程可以让机器人自主移动到光线最强的地方。

    B 充电

    本设计采用4.8V镍氢充电电池为系统供电。太阳能电池板正负极通过一个三极管与电池正负极相连。有一个电压比较器比较电池电压与太阳能板的压差,如果压差高于某值,比较器控制三极管导通,太阳能电池板对充电电池充电。充电电池电压上升,当高于某值时控制三极管关断,结束充电。为使太阳能板能对电池组充电,要求太阳能板在阳光直射下输出电压高于8V。



    C 语音识别

    用AVR单片机的高速AD检测功能能实现简单的语音识别。声音信号被驻极体电容话筒接收后送至LM386音频功放芯片放大和过滤后送至单片机AD转换口,单片机对音频信号幅值采样转化为一组数字,然后对这组进行取方差运算,得出一个特征值,该特征值可以用于简单的语音识别。比如你发一个“e”,方差应该比较小,如果你发“p”爆破音,方差应该较大。当然,如果你用更复杂的数据处理,会得到更好的识别效果。本设计使用了2路声音信号,目的是让单片机判断出声源的大体方位。

    D 超声波测距

    用AVR的1个IO口输出40KHz信号送至超声波发射电路,当超声波遇到障碍物返回后,被超声波接收头接收,信号经CX20106A解码芯片处理,得到一个低电平脉冲,用该脉冲引发AVR单片机中断,AVR通过检查发波和收到回波之间的时间差即可算出障碍物距离。   E 电机驱动

    本设计采用2片LG9110电机驱动芯片驱动两台直流减速电机。LG9110输出最大电流为800mA,仅需要2条控制线与单片机IO口直接相连即可控制一台电机正反转或者停止。LG9110仅有8个引脚,使用非常方便。

    F 让机器生命更聪明

    我的这个机器生命设计方案能实现最酷的效果是:白天,阳光明媚,机器生命跑到阳光底下晒太阳,太阳光会随着时间变化,机器生命能自动跑到最合适的位置享受日光浴。到了晚上,机器生命会找个安静的地方闭目养神,等待明天太阳升起。你可以训练机器生命,让它知道自己的名字叫什么。比如你叫着它的名字,同时站在它面前用强光照射它的太阳能电池板,如此反复训练,会使机器生命听到自己名字后向声源方向跑去,

    在距离声源一定远处

    停止,因为以往这样做它都能享受强光照射并充电。这就如同真正的宠物狗,你叫它名字它就跑到你跟前希望能获得食物。这一切都是完全能够实现的,关键就在于编程序实现它。   G 想象无极限,你的机器宠物将无所不能

    以上方案中,ATmega16的功能被发挥到极致,以至于没有空闲的IO口,系统不能再扩展了。如果你用ATmega128单片机做,那么它拥有53个IO口,30多个中断,128Kb的程序存储器,4Kb的RAM,使得你能编写更复杂的程序、储存更多的动态数据、连接更多的外设,你的机器生命将变得非常有生命力。比如加入三轴加速度传感器、地磁传感器、GPS定位、雨水传感器甚至摄像头、无线通信模块等,重新设计一个坚固和强劲的底盘,你的机器生命就可以在室外自由探索了。

    以上芯片外设来源说明:在淘宝上购买很容易

    底盘:340元的高级履带式1:16电动坦克模型

    加速度传感器、地磁传感器:美国AD公司的40元ADXL330加速度传感器

    GPS定位:几十元的车载外置GPS天线

    最后,我想说,机器人是非常好玩的,只要你有想象力,有毅力,努力研究实践就能创造奇迹。

    二、工程师分享的单片机学习步骤

    有了单片机学习板之后你就要多练习,把学习板和电脑连好,打开调试软件坐在电脑前,先学会怎么用调试软件,然后从最简单的流水灯实验做起,等你能让那八个流水灯按照你的意愿随意流动时你已经入门了,你会发现单片机是多么迷人的东西啊,太好玩了,这不是在学习知识,而是在玩,当你编写的程序按你的意愿实现时你比做什么事都开心,你会上瘾的,真的。做电子类的人真的会上瘾。然后让数码管亮起来,这两项会了后,你已经不能自拔了,你已经开始考虑你这辈子要走哪一行了。就是要这样练习,在写程序的时候你肯定会遇到很多问题,而这时你再去翻书找,或是问别人,当得到解答后你会记住一辈子的,知识必须用于现实生活中,解决实际问题,这样才能发挥它的作用。另外我再说说用汇编和C语言编程的问题。很多同学大一二就开设了C语言的课 ,我也上过,我知道那时天天就是几乘几,几加几啊,求个阶乘啊。学完了有什么用?让你用C语言编单片机的程序你是不是就傻了?书上的东西我们必须要会运用。单片机编程用C语言或汇编语言都可以,但是我建议用C语言比较好,如果原来有C语言的基础那学起来会更好,如果没有,也可以边学单片机边学C语言,C 语言也挺简单,只是一门工具而已,我劝你最好学会,将来肯定用得着,要不你以后也得学,你一点汇编都不会根本无所谓,但你一点C语言都不会那你将来会吃苦头。汇编写程序代码效率高,但相对难度较大,而且很罗嗦,尤其是遇到算法方面的问题时,根本是麻烦的不得了,现在单片机的主频在不断的提高,我们完全不需要那么高效率的代码,因为有高频率的时钟,单片机的ROM也在不断的提高,足够装得下你用C语言写的任何代码,C语言的资料又多又好找,将来可移植性非常好,只需要变一个IO口写个温度传感器的程序在哪里都能用,所以我劝大家用C语言。总结上面,只要你有信心,做事能坚持到底,有不成功不放弃的强烈意志,那学个单片机来说就是件非常容 易的事。

    步骤:

    1.找本书大概了解一下单片机结构,大概了解就行。不用都看懂的。

    2.找学习板练习编写程序,学单片机就是练编程序,遇到不会的再问人或查书。

    3.自己网上找些小电路类的资料练习设计外围电路。焊好后自己调试,熟悉过程。

    4.自己完全设计具有个人风格的电路,产品,。。。你已经是高手了

    ^_^。 。。。。

    学习单片机的八大步骤

    学习使用单片机就是理解单片机硬件结构,以及内部资源的应用,在汇编或C语言中学会各种功能的初始化设置,以及实现各种功能的程序编制。

    第一步:数字I/O的使用

    使用按钮输入信号,发光二极管显示输出电平,就可以学习引脚的数字I/O功能,在按下某个按钮后,某发光二极管发亮,这就是数字电路中组合逻辑的功能,虽然很简单,但是可以学习一般的单片机编程思想,例如,必须设置很多寄存器对引脚进行初始化处理,才能使引脚具备有数字输入和输出输出功能。每使用单片机的一个功能,就要对控制该功能的寄存器进行设置,这就是单片机编程的特点,千万不要怕麻烦,所有的单片机都是这样。   第二步:定时器的使用

    学会定时器的使用,就可以用单片机实现时序电路,时序电路的功能是强大的,在工业、家用电气设备的控制中有很多应用,例如,可以用单片机实现一个具有一个按钮的楼道灯开关,该开关在按钮按下一次后,灯亮3分钟后自动灭,当按钮连续按下两次后,灯常亮不灭,当按钮按下时间超过2s,则灯灭。数字集成电路可以实现时序电路,可编程逻辑器件(PLD)可以实现时序电路,可编程控制器(PLC)也可以实现时序电路,但是只有单片机实现起来最简单,成本最低。定时器的使用是非常重要的,逻辑加时间控制是单片机使用的基础。   第三步:中断

    单片机的特点是一段程序反复执行,程序中的每个指令的执行都需要一定的执行时间,如果程序没有执行到某指令,则该指令的动作就不会发生,这样就会耽误很多快速发生的事情,例如,按钮按下时的下降沿。要使单片机在程序正常运行过程中,对快速动作做出反应,就必须使用单片机的中断功能,该功能就是在快速动作发生后,单片机中断正常运行的程序,处理快速发生的动作,处理完成后,在返回执行正常的程序。中断功能使用中的困难是需要精确地知道什么时候不允许中断发生(屏蔽中断)、什么时候允许中断发生(开中断),需要设置哪些寄存器才能使某种中断起作用,中断开始时,程序应该干什么,中断完成后,程序应该干什么等等 。

    中断学会后,就可以编制更复杂结构的程序,这样的程序可以干着一件事,监视着一件事,一旦监视的事情发生,就中断正在干的事情,处理监视的事情,当然也可以监视多个事情,形象的比喻,中断功能使单片机具有吃着碗里的,看着锅里的功能。 以上三步学会,就相当于降龙十八掌武功,会了三掌了,可以勉强护身。

    第四步:与PC机进行RS232通信

    单片机都有USART接口,特别是MSP430系列中很多型号,都具有两个USART接口。USART接口不能直接与PC机的RS232接口连接,它们之间的逻辑电平不同,需要使用一个MAX3232芯片进行电平转换。

    USART接口的使用是非常重要的,通过该接口,可以使单片机与PC机之间交换信息,虽然RS232通信并不先进,但是对于接口的学习是非常重要的。正确使用USART接口,需要学习通信协议,PC机的RS232接口编程等等知识。试想,单片机实验板上的数据显示在PC机监视器上,而PC机的键盘信号可以在单片机实验板上得到显示,将是多么有意思的事情啊!

    第五步:学会A/D转换

    MAP430单片机带有多通道12位A/D转换器,通过这些A/D转换器可以使单片机操作模拟量,显示和检测电压、电流等信号。学习时注意模拟地与数字地、参考电压、采样时间,转换速率,转换误差等概念。使用A/D转换功能的简单的例子是设计一个电压表。   第六步:学会PCI、I2C接口和液晶显示器接口

    这些接口的使用可以使单片机更容易连接外部设备,在扩展单片机功能方面非常重要。   第七步:学会比较、捕捉、PWM功能

    这些功能可以使单片机能够控制电机,检测转速信号,实现电机调速器等控制起功能。   如果以上七步都学会,就可以设计一般的应用系统,相当于学会十招降龙十八掌,可以出手攻击了。

    第八步:学习USB接口、TCP/IP接口、各种工业总线的硬件与软件设计

    学习USB接口、TCP/IP接口、各种工业总线的硬件与软件设计是非常重要的,因为这是当前产品开发的发展方向。

    三、电子电路设计之C51单片机常见问题

    笔者在工作中实际使用过AT89C2051、AT89C51、AT89C52等51单片机,后来应用台湾新茂、华邦等厂家的51单片机。实践中遇到许多问题,都是书本上没有的。我印象中,书本上的知识只有一页插图了,就是cpu的时序图。最初直接用汇编写程序,然后是C51嵌套汇编。编译器曾用伟福系列编译器,后来使用keil等,感觉这些编译器大同小异。需要熟练的C语言基础,加上单片机应用的特殊性。

    本文就51单片机应用中一些常见问题作个总结,这都是我实际碰到过的,因为文章篇幅所限,这些问题远远不足以表达单片机的常见问题。希望对初学者有所帮助,文中不完善的地方务请指点。谢谢!

    1:C51编译器如何区分位地址和字节地址

    c:上面的语句,执行顺序是把0x11给R7,然后跳转子程序,子程序将它加1后送回。   d:函数跳转到汇编程序时,本区的R0-R7,A,B,PSW,DPTR等寄存器可以供子程序使用,不必考虑调用后是否要恢复这些常规资源。上例中,A的值被函数使用了,编程者不必恢复调用前的值。

    3:51单片机的P0口特殊之处

    许多新手都碰到这个问题,其实很简单,这涉及到芯片的io脚是怎么做出来的。这对硬件工程师来说十分重要。TTL的io脚模型:


    P1,P2,P3口都可以理解成左图,注意vcc下面有个电阻,因此可以理解成:引脚输出1的能力弱。地那边没有电阻,可以理解成引脚吸入电流能力强。而P0口,可以理解成右图。这就是集电极开路输出,也叫OC输出。可以看出,当CTR=1时,三极管导通,引脚被接地;当ctr=0时,三极管截止,引脚浮空,也叫三态。这个端口这么做的目的是考虑P0口肩负读写数据和地址复用,这个关系要仔细看懂cpu时序图。因此,P0口要加合适的上拉电阻,绝不要加下拉电阻。上拉电阻的选择要看外部负载情况。

    4:P1-3口如何输入输出

    从上节的左图可以看出。做输出时,ctr=1则输出强信号0,ctr=0则输出弱信号1。当io脚做输入时,应使ctr=0,这样三极管截止。外部信号如果是1,则上拉电阻加强了这个1,单片机就会读到1。当外部信号为0时,注意,必须将上拉电阻的上拉作用全部抵消,才能在引脚上得到0。

    因此,对于程序来说,把io脚置1就处于接收状态,当然也是输出1状态。程序置io口为1,读取的信号是不是1就依靠外部电路了,如果外部电路没有“吃掉”上拉电阻的电流,则读取得到1,反之,虽然程序置io脚为1,但是读取得到的就是0。

    因此,如果用io脚的高电平驱动外部电路时,要小心外部电路把这个1“吃掉”从而输出不了1。而作为输入时,为0电平的外设必须足够有能力将io脚拉低。所以,用io

    直接点亮led的时候,最好用反逻辑,就是输出0,让led亮。这样能保证驱动能力。就是io脚接led的负端,led的正端过电阻接vcc。

    因此,io脚输出1时,外部电路将它强行接地是没有关系的,而io脚输出0的时候,外部电路强行接电源就会把io脚损坏。所以,程序加电之后,一般把所有io口都写成1:MOV P0,0FFH。

    P3口引脚复用,必须引脚都处于输出1状态。例如,把RXD脚输出0,则它什么数据都读不进来了,笔者早期曾调试一整天才发现串口收不到数据是没有把RXD置1的原因,把时间都浪费在外围了,当时很是汗颜。

    5:有关晶振

    单片机的晶振在内部可以简化成一个反向器。当晶振输入脚XI刚过坎压、被认为是1的一瞬间,输出脚XO就输出0,这个0会带动晶振使XI电压下降,当降低到坎压被认为是0的一瞬间,输出脚XO就输出1。这样周而复始。

    因此,用示波器观察正常工作的晶振输入脚XI时,得到的是一个不高不低的近似水平线。而XO则是幅值很大的正弦波。测量晶振输入脚XI时,示波器表笔要打在X10档上,否则,表笔就能把晶振弄停。

    因此布线时,晶振输入脚XI要尽量靠近晶振,而XO脚可稍远。同时XO具有一定的驱动能力,某些芯片可以用它驱动其它时序电路(不推荐这么做,因为系统可靠性下降)。   写到这里,才发觉51单片机的问题太多了,这篇文字简直就是沧海一粟。以后再补充吧,另行成文。

    四、单片机经验之谈

    一、前言

    很多单片机初学者在与我交流的时候总是的一句话是我现在是单片机初学者,我怎样才能更快的学好单片机,学习单片机有市场不,对于这个问题现在就我自己如何学单片机,如何入门,如何熟练,整个过程谈谈自己的想法。先说说单片机,现在用的比较多的的MCS-51的单片机(但是考虑到成本及引脚资源在实际开发中用的单片机型号不一),它的学习资料非常多,且学习成本非常低,如果你听说企业里用的是什么什么芯片,但是不知道,你问过没有,那个仿真器需要多少钱,51单片机对于智能控制入门来说是非常好的,一线下载程序,ARM太神秘,PLC太高贵,想来想去还是51。那怎样才能更快更好的学好单片机呢?单片机这门课是一项非常重视动手实践的科目,而且单片机也是一门集计算机编程与电子技术为一身的学科,如果你是单片机高手,那么说明你也是计算机编程和电子技术高手。

    二、学习单片机时候一定要看书

    不能总是看书,但是学习它首先必须得看书,那这不很矛盾。因为从书中你需要大概了解单片机各个功能寄存器(比如引脚控制寄存器、定时、中断、串口相关寄存器),控制单片机的核心是用程序去控制单片机的各个功能寄存器,给寄存器赋值二进制数据0或者1,这样一来对于引脚寄存器单片机可以根据二进制数据0和1输出高低电平控制外部设备,对

    于内部资源寄存器,单片机也通过二进制数据0和1使用单片机内部的功能。比如单片机引脚寄存器P1,语句P1=0xfe;(MOV P1,#0FEH)。说明现在控制单片机P1口的第一个引脚输出低电平,其他引脚输出高电平。比如中断中断允许寄存器IE,语句IE=0x81;(MOV IE,#81H) 则说明控制中断打开总开关和外部中断0的子开关。至于看书,只需大概了解单片机各管脚、各个特殊功能寄存器都是干什么的?能实现什么样的功能?这个非常重要,这也许是看书的最主要的目的。第一次,第二次你可能看不明白,但这不要紧,因为还缺少实际的感观认识。通过接下来的实验就可以非常感观的认识,在这个过程一定要花时间,学习程序不能硬背,但是学习寄存器一定要下功夫,理解他的功能所在。推荐一本书,就这一本就足够了,书名是《例说8051》有汇编语言和C语言版本的,非常强悍的一本书,但是我用一个五一放假的时间看完了这本书,看完后,觉得自己已经是单片机高手了。书中图文并茂,内容安排紧张有序,并非市面上很多说教的技术文档式的书,什么学完概念,学指令,学完指令学接口,学完接口才知道,原来学习单片机是学天书。根据书本的安排循序渐进的看完前两章,然后一定是实践,一定是实践啊,这是非常关键的一步,在战场上上纸上谈兵的列子很多,在学习单片机也一样,很多相关专业的研究生甚至博士生直到毕业都不清楚单片机的IO口的分布,不知道分布谈何说开发呢?更有一些所谓的单片机高手只停留在编程,以为了买了一块高级学习板,练习完了里面所有的程序,感觉自己排第二没人敢拍第一,觉得下一步不知道如何学习单片机了。殊不知,他们中的很多人到最后单片机LED的电阻加多大都不清楚更不用说单片机的引脚分布,你说,如果这样去开发那不是“草菅人命”啊。不是纸上谈兵是什么啊。

    三、学习单片机准备什么所以啊?

    学习单片机看书不够,实践也要从实际出发,现在的技术太模块了,什么都可以模块,模块的到最后,技术人员都成了只会用了,祖先的留下的知识,基础的知识该知道还是一定要知道的啊。 毕竟学习单片机的最终目的是开发,是通过创造智能控制的实物,体现自己的价值。关于实践有两种方法可以选择一种方法:购买一块51单片机的实验板,不要求功能太的,对于初学者来功能非常多的那种板子,上面有很多东西你这辈子都用不着,更有实验板为了增加功能,降低成本,实验板上到处用的是贴片元件,双面布线,越复杂就越有水平,好像他们在设计的时候就想着,学习单片机只要根据我的提示下载程序就可以了,更有甚者将下载器和集成了实验板上。很多初学者学完单片机还认为,原来单片机不是一块芯片,是老教材上经常提到的使用已经不到的单板机。我觉得初学单片机有这几个模块就够了,剩下的得自己去开发。流水灯、数码管、键盘、蜂鸣器、串口通讯、AD等这就差不多了。如果上面我提到的这些,你能熟练应用,那可以说对于单片机方面的硬件你已经入门了,剩下的就是自己练习设计电路,不断的积累经验。设计的电路的时候必须要学习下PCB板设计软件,毕竟现在做开发要产品批量化还得电脑辅助设计啊,手工的效率太低了。但是在学习的过程中建议自己动手焊接。在焊接前一定要了解电路连接,网上随便搜索可以找到很多电路原理图,但是都不一定都能用,所以建议备一块面包板,有了它你在焊接电路前就可以先测试下了。如果在面包板上测试成功,后来的焊接你就志在必得了,如果失败,大不了重新再找一个。只要过了第一关,后面的路就好走,万事起步难。方法二:你身边如果有单片机入门者,动手能力比较强,请他帮忙,搭个简单的单片机最下电路,哪怕是控制一个LED工作的电路。对于他们来说,做个单片机的最小系统板是轻而易举,而对于初学者可就难多,这中间的一层窗户纸破了就什么都简单了。因为只有对硬件了解了,才能熟练运用。只有知道程序是和下载到单片机内部的,才会清楚为什么要写单片机程序,这个动力来自于哪里,来至于心里有底。单片机编程就是与单片机对话,如果不知道对方谁,有没有再听,你还会有说话的激情吗。当然了如果没有这样的人,还是那句话,在网上多找几个最小电路电路原理

    图,在面包板上焊接就可以了。当然了这个也不会的,那建议你一定要买一块实验板,以后单片机的学习实验及项目测试验都用的上。

    四、如何迈入单片机开发世界

    有了单片机实验板你就要多练习,最好是自己有台电脑,少下载几部电影,少网络游戏,把实验板和电脑连好,安装上必备的软件,下载参考程序,并修改参考程序,从最简单的交通灯实验做起,等你发现你能控制交通灯,并了解交通的软硬设计的时候你已经入门了,你会发现单片机是多么迷人的东西啊,这不是在学习知识,而是在提升自我的价值。用途那么广的交通的设计都不在话下了,你还会觉得你没有学到东西吗。还会觉得自己什么都不会吗?计算机编程、电子技术的专业知识都用上了啊。

    当你编写的程序按你的意愿实现时,你比做什么事都开心,那种学习的收获感和成就感还有充实感是非常难得的。然后让数码管亮起来显示你所需要的数字。这两部分会了以后,你已经不能自拔了,你已经开始考虑你这辈子要走哪一行了。就这样学习,在写程序的时候你肯定会遇到很多问题,而这时你再去翻书找,这其中你会找你之前学过的编程的书,还有数电模电的书,你会发现原来之前学的知识还是有用的。遇到不懂再去找以前学过的书本查阅这才是 “温故而知新,可以为师矣”的大道理啊。

    知识必须用于现实生活中,解决实际问题,用单片机设计个简易的家电定时器、红外遥控器什么,这样才能发挥它的作用,好好想想,上了这么多年大学,探索了那么久,犹豫徘徊,天天上课,在课堂上学到了什么?是不是为了期末60分的考试而忙碌,侥幸靠了90分,很高兴啊,在别人面前吹自己专业知识如何如何学习的好,殊不知,大学考试不像高中考试啊,那了奖学金又怎样。但是下学期开学回来一想,所学的知识已经忘记的一干二净。学到什么了?为什么要推荐学习单片机,因为单片机是工科生学的,集合计算机编程电子技术及多门控制语言为一体的学科,与其说学习是在学习单片机,不如说是在学习一个大学科。

    五、学习单片机是汇编编程还是C语言编程 关于用汇编和C语言编程的问题。这个问题困恼很多人,可能主要是学校教学和部分教材的教育引导引起的吧,大一开了C语言编程,没等学生知道到底C语言有什么实际的用途,马上其他的语言一起来过来了。即使是开始了专门的单片机课程,但是课程的内容与技术文档很相识,指令很多,但是完整的不多,所以学完了也不知道,到底为什么要学习编程。很多同学大一就开设了C语言的课,我也上过,但是那时候就是天天几乘几,几加几啊,求个阶乘啊,用C语言去解决小学数学问题,每周两次上机,对着书本不停的敲打,下课了也不知道自己到底掌握了什么,掌握了这个有什么用途。学完了有什么用?如果在面试的时候,老板问,你学过编程吗,你脑子里马上是什么“C语言,VC什么VB。很多,什么C语言是基础是面向工程的,什么VC是高级面向对象的”,但是老板又问,你能将你所学习的C语言应用到实际中不,比如设计一个定时报警器的C语言。这下傻了,学校里没有学过啊。

    单片机编程用C语言或汇编语言都可以,但是我建议用C语言比较好,模块化管理编程方便,移植性强,适合编写大程序。如果原来有C语言的基础那学起来会更好,如果没有,也可以边学单片机边学C语言。虽然很多人是从汇编语言开始接触单片机的,但是写小程序汇编语言还是简单的,如果要实现一些算法,那汇编语言就不简单了。虽说C语言编译以后代码量明显比汇编长,而且执行效率也没有汇编语言高,但是在以前单片机开发中芯片工艺的限制,及单片机主频的限制,很多单片机内部存储器小的可伶,主频也小得可伶。但是现在不一样了,芯片内部的存储器根不不在乎这点差别。主频也越来越高。

    那汇编语言是不是不学了呢?不是的,一定要学习,有两方面首先入门单片机的时候要用汇编语言,它的语法简单。第二如果你要做单片机的程序的高级设计师,那汇编语言是非掌握不可的,很多像高级单片机ARM都是汇编语言作为引导代码的,还有就是很多新出品的单片机起先也是先有汇编语言编译器之后才有C语言编译器。所以,我觉得对于单片机学习汇编语言入门,C语言精通,汇编语言再精通。最后,对于单片机的学习,入门为先,入门了以后就要去关注市场,关注企业,企业需要什么样的人才,我想有了基础以后在面试之前了解下企业所需要的单片机类型,很快就上手了,毕竟学习是相同的。

    转载自:http://www.doczj.com/doc/e1dff2f5c8d376eeaeaa31f7.html
    展开全文
  • 常用单片机实验板使用手册

    千次阅读 2014-12-26 14:52:02
    单片机实验板使用手册 目录 目录....................................................................................................................2 1.准备工作.................................

     

     

     

     

     

    单片机实验板使用手册

     

     

     

     

     

     

     

     

     

     

     

     

    目录

     

    目录....................................................................................................................2

    1.准备工作....................................................................................................3

    2学习方法介绍...........................................................................................3

    3.实验例程详细解答................................................................................3

    3.1闪烁灯.............................................................................................4

    3.2流水灯..................................................................................................6

    3.3单键识别..........................................................................................8

    3.4 59秒计数器.................................................................................10

    3.5矩阵键盘检测............................................................................13

    3.6利用定时器和蜂鸣器唱歌.............................................................19

    3.7 模数转换ADC0804的应用…………………………..………20

    3.8 数模转换DAC0832的应用……………………………………….23

    3.9 DS18B20温度测量显示实验...........................................................24

    3.10 1602字符液晶显示...................................................................................29

    3.11 EEPROM AT24C02实验.........................................................................32

    3.12 串口通讯实验............................................................................................36

    联系方式...................................................................................................................38

    4 WAVE使用说明...............................................................................................39

    5 KEIL的使用.....................................................................................................43

    6 STC-ISP软件的使用.......................................................................................50

     

     

     

     

     

     

     

     

     

     

     

    1.准备工作

    拿到实验板后首先需要做的几件事

    当用户拿到实验板后的第一件事是先看实验板供电是否正常、下载程序功能是否正常、各芯片功能是否都能成功实现,检测方法如下所示:

     

    1. 将包装中的USB线两端分别插接实验板左侧的USB供电接口和电脑USB口,打开实验板上电源,这时会看到实验板的电源指示灯会亮,紧接着会看到实验板上数码管或是流水灯都有随机的亮灭现象出现,也有可能只看到电源指示灯亮而无其它现象,这是因为我们在发货前要对产品进行综合测试,单片机内部装有测试时的程序,用户不必奇怪,以上状态说明实验板供电系统正常。

    2. 安装STC单片机程序下载软件,下载光盘中写好的例程测试各功能是否正常,安装过程及下载方法在视频中都有详细介绍,关于STC单片机程序下载软件的STC-ISP安装,请查看本手册后面的说明或同光盘中的文档。

    3. 安装单片机编程软件KEIL或是WAVE,这两个软件在产品配套光盘里的软件目录下都有,用户可自由选择使用任何一种软件,这两种软件都支持单片机的C语言或是汇编语言编译,我们推荐用户使用KEIL,在OK100E配套的单片机视频教学光盘中全部使用的是KEIL软件讲解,在视频教学的第1讲中有详细的KEIL软件建立工程及编译源代码的介绍,请大家自行查看。我们在手册中也做了详细的介绍,请大家查看本手册后面的说明。

    2学习方法介绍

    接下来最重要的工作便是跟着配套教学光盘一讲一讲的跟着老师做,把老师每讲的内容都及时的消化,遇到不懂的问题要及时查书,一个个搞明白,不要积累任何小问题,大部分用户都是从零开始学起,讲座中的内容也是从最简单的开始,一步步深入,只要大家愿意学、有信心、有毅力、相信大家跟着教学讲座走10天,之后必将会有非常大的收获。如果用户没有购买配套视频光盘,我们会赠送前三讲的内容,这三讲中非常详细的介绍了KEIL软件的使用方法,讲了流水灯设计流程,实验板上其余的功能就需要靠用户自来对它进行编程并实现它们了,这样学起来只是时间会稍长些,感觉会累点,但只要大家肯努力,终究也一定会学会的。

    3.实验例程详细解答

    注意:在我要讲具体实验之前这里有必要先介绍一下本实验板上用到的一些元件的操作方法,对于一个电子制作者或是电子爱好者来说学会怎么样搜索自己需要元件的资料是非常重要的,现在市场上各种各样的芯片非常的多,能实现同一个功能的芯片也有很多种,世界各大芯片制造公司都有生产。所以我们不可能把芯片的功能、名称及详细使用方法都记全,也没有这个必要,但是必须要知道在你需要实现某个功能的时候怎么样才能找到合适的芯片,下面先给大家推荐两个搜索网站:

    www.baidu.com www.google.com

    以上两个网站是中国最大的搜索网站和世界最大的搜索网站,上面几乎可以搜到你需要的任何信息,大家一定要充分利用身边可利用的资源,问别人是最没有办法的办法,当自己在经过多重努力后仍然没有得到最佳答案,这时再去问别人。

    另外需要提醒大家一点,大部分芯片的资料全是英文,大家学了这么多年英文,现在正是你用它的时候了,对于电子爱好者来说,看芯片的英文介绍就应该达到看汉语一样的水平,建议大家以后装软件全装英文版的,看电影全看国外原声的,最好连自己电脑的操作系统也装英文版的,从点点滴滴中增长知识。

    再给大家介绍两个查芯片资料的网站:

    www.21ic.com 这里的芯片资料比较全,如果没有找到你要的资料,那可参考www.alldatasheet.com ,这里有全世界所有的芯片资料,并且每天都在更新。

    锁存器(74HC573):顾名思义,就是把输入端的数据锁存(或送)到输出端,请看下图中的U3元件,第11角(锁存端)为高电平的时候,右边D0-D7的输入与左边Q0-Q7的输出是直通的,就是说,输入端是什么电平,输出端就是什么电平,可以把它当作不存在。当第11角为低电平的时候,左右两端就被断开了,无论输入端怎么变化,输出端都不会变化,当第11角由低电平变为高电平的一瞬间,输入端的数据立刻被传送到输出端,并且在11角保持为高电平期间,输出端数据始终的输入端数据相同,如果此时我们再次把第11角设置为低电平,那么以后当输入端无论再怎么变化,输出端都不会变化而是保持刚才第11角在下降沿(由高电平到低电平跳变)之间时输入端的值,这样就达到了锁存数据的目的,这也就是所谓的总线设计思路,一个8位的数据线加一个锁存器后就可以扩接多个元件,当选通哪个元件的片选信号,就送数据给那个元件。先说这个元件,以后用到别的元件我们再解释。下面开始讲解例程。

     

    3.1闪烁灯

    [实验要求]

    点亮与单片机P1.0口相连的发光二极管,延时约0.2S,然后熄灭,再延时约0.2S,再点亮,如此循环下去。

    [实验目的]

    初步了解单片机IO口输出高低电平的方法,延时函数的时间估算。

    关于延时函数的时间估算问题在视频第二讲有详细演示介绍。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    #include<reg51.h>

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

    上面这行是一个"文件包含"处理。所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来这里的程序虽然只写了一行,但C编译器在处理的时候却要处理几十或几百行,这里包含reg51.h的目的在于本程序要使用P1这个符号,而P1是在reg51.h这个头文件中定义的。大家可以在编译器目录下面用记事本打开这个文件看看。

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

    sbit P1_0=P1^0; //定义IO口这步的目的是让编//译器知//P1_0代表的就是单片机的P1.0

    void delay02s(void) //延时0.2秒子程序

    {

    unsigned char i,j,k; //定义3个无符号字符型变量。

    for(i=20;i>0;i--) //三个FOR循环用来延时,这里为

    for(j=20;j>0;j--) //什么是0.2S大家可以用WAVEKEIL

    for(k=248;k>0;k--); //设置断点仿真,就可知道大概

    } //0.2S了。

    void main(void) //每一个C语言程序有且只有一个主函数,

    {

    while(1) //循环条件永远为真,以下程序一直执行下去。

    {

    P1_0=0; // I/OP1.0输出低电平,小灯被点亮。

    delay02s(); //延时经过0.2秒。

    P1_0=1; // I/OP1.0输出高电平,小灯熄灭。

    delay02s(); //延时经过0.2秒。

    }

    }

     

    3.2流水灯

    [实验要求]

    单片机P1口相连的8个发光二极管中的一个循环移位点亮,同时蜂鸣器发出滴滴的响声。

    蜂鸣器用一PNP三极管驱动,集电极(C极)通过蜂鸣器线圈接5V电源,基极(B极)是控制端,发射极(E极)接地,当三极管CBPN结正偏时,PN结导通,即B极为低电平时,三极管导通,蜂鸣器发声,视频中有介绍,若大家有疑问可参考模电书。

    [实验目的]

    掌握循环移位的工作原理和操作方法,学会使用C51封装好的函数库C51LIB,延时函数的时间估算。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    #include <reg51.h>

    #include <intrins.h> //后面要用到它里面的_crol_(kl)函数

    这个函数的意思是把一个字符变量k循环左移l位,关于它的说明请查看安装KEIL目录下的\Keil\C51\HLP文件夹里面的c51lib,这个文件里面有各种用C语言封装好的函数库,我们在以后使用其中某些函数时可以直接使用而自己不必再写。

    unsigned char a,b,k,j; //定义四个字符变量

    sbit beep=P2^3; // 定义蜂鸣器的接口

    void delay10ms() //延时子程序,大约延时10ms

    {

    for(a=100;a>0;a--)

    for(b=225;b>0;b--);

    }

    void main()

    {

    k=0xfe; //先给k一个初值11111110等待移位

    while(1)

    {

    delay10ms();

    beep=0; //打开蜂鸣器

    delay10ms(); //让它响10ms

    beep=1; //关闭蜂鸣器

    j=_crol_(k,1); //k循环左移一位

    k=j; //把移完的值再送给k

    P1=j; //同时把值送到P1口点亮发光二极管

    } //再次循环

    }

     

    3.3单键识别

    [实验要求]

    每按一次独立键盘的S2键,与P1口相连的八个发光二极管中点亮的一个往下移动一位。

    注意:关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms左右,在按下瞬间到稳定的时间为5-10ms,在松开的瞬间到稳定的时间也为5-10ms,如果我们再首次检测到键被按下后延时10ms左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理。

    [实验目的]

    独立按键的识别方法、键盘消抖等。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    #include <reg52.h>

    sbit BY1=P3^4; //定义按键的输入端S2

    unsigned char count; //按键计数,每按一下,count1

    unsigned char temp;

    unsigned char a,b;

    void delay10ms(void) //延时程序

    {

    unsigned char i,j;

    for(i=20;i>0;i--)

    for(j=248;j>0;j--);

    }

    key() //按键判断程序

    {

    if(BY1==0) //判断是否按下键盘,当单片机上电时所有IO口为高电平,S2键一端接地另一端接P3.4,所以当键被按下时P3.4口直接接地,此时检测P3.4肯定为低电平。

    {

    delay10ms(); //延时,软件去抖动干扰

    if(BY1==0) //再次检测确认按键按下

    {

    count++; //按键计数加1

    if(count==8) //8次重新计数

    {

    count=0; //count清零

    }

    }

    while(BY1==0);//等待按键释放,如果键未释放则一直在此等待。

    }

    }

    move() //广告灯向下移动移动函数

    {

    a=temp<<count; // 这三句为一个循环移位,相当于前面提到的

    b=temp>>(8-count);// _crol_()函数,这里是自己写的过程,大家可对比

    P1=a|b; //下。

    }

     

    main()

    {

    count=0; //初始化参数设置

    temp=0xfe;

    P1=0xff;

    P1=temp;

    while(1) //永远循环,扫描判断按键是否按下

    {

    key(); //调用按键识别函数

    move(); //调用广告灯移动函数

    }

    }

    3.4 59秒计数器

    [实验要求]

    使用软件延时的方法实现0-59秒自动计数器,用数码管的前两位显示出来。

    [实验目的]

    练习进位操作,数码管动态显示。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    //59秒自动计数器

    #include<reg51.h>

    #define uchar unsigned char

    uchar j,k,i,a,A1,A2,second;

    sbit dula=P2^6; //锁存器控制端定义

    sbit wela=P2^7;

    uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

    0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字编码

    void delay(uchar i) //延时函数

    {

    for(j=i;j>0;j--)

    for(k=125;k>0;k--);

    }

    void display(uchar sh_c,uchar g_c) //显示函数

    {

    dula=0;

    P0=table[sh_c]; //显示十位

    dula=1;

    dula=0;

     

    wela=0;

    P0=0xfe;

    wela=1;

    wela=0;

    delay(5); //5ms

     

    P0=table[g_c]; //显示个位

    dula=1;

    dula=0;

     

    P0=0xfd;

    wela=1;

    wela=0;

    delay(5); //5ms

    }

     

    void main() //主函数

    {

    while(1)

    {

    second++; //秒加一

    if(second==60) //判断是否到60

    second=0; //如果到了则清零

    A1=second/10; //没到则分离出十位和个位

    A2=second%10;

    for(a=50;a>0;a--) //显示部分。至于时间大概是多少

    { //请用户用软件仿真看时间约等于1

    display(A1,A2);};//便可,如果需要精确定时请用定时器

    }

    }

     

    3.5矩阵键盘检测

    [实验要求]

    依次按下4*4矩阵键盘上从第1到第20个键,同时在六位数码管上依次显示0123456789ABCDEF

    说明:本实验板上数码管为共阴极。

    静态数码管显示原理(视频中有详细介绍):这里就共阴极数码管显示原理进行讲解,一位数码管内一共有8个发光二极管,对共阴极来说其8个发光二极管的阴极在数码管内部全部接在一起,也就是"共阴"说法的来源,阳极是独立的,设计电路时一般把阴极接地,当我们从外部给任一个阳极加一个高电平时这个发光二极管就亮了,如果想要出一个8字,并且把右下角的小数点也点亮的话,那可以给8个阳极全总送高电平,想出几就给相对应的发光二极管送高电平,因此我们在显示数字的时候首先做的就是给0-9十个数字编好码,在要它亮什么数字的时候直接把这个编码送到它的阳极就行了。另外说一下,一般的数码管每一段亮至少需要10个毫安的电流,而单片机的IO口送不出如此大的电流,所以我们需要加数码管的驱动电路,可以用上拉电阻的方法,也可以使用专门的驱动芯片,本实验板使用的74HC573,其输出电流较大,足够点亮数码管。

    本实验板上的六位数码管中每个的相同段号(段指a,b,c,d,e,f,g,h)全部是接在一起的,其中每一个位(阴极)是独立的,所以在做静态显示的时候所有的数码管只能显示相同的数字,当然可以控制显示几位,如果让它们显示不同的数字那就得给每一个数码管加一套驱动电路了。但这样做是没有必要的,后面我们会讲到关于数码管动态显示原理。

    下面给出本实验板共阴极数码管数字编码

     

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    矩阵键盘的四行分别与P3.0-P3.3连接,四列分别与P3.4-P3.7连接。

    [实验目的]

    学会矩阵键盘的检测,掌握数码管静态显示原理。

    [硬件电路]

    键盘电路见3.3

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    //4*4键盘检测程序,按下键后相应的代码显示在数码管上

    #include<reg51.h>

    sbit beep=P2^3; //蜂鸣器接口

    sbit dula=P2^6; //控制数码管段选的锁存器锁存端

    sbit wela=P2^7; //控制数码管位选的锁存器锁存端

    unsigned char i=100;

    unsigned char j,k,temp,key;

    void delay(unsigned char i) //可自定义延时长短的延时函数

    { //i=10时大约为10毫秒

    for(j=i;j>0;j--)

    for(k=125;k>0;k--);

    }

    unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,

    0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; // 0-F编码

    display(unsigned char num) // 显示子函数

    {

    P0=table[num]; //将第num个显示编码送P0

    dula=1; //一个下降沿将数据锁存

    dula=0;

    P0=0xc0; //位选通全部的数码管

    wela=1; //一个下降沿将数据锁存

    wela=0;

    }

    void main()

    {

    dula=0; //先关闭两个锁存器

    wela=0;

    while(1) //进入检测总循环

    {

    P3=0xfe; //P3.0送低电平,其余为高电平

    temp=P3; //P3口数据读回来

    temp=temp&0xf0; //P3口与11110000相与

    if(temp!=0xf0) //如果有键按下刚一定不相等,于是进入//下一步检测

    {

    delay(10); //延时去抖动

    if(temp!=0xf0) //再次判断是否有键按下

    {

    temp=P3; //判断为有,再次读P3口数据

    switch(temp) //因为我们刚才是将第一行置的低

    { //在这里再判断是第几列

    case 0xee: //如果temp=0xee则为第一行和第一列

    key=0; //的交叉点,由此我们知道是矩阵键盘

    break; //上的第一个键被按下,我们给key=0

    case 0xde: //以后依此类推

    key=1;

    break;

    case 0xbe:

    key=2;

    break;

    case 0x7e:

    key=3;

    break;

    }

    while(temp!=0xf0) //这段程序是检测按键是否被释放

    {

    temp=P3; //如果没有释放就一直等待并且

    temp=temp&0xf0;

    beep=0; //蜂鸣器一直响

    }

    beep=1; //释放后关闭蜂鸣器

    display(key); //显示按下相应键值的数据

    P1=0xfe; //将第一个发光二极管点亮(我写

    } //程序的时候测试用的)

    }

    P3=0xfd;

    temp=P3;

    temp=temp&0xf0;

    if(temp!=0xf0)

    {

    delay(10);

    if(temp!=0xf0)

    {

    temp=P3;

    switch(temp)

    {

    case 0xed:

    key=4;

    break;

    case 0xdd:

    key=5;

    break;

    case 0xbd:

    key=6;

    break;

    case 0x7d:

    key=7;

    break;

    }

    while(temp!=0xf0)

    {

    temp=P3;

    temp=temp&0xf0;

    beep=0;

    }

    beep=1;

    display(key);

    P1=0xfc;

    }

    }

    P3=0xfb;

    temp=P3;

    temp=temp&0xf0;

    if(temp!=0xf0)

    {

    delay(10);

    if(temp!=0xf0)

    {

    temp=P3;

    switch(temp)

    {

    case 0xeb:

    key=8;

    break;

    case 0xdb:

    key=9;

    break;

    case 0xbb:

    key=10;

    break;

    case 0x7b:

    key=11;

    break;

    }

    while(temp!=0xf0)

    {

    temp=P3;

    temp=temp&0xf0;

    beep=0;

    }

    beep=1;

    display(key);

    P1=0xf8;

    }

    }

    P3=0xf7;

    temp=P3;

    temp=temp&0xf0;

    if(temp!=0xf0)

    {

    delay(10);

    if(temp!=0xf0)

    {

    temp=P3;

    switch(temp)

    {

    case 0xe7:

    key=12;

    break;

    case 0xd7:

    key=13;

    break;

    case 0xb7:

    key=14;

    break;

    case 0x77:

    key=15;

    break;

    }

    while(temp!=0xf0)

    {

    temp=P3;

    temp=temp&0xf0;

    beep=0;

    }

    beep=1;

    display(key);

    P1=0xf0;

    }

    }

    }

    }

     

    3.6利用定时器和蜂鸣器唱歌

    [实验要求]

    用单片机的P2.3口输出不同占空比的方波来控制与它相连的蜂鸣器,当方波的占空比不同时蜂鸣器发出的音调就不同,由此根据歌曲的音调编程实现让蜂鸣器唱歌。

    占空比:一个周期中,高电平的长度比上总周期的长度的值再乘上100%。标准方波的占空比为50%.

    [实验目的]

    学会利用单片机的定时器,掌握蜂鸣器的发声操作。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    #include "reg51.h"

    unsigned char Count;

    sbit _Speak =P2^3 ; //蜂鸣器控制脚

    unsigned char code SONG[] ={ //祝你平安,以下为编码

    0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,

    0x10,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,

    0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,

    //路边的野华不要采 , 以下为这首歌的编码

    0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0xFF,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,

    0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F,

    0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00,

    };

    void Time0_Init() //定时器0初始化函数

    {

    TMOD = 0x01; //工作模式选择

    IE = 0x82; //中断设置

    TH0 = 0xD8; //装初值

    TL0 = 0xEF; //12MZ晶振,10ms

    }

     

    void Time0_Int() interrupt 1 //定时器0中断子函数

    {

    TH0 = 0xD8;

    TL0 = 0xEF;

    Count++; //长度加1

    }

    /*-------------------------------------------------

    1MS延时子程序

    -------------------------------------------------*/

    void Delay_xMs(unsigned int x)

    {

    unsigned int i,j;

    for( i =0;i < x;i++ )

    {

    for( j =0;j<3;j++ );

    }

    }

    /*-------------------------------------------------

    功能:歌曲播放子程序i为播放哪一段曲目

    -------------------------------------------------*/

    void Play_Song(unsigned char i)

    {

    unsigned char Temp1,Temp2;

    unsigned int Addr;

    Count = 0; //中断计数器清0

    Addr = i * 217;

    while(1)

    {

    Temp1 = SONG[Addr++];

    if ( Temp1 == 0xFF ) //休止符

    {

    TR0 = 0;

    Delay_xMs(100);

    }

    else if ( Temp1 == 0x00 ) //歌曲结束符

    {

    return;

    }

    else

    {

    Temp2 = SONG[Addr++];

    TR0 = 1;

    while(1)

    {

    _Speak = ~_Speak;

    Delay_xMs(Temp1);

    if ( Temp2 == Count )

    {

    Count = 0;

    break;

    }

    }

    }

    }

    }

    /*-------------------------------------------------

    功能:主程序

    -------------------------------------------------*/

    void main()

    {

    Time0_Init(); //定时器0中断初始化

    while(1)

    {

    Play_Song(0); //播放

    }

    }

     

    3.7模数转换ADC0804的应用

    [实验要求]

    从ADC0804 的模拟量通道输入0-5V 之间的模拟电压,通过ADC0804 转换成数字量送给单片机,经单片机处理后在数码管上以十进制形成显示出来。

    [实验目的]

    学习如果用单片机控制ADC0804芯片进行数模转换,掌握数码管动态扫描显示的原理。

    动态扫描:就六位数码管显示123456举例说明如下:先让第一个数码管显示1,其余的全部不亮,1大约亮几毫秒,然后熄灭,紧接着立即让第二个数码管显示2,其余的全部不亮,2同样亮几毫秒,依次这样亮到第六个数码管,然后再回来显示1,如此这样以很快的速度不断循环下去,由于人眼的视觉暂留时间大约为20毫秒左右,所以是感觉不出有不亮的数码管存在的,看见的是六个数码管同时在显示,数值是123456,如果我们把这个过程一点点放慢,看见的是从第一个数码管显1,然后移到第二个再显2,。。。也就是说在任一时刻只有一位数码管是亮的。这就是数码管动态扫描显示的原理。

    ADC0804: ADC08048位全MOS中速A/D 转换器、它是逐次逼近式A/D 转换器,片内有三态数据输出锁存器,可以和单片机直接接口。单通道输入,转换时间大约为100usADC0804 转换时序是:当CS0 许可进行A/D 转换。WR由低到高时,A/D开始转换。CSWR同时有效时启动A/D转换,转换结束产生INTR 信号(低电平有效),可供查询或者中断信号。在CSRD 的控制下可以读取数据结果。本实验没有使用INTR信号。

    [硬件电路]

     

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    //拧动AD旁边的电位器,会在数码管的前三位显示0-255之间的数值。这就是把模拟信号转换成数字信号,即模数转换。说明:由于不同AD的自身特性不同,所以时序如果掌握不好的话,很有可能在数码管上不会动态显示变化数值,但按下实验板上复位键后可更新内容。

    #include<reg51.h>

    #include <intrins.h>

    #define uint unsigned int //宏定义,详情请看C语言书。

    #define uchar unsigned char

    sbit adrd=P3^7; //AD读引角

    sbit adwr=P3^6; //AD写引角

    sbit diola=P2^5;

    sbit dula=P2^6; //数码管段选锁存

    sbit wela=P2^7; //数码管位选锁存

    unsigned char j,k,adval;

    void delay(unsigned char i) //延时程序

    {

    for(j=i;j>0;j--)

    for(k=125;k>0;k--);

    }

    uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管编码

    void display(uchar bai_c,uchar sh_c,uchar g_c) //显示程序

    {

    dula=0;

    P0=table[bai_c]; //显示百位

    dula=1;

    dula=0;

    wela=0;

    P0=0x7e;

    wela=1;

    wela=0;

    delay(5);

    dula=0;

    P0=table[sh_c]; //显示十位

    dula=1;

    dula=0;

    wela=0;

    P0=0x7d;

    wela=1;

    wela=0;

    delay(5);

    P0=table[g_c]; //显示个位

    dula=1;

    dula=0;

    P0=0x7b;

    wela=1;

    wela=0;

    delay(5);

    }

    void main() 主程序

    {

    uchar a,A1,A2,A2t,A3;

    diola=0;

    while(1) //主循环程序不断的采样、显示

    {

    adwr=0; //AD写入(随便写个什么都行,主要是为了启动//AD转换)

    _nop_(); //一个延时字函数

    adwr=1;

    adrd=0;

    adval=P1; //AD数据读取

    adrd=1;

    delay(10);

    A1=adval/100; //分出百,十,和个位

    A2t=adval%100;

    A2=A2t/10;

    A3=A2t%10;

    for(a=10;a>0;a--) // 显示十次,然后去采集一次电压信号

    {

    display(A1,A2,A3);} //送去显示各位。

    };

    }

     

     

     

     

    3.8 数模转换DAC0832的应用

    [实验要求]

    通过用单片机控制DAC0832输出锯齿波,让实验板上发光二极管D12由暗到亮变化,循环下去。

    [实验目的]

    学会用单片机控制数模转换芯片DAC0832。

    DAC0832:DAC0832是8位全MOS中速D/A 转换器,采用R2RT 形电阻解码网络,

    换结果为一对差动电流输出,转换时间大约为1us。使用单电源+5V―+15V 供电。参考电压为-10V-+10V。在此我们直接选择+5V 作为参考电压。DAC0832 有三种工作方式:直通方式,单缓冲方式,双缓冲方式;在此我们选择直通的工作方式,将XFER、WR2、CS 管脚全部接数字地。管脚8 接参考电压,在此我们接的参考电压是+5V。我们在控制P0口输出数据有规律的变化将可以产生三角波,锯齿波,梯型波等波形了。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    //TX-1BDA测试程序,下载后可观察到D12发光二极管由暗变亮再熄//灭过程,

    #include<reg51.h>

    sbit wela=P2^7; //数码管位选

    sbit dula=P2^6; //段选

    sbit dawr=P3^6; //DA写数据

    sbit csda=P3^2; //DA片选

    unsigned char a,j,k;

    void delay(unsigned char i) //延时

    {

    for(j=i;j>0;j--)

    for(k=125;k>0;k--);

    }

    void main()

     

    {

    wela=0;

    dula=0;

    csda=0;

    a=0;

    dawr=0;

    while(1)

    {

    P0=a; //a不断的加一,然后送给DA

    delay(50); // 延时50ms 左右,再加一,再送DA

    a++;

    }

    }

    注意:随着给DA送的数字量的不断增加,其转换成模拟量的电流也不断的增大,所以我们观察发光二极管D12就会从暗变亮,熄灭。。。

     

    3.9 DS18B20温度测量显示实验

    [实验要求]

    用单片机控制实验板上的DS18B20数字温度传感器,读取当前环境温度,精度达0.1度,温度范围0-99度,并用数码管的前三位显示出来。同时实验板上的单片机还能把温度值通过串口发送到计算机,在计算机上安装该目录下的.exe文件后,打开应用程序可看到温度值。

    注意:DS18B20 数字温度传感器是DALLAS 公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。DS18B20 产品的特点(1)、只要求一个I/O 口即可实现通信。(2)、在DS18B20 中的每个器件上都有独一无二的序列号。(3)、实际应用中不需要外部任何元器件即可实现测温。(4)、测量温度范围在-55 到+125摄氏度之间。(5)、数字温度计的分辨率用户可以从9 位到12 位选择。(6)、内部有温度上、下限告警设置。

    DS18B20 详细引脚功能描述1、GND 地信号;2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下,也可以向器件提供电源;3、VDD可选择的VDD 引脚。当工作于寄生电源时,此引脚必须接地。DS18B20 的使用方法。由于DS18B20 采用的是1-Wire 总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S52 单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。

    [实验目的]

    学习单总线器件的读写方法,数值合成,数字类型变化等。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    //安装目录下的EXE文件,通过串口线连接计算机与实验板,打开

    //软件后可在软件界面上显示当前温度值。

    #include <reg52.h>

    #define uchar unsigned char

    #define uint unsigned int

    sbit DS=P2^2; //define interface 定义DS18B20接口

    uint temp; // variable of temperature

    uchar flag1; // sign of the result positive or negative

    sbit dula=P2^6;

    sbit wela=P2^7;

    unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//不带小数点编码。

    unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,

    0x87,0xff,0xef}; // 带小数点编码。

    void delay(uint count) //延时子函数

    {

    uint i;

    while(count)

    {

    i=200;

    while(i>0)

    i--;

    count--;

    }

    }

    ///功能:串口初始化,波特率9600,方式1///

    void Init_Com(void)

    {

    TMOD = 0x20;

    PCON = 0x00;

    SCON = 0x50;

    TH1 = 0xFd;

    TL1 = 0xFd;

    TR1 = 1;

    }

     

    void dsreset(void) //发送初始化及复位信号

    {

    uint i; //DS18B20初始化

    DS=0;

    i=103;

    while(i>0)i--;

    DS=1;

    i=4;

    while(i>0)i--;

    }

     

    bit tmpreadbit(void) //read a bit 读一位

    {

    uint i;

    bit dat;

    DS=0;i++; //i++ for delay 小延时一下

    DS=1;i++;i++;

    dat=DS;

    i=8;while(i>0)i--;

    return (dat);

    }

     

    uchar tmpread(void) //read a byte date 读一个字节

    {

    uchar i,j,dat;

    dat=0;

    for(i=1;i<=8;i++)

    {

    j=tmpreadbit();

    dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好//一个字节在DAT

    }

    return(dat); //将一个字节数据返回

    }

     

    void tmpwritebyte(uchar dat) //write a byte to ds18b20

    { //写一个字节到DS18B20

    uint i;

    uchar j;

    bit testb;

    for(j=1;j<=8;j++)

    {

    testb=dat&0x01;

    dat=dat>>1;

    if(testb) //write 1 1部分

    {

    DS=0;

    i++;i++;

    DS=1;

    i=8;while(i>0)i--;

    }

    else

    {

    DS=0; //write 0 0部分

    i=8;while(i>0)i--;

    DS=1;

    i++;i++;

    }

    }

    }

     

    void tmpchange(void) //DS18B20 begin change 发送温度转换命令

    {

    dsreset(); //初始化DS18B20

    delay(1); //延时

    tmpwritebyte(0xcc); // 跳过序列号命令

    tmpwritebyte(0x44); //发送温度转换命令

    }

    uint tmp() //get the temperature 获得温度

    {

    float tt;

    uchar a,b;

    dsreset();

    delay(1);

    tmpwritebyte(0xcc);

    tmpwritebyte(0xbe); //发送读取数据命令

    a=tmpread(); //连续读两个字节数据

    b=tmpread();

    temp=b;

    temp<<=8; //two byte compose a int variable

    temp=temp|a; //两字节合成一个整型变量。

    tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20

    //可以精确到0.0625度,所以读回数据的最低位代表的是

    //0.0625度。

    temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位

    //也转换为可显示数字,同时进行一个四舍五入操作。

    return temp; //返回温度值

    }

    void readrom() //read the serial 读取温度传感器的序列号

    { //本程序中没有用到此函数

    uchar sn1,sn2;

    dsreset();

    delay(1);

    tmpwritebyte(0x33);

    sn1=tmpread();

    sn2=tmpread();

    }

    void delay10ms() //delay

    {

    uchar a,b;

    for(a=10;a>0;a--)

    for(b=60;b>0;b--);

    }

    void display(uint temp) //显示程序

    {

    uchar A1,A2,A2t,A3,ser;

    ser=temp/10; //分离出三位要显示的数字

    SBUF=ser;

    A1=temp/100;

    A2t=temp%100;

    A2=A2t/10;

    A3=A2t%10;

    dula=0;

    P0=table[A1]; //显示百位

    dula=1;

    dula=0;

    wela=0;

    P0=0x7e;

    wela=1;

    wela=0;

    delay(1);

    dula=0;

    P0=table1[A2]; //显示十位 带小数点的

    dula=1;

    dula=0;

    wela=0;

    P0=0x7d;

    wela=1;

    wela=0;

    delay(1);

    P0=table[A3]; //显示个位

    dula=1;

    dula=0;

    P0=0x7b;

    wela=1;

    wela=0;

    delay(1);

    }

    void main() //主函数

    {

    uchar a;

    Init_Com(); //初始化串口

    do

    {

    tmpchange(); //温度转换

    for(a=10;a>0;a--)

    {

    display(tmp()); //显示十次

    }

    }

    while(1);

    }

     

    3.10 1602字符液晶显示

    [实验要求]

    1602液晶屏上指定的位置显示出自己想要的数字或字符,学会使用1602液晶做滚动字符显示。

    [实验目的]

    学习1602液晶的操作。

    注意:实验板附带的1602安装方法请看光盘里的液晶使用方法,插好液晶后如果显示字符不清楚,请调节1602液晶对比度调节电位器,顺时针拧动直到液晶上面一行能显示出黑色的方格为止。

    关于1602液晶的资料请查看光盘里元件资料下的资料。

    [硬件电路]

    常用单片机实验板使用手册 - 全能特工 - 掌中智能

    [源代码]

    #include<reg52.h>

    #define uchar unsigned char //宏定义

    #define uint unsigned int //宏定义

    sbit rs=P3^5; //液晶数据命令选择端

    sbit lcden=P3^4; //液晶写数据控制端

    sbit dula=P2^6;

    sbit wela=P2^7;

    uchar table1[]="OK100E V1.1 MCU \

     菊子曰:我在用着的博客编辑软件
    展开全文
  • 一. Proteus仿真平台简介 Proteus软件是英国Labcenter electronics公司出版的EDA工具软件(该...现已受到电子类特别是单片机爱好者、从事单片机教学的教师、致力于单片机开发应用等的科技工作者的青睐。以前的如EW...
  • STM32自学周记(一)

    2019-03-17 12:05:46
    第一天学习的时候在网上到处找资料,看stm32的介绍,看stm32的学习方法,制定计划。学习单片机一定要多动手,代码只看不动手敲一敲什么都记不住,所以当天晚上联系了同学一起买了块迷你开发板。 在开发板邮回来之前...
  • 舵机抖动的解决方法

    千次阅读 2019-09-30 15:52:29
    最近用arduino单片机,机械臂一直在不停的抖动。 首先,需要知道舵机的使用方法,简单来说,就是给一定时间的高电平,舵机能转动在一定的角度。其实,你只需给舵机一次能转动在一定角度的高低电平,之后只需保持上电...
  • 能电脑所不能的单片机,这就是Arduino。 我们每天使用的计算机是强大的,但它们根本不了解身边发生了什么事。比如说你的笔记本电脑也不能感到光或水。另外,Arduino对外专门设计成键控的。它有一个用于简化传感器...
  • 实验名称:Arduino智能小车组装和综合测试 实验小组成员:20135223何伟钦 20135234马启扬 20135229吕松鸿 实验日期:2015.10.27—2015.11.3 实验时长:24h-48h 一....第一步:将光盘资料全部复制到您的电脑保存好...
1
收藏数 8
精华内容 3
关键字:

单片机小灯闪烁教学手段