博文

【014】外中断0响应实例 [51](2006-06-29 22:15:00)

摘要:实验参考: 《单片机轻松入门》(周坚)
实验板:   FB51A。(查看)
方法: 通过按键模拟外部中断的产生信号,用P0.0口接的LED作为中断响应。
实验现象:键按下时,P0.0口的LED亮灭交替。 电路如下: 在程序中,将中断0设置为下降沿触发:


       org   0000h
       ajmp  start
       org   0003h     ; 外部中断地址入口
       ljmp  int_0     ; 转到真正的处理程序
       org   30h
start: mov  sp, #5fh   ; 初始化堆栈
       mov  p0, #0ffh  ; 灯全灭
       mov  p3, #0ffh  ; P3口置高电平
       setb IT0        ; 下降沿触发
       setb EA         ; 开总中断
       setb EX0    ......

阅读全文(4430) | 评论:2

【013】查询方式按键 [51](2006-06-25 00:57:00)

摘要:实验参考: 笨笨工作室-实验六、查询方式按键。(查看)
实验板:   FB51A。(查看)

实验目的: <1> 掌握读取外部按键时候应该注意的事项,掌握查询方式响应按键的方法。
     <2> 掌握读取按键去抖动的方法。
      <3> 掌握判直接寻址位转移指令jb,jnb的用法。

实验现象: 最右面的数码管初始显示0,每次按下外部按键K1执行加一,计数到9时重新回0。 单片机响应外部按键的方式有两种,一种是查询方式,一种是中断方式。

查询方式:单片机不断的查询是否有按键按下,如果有按键按下的话,就执行相应的程序,否则继续查询。

中断方式:单片机处理自己的工作,如果有按键按下,向单片机发出中断请求。单片机停下现在正在处理的工作,转去执行中断程序,执行之后回来继续刚才的工作。

本实验是用查询方式完成, 只用到一个键K1,每次按下,使第一位数码管加1显示,计数到9里重新回0。显示部分电路及查表显示方法参考:【005】数码管显示数字 和 【006】多位数码管动态显示。原理图如下:
由原理图知:当按键k1按下的时候,对应P1.0输入低电平。因此,我们要查询k1是否按下,只要检测到p1.0是低电平即可。 在查询键是否按下时,要注意按键的去抖动问题,关于键的消抖,见 【012】按键消抖 。 按上述方法编写程序:

        org   0000h
start:  mov   p0, #48h       ; 段码-显示0
        mov   p2, #01h       ; 位码-选通第一位数码管 main:   mov   r7, #0ffh  ......

阅读全文(5525) | 评论:4

【012】按键消抖(2006-06-23 19:29:00)

摘要:参考: 《单片机原理及接口技术》(李朝青) 按键电路:常用的非编码键盘,每个键都是一个常开开关电路。


按键消抖:

通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号小型如下图。由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,如下图。抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。这是一个很重要的时间参数,在很多场合都要用到。
按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒。键抖动会引起一次按键被误读多次。为确保CPU对键的一次闭合仅作一次处理,必须去除键抖动。在键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。按键的抖动,可用硬件或软件两种方法。

<1> 硬件消抖:在键数较少时可用硬件方法消除键抖动。下图所示的RS触发器为常用的硬件去抖。

图中两个“与非”门构成一个RS触发器。当按键未按下时,输出为1;当键按下时,输出为0。此时即使用按键的机械性能,使按键因弹性抖动而产生瞬时断开(抖动跳开B),中要按键不返回原始状态A,双稳态电路的状态不改变,输出保持为0,不会产生抖动的波形。也就是说,即使B点的电压波形是抖动的,但经双稳态电路之后,其输出为正规的矩形波。这一点通过分析RS触发器的工作过程很容易得到验证。

<2> 软件消抖:如果按键较多,常用软件方法去抖,即检测出键闭合后执行一个延时程序,产生5ms~10ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。......

阅读全文(7224) | 评论:0

〖003〗三位加法器 [Verilog HDL模块的基本概念](2006-06-16 21:36:00)

摘要:参考:  《CPLD与单片机综合应用技术》(周立功)
实验板: 网助二号 例 5.2.3 module adder(count, sum, a, b, cin);
input [2:0] a, b;
input cin;
output count;
output [2:0] sum; assign {count, sum} = a + b + cin; endmodule

