零基础学习单片机(一)--LED

最近公司要做智能小车的改装。笔者很是惭愧,浑浑噩噩在大学读了4年的电子专业,到头来单片机都没玩过2次。

计划花一段时间来玩单片机,从最简单的LED入手。

该系列的学习笔记 开发环境是:

开发板:HC800EM3  感觉是一块很不错的开发板,提供的外部接口不少,板子还提供了单片机与ARM的“转换接口”。

单片机型号:STC90C516RD+

ARM:STM32

开发工具:keil 3 (单片机版)

一、原理图

由于网上的教程很多,对于keil的使用以及板子的电路分析 就不具体介绍了。(很庆幸,板子的原理图多少还能看的懂,以后要恶补啊~)。

很容易理解,将1管脚置0,这灯D8会亮。

二、单片机延时程序的粗浅分析

为了让LED灯能够具有多种效果(例如闪烁),必然要用到延时程序。部分网友说,单片机的延时程序精度不高,建议用定时器。但是毕竟是入门,之后再研究定时器吧。

下面的程序是在12MHZ 晶振源,延时1ms的c程序。

 

[cpp] view plaincopy
 
  1. void delay_ms(void)   
  2. {  
  3.     unsigned char a,b,c;  
  4.   
  5.     for(c = 1;c > 0; c--)  
  6.         for(b = 142; b > 0; b--)  
  7.             for(a = 2; a>0; a--);  
  8. }  

1、机器周期

 

一个机器周期包含12个时钟周期。时钟周期的计算公式=(1/晶振频率)秒。

例如,晶振为12MHZ

该单片机的时钟周期=(1/12)微秒,由此可以得到机器周期为1us。

在这里机器周期可以理解为指令周期,就是单片机执行一条指令花费的时间。注:这里的指令并不是C语言的指令,而且机器指令,可以通过反汇编查看。

2、反汇编

我们要计算一个程序执行的时间,毕竟查看其对应的反汇编代码。这里附上上面程序的反汇编代码,keil 可以调出反汇编代码查看窗口。

 

[cpp] view plaincopy
 
  1.     54: void delay(void)      
  2.     55: {   
  3.     56:     unsigned char a,b,c;   
  4.     57:     for(c=1;c>0;c--)   
  5. C:0x0045    7F01     MOV      R7,#0x01  
  6.     58:         for(b=142;b>0;b--)   
  7. C:0x0047    7E8E     MOV      R6,#0x8E  
  8.     59:             for(a=2;a>0;a--);   
  9. C:0x0049    7D02     MOV      R5,#0x02  
  10. C:0x004B    DDFE     DJNZ     R5,C:004B  
  11. C:0x004D    DEFA     DJNZ     R6,C:0049  
  12. C:0x004F    DFF6     DJNZ     R7,C:0047  
  13.     60: }   
  14. C:0x0051    22       RET     

3、反汇编分析

 

下面列出了 delay_ms() 每条指令对应的机器周期。

这里附上8051 的指令周期表下载地址。

 

[cpp] view plaincopy
 
  1.             <span style="white-space:pre">  </span>指令       机器周期  
  2. C:0x0045    7F01     MOV      R7,#0x01      1  
  3.   
  4. C:0x0047    7E8E     MOV      R6,#0x8E      1  
  5.   
  6. C:0x0049    7D02     MOV      R5,#0x02      1  
  7. C:0x004B    DDFE     DJNZ     R5,C:004B     2  
  8. C:0x004D    DEFA     DJNZ     R6,C:0049     2  
  9. C:0x004F    DFF6     DJNZ     R7,C:0047     2  
  10.   
  11. C:0x0051    22       RET                2  

下面我们来计算 该程序 需要耗费多少时间。(不理解汇编指令的话,可以查看8051 指令周期表)

 

DJNZ     R5,C:004B,执行该循环所用的机器周期数为2*2=4。

从第三条指令到第五条指令的循环,执行该循环所用的机器周期数为(1+2*2+2)*142

从第二条指令到第六条指令的循环,执行该循环所用的机器周期数为(1+(1+2*2+2)*142+2)*1 

 

[plain] view plaincopy
 
  1. delay_time = 1+(1+(1+2*2+2)*142+2)*1+2 秒  

网上提供了一个很不错的延时程序计算软件。单片机小精灵软件
三、主程序

 

 

[cpp] view plaincopy
 
    1. <pre name="code" class="cpp">int main(void)  
    2. {  
    3.     P2 = 0xFE;  
    4.   
    5.     while(1)  
    6.     {  
    7.         delay_ms(100);      //延时100ms  
    8.         P2 ^= (1 << 0);       //取反  
    9.     }  
    10.   
    11.     return 0;  
    12. }</pre><p></p>  
    13. <pre></pre>  
    14. <span style="font-family:monospace"><span style="white-space:pre">程序的执行效果是 D1每隔100ms会闪烁一次</span></span>  
    15. <p></p>  
    16. <p style="text-align:left"><span style="font-family:monospace"><span style="white-space:pre"><br>  
    17. </span></span></p>  
    18. <p style="text-align:left"><span style="font-family:monospace"><span style="white-space:pre">有兴趣的朋友,可以自己修改主程序,让LED灯显示不同的效果。单片机挺有趣的~~今天就先写到这。</span></span></p>  
    19. <p style="text-align:left"><span style="font-family:monospace"><span style="white-space:pre"><span style="font-family:Arial; font-size:14px; line-height:26px">以上纯属个人学习笔记,如果哪里错了,希望提出。愿和大家一起共同学习,一起进步。我的邮箱地址是:xzy@yingzhi8.com</span><br>  
    20. </span></span></p>  
    21. <p style="text-align:left"><br>  
    22. </p>  
    23. <p><br>  
    24. </p>  
posted @ 2013-11-07 10:12  王井玉  阅读(387)  评论(0)    收藏  举报