★ 此例描述了一个名为adder的三位加法器,可根据2个三比特数a、b及进位(cin)计算出和(sum)以及向上进位(count)。 "{  }"是拼接符,把count和sum拼接为一个4位的信号。

如何验证其正确性呢?开始将a的3个端口接了三个拨码开关,b的3个端口接了三个按钮开关(因为板上资源只有4个拨码开关和4个按钮开关),将相加得到的和sum的三个端口接三个LED显示结果, 进位位count同样接LED显示是否有进位,进位cin置为0。虽然这样的接法可以通过开关输入两个加数,也能看到结果,得出该模块的正确性,但总觉得这么手工输入的办法有些蠢,也没有发挥这块板MCU+CPLD综合的优势,于是产生如下方案。

用51单片机的P0口低3位产生被加数a, P2口低3位产生加数b, 得到的和还有进位仍然通过LED显示。开始想用二重循环产生所有的组合,被加数有8种情况,加数有8种情况,共可得到8×8=64种组合,但这样一来即不容易验证,二来也没必要,所以最终决定将b数值确定为01h, 而a的值由000b递增为111b这8个状态,分别与b相加后得到结果为001b,010b,011b,……,111b(第7个结果),再加01h后将产生进位,与后三位合并后为1000b,每个状态后延时1s以便观察,如此循环。上述过程中前一级的进位cin接地,即始终为0。

51单片机程序:

          org    0000h
start:    mov    p2, #01h
 &......

阅读全文(7608) | 评论:0

〖002〗二选一多路器[Verilog HDL模块的基本概念](2006-06-10 16:01:00)

摘要:参考:《单片机与CPLD综合应用技术》(周立功)
实验板: 网助二号 从几个简单Verilog HDL程序了解Verilog HDL模块的特性。

例5.2.1

module muxtwo(out, a, b, sl);
input  a, b, sl;
output out;
reg out;
    always @ (sl or a or b)
        if(!sl)
            out = a;
        else
            out = b;
endmodule

这几天看了许多不常见的符号,正好拿来组成以下框图表示上述模块:

         ____
a ───┤   ╲
        ㄧ    ├─── out
b ───┤   ╱
          ̄ ̄ㄧ
sl ─────┘

由于Verilog HDL是与C语言类似的, 所以不难理解此模块muxtwo的作用。这是一个二选一多路器(想起了数电里学过的数据选择器,又叫多路选择器Multiplexer, 简写为MUX), 即选择由out端输出a还是b由sl电平决定。sl为0时输出out与a相同; 否则与b相同。"always @ (sl or a or b)"这一句表示只要sl,或a,或b其中有一个变化,就执行下面......

阅读全文(8564) | 评论:0

[061] 一个字符串是否包含另一个字符串(2006-06-03 13:51:00)

摘要:《C程序设计》(夏宝岚) 习题6.13 检查一个字符串中是否包含另一个字符串

#include <stdio.h>
#include <string.h>
void main ()
{
    int i = 0;
    int j = 0;     int k = 0;    /* 偏移量&&累计已经匹配的长度 */     int flag = 0; /* 是否有匹配的字符串标志位, 1为真, 0为假 */     char m[50];
    char s[50];     printf("Mother string: ");
    gets(m);
    printf("Son    string: ");
    gets(s);
   
    for(i = 0; i < (int)strlen(m); i++)
    {
        for(j = 0; j < (int)strlen(s); j++)
        {
            if(s[j] == m[i + k]) /* 若匹配则记录已经匹配的个数k */
           &......

阅读全文(5764) | 评论:3

[060] 连接两个字符串(2006-06-02 22:26:00)

摘要:《C程序设计》(夏宝岚) 6.9 编写程序,实现将两个字符串连接起来(不允许用strcat函数)。

思路:定义三个数组a[], b[], c[],a.b用于存放将要连接的两个字符串,c用于保存a,b连接后的串。主要就是通过对字符串结束标志'\0'的判断分别将两串合并。第一次循环用控制变量i将串a复制到c中,第二次循环由于b串要从0开始,所以引入另一控制变量j由0开始,继续写入c时控制量i要延续第一次循环的值,最后将串c结束标志'\0'写入即可。如下:

#include <stdio.h>
void main ()
{
    int i = 0;
    int j = 0;     char a[50];
    char b[50];
    char c[50];     printf("First  string: ");
    gets(a);
    printf("Second string: ");
    gets(b);        while(a[i] != '\0') /* 将a串中内容copy到c中 */
    {
        c[i] = a[i];
        i++;
    }
    while(b[j] != '\0') /* 将b串中内容继续copy到c中 */
    {
        c[i] =......

阅读全文(5362) | 评论:4

[062] 杨辉三角的多种解法(2006-06-07 12:21:00)

摘要:《C程序设计》(夏宝岚) 习题6.5 编写程序,打印杨辉三角形(即二项式系数表)

在网上搜了一下关于杨辉三角的介绍,才知道原来这个数学三角并不是杨辉提出的,而是由一个叫做贾宪的人提出,大约在1050年他使用这个三角进行高次开方运算。南宋数学家杨辉在《详解九章算法》(1961年)记载并保存了“贾宪三角”,故称杨辉三角。杨辉在书中很确凿地载明:此图“出释锁算书,贾宪用此术”,所以后来都改称“贾宪三角”了。他所说的图叫做"开方作法本源图", 关于其详细介绍,见 贾宪三角一文。

杨辉三角的形式如下:

                              1
                           1     1
                        1     2     1
                     1     3 &nb......

阅读全文(7428) | 评论:10

[059] C语言中动态分配数组(一维)(2006-05-28 17:52:00)

摘要:    当初学Pascal的时候就想过这个问题:如何动态的定义及使用数组呢?记得一般用数组的时候都是先指定大小的。当时问老师,老师说是不可以的。后来又问了一位教C++的老师,他告诉我在C++里用new可以做到,一直不用C++,所以也不明白。今天在逛论坛时终于找到了C语言中的用法(看原贴):

    int *a;
    int N;
    scanf("%d", &N);
    a = (int *) malloc(N * sizeof(int));
    ....
    free(a);

    这样就动态分配了数组a[N]。数组的长度N可输入确定,也可用程序中的变量确定。但要注意程序结束后要用free()将其释放,否则内存会泄漏。 验证一下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i = 0;     int *a;
    int N;     printf("Input array length: ");
    scanf("%d", &N);
    printf("\n");     a = (int *) malloc(N * sizeof(int));
    
    for(i = 0; i < N; i++)
    {
        a[i......

阅读全文(12130) | 评论:10

【011】单片机开发中应掌握的原则(2006-05-28 16:59:00)

摘要:选自《单片机语言C51应用实战集锦(修订版)》(范风强)     在学习新的开发软件时,一定要先看帮助手册,买书要全面。多实践、焊电路板、编写以及调试,如只用软件模拟,与真正的实践还是有距离的。 一、总的原则     从技术的角度来看,单片机开发分为软件、硬件两部分。许多厂商在仿真机、编程器之后力推开发板,其目的就是要让开发者在开发过程中尽量少做硬件的工作,甚至不需要做硬件开发工作。这些板通常力求全面,功能很多,设计者把所有的功能都做上,用户要用什么功能就有相应的电路板。在进行开发时,总的原则是:     <1> 定位准确。应用目标锁定在什么层次、什么类型,需要哪些功能,不需要做的就不必花钱去做。     <2> 经过实践检验。所采用的技术必须是经过实践检验的成熟技术,这一点很重要。     <3> 简单性原则。如果所做的就是开关量控制,不涉及模拟量,就不必采用模拟量技术。如果能够用单片机实现的技术,就不要用外围电路去实现。尽量做到小型、简单、可靠、廉价。     <4> 使用单片机C语言编程。C语言是简洁、高效、而又最贴近硬件的高级编程语言。20世纪90年代初单片机C语言就已成熟为专业水平的高级语言,不应再有顾虑。当前厂商在推出新的单片机产品时纷纷配套C语言编译器。     <5> 如有可能,使用中、高档的单片机仿真工具。 二、软件原则     <1> 提高C语言编程代码的效率     用C语言进行单片机程序设计是单片机开发与应用的必然趋势。如果使用C编程时,要达到最高的效率,最好熟悉所使用的C编译器。先试验一下每条C语言编译后对应的汇编语言的语句行数,这样就可以很明确地知道效率。在今后编程的时候,使用编译效率最高的语句。
    各厂家的C编译器都会一定的差异,故编译效率也会有所不同,优秀的嵌入式系统C编译器代码长度和执行时间仅比以汇编语言写的同样功能的程......

阅读全文(3606) | 评论:0