2016年10月9日星期日

单片机中unsigned char 和unsigned int的区别

单片机中unsigned char 与 unsigned int的区别如下:
  unsigned char 是无符号字符,数据长度是8位,表示值范围从0~255
  unsigned int 是无符号整数,数据长度是16位(或者32位,看单片机的型号而定),表示范围从0~65535(或者0~4294967295)
uint 是无符号整型,16位二进制,需要2个字节表达,其值范围为:0到65535。
uchar是无符号字符型,8位二进制,只需要1个字节表达,其值范围为:0到255。
显然,如果delay函数定义为delay(uchar z),你在调用delay函数时,传递的参量不能超过255,否则就会得到意想不到的后果。另外,在delay函数内部,传递的延时量z用unchar型和unint型,即使是用同一个传递数字,例如都是用delay(100),因为运算量的不同,它们之间还是有些差异的。
这里所谓的运算量是指编译成汇编后的运算,从C源程序是看不出来的。

2016年6月2日星期四

单片机编码表 unsigned char code table[] 的理解

 code的作用是告诉单片机,定义的数据要放在ROM(程序存储区)里面,其实是相当于汇编里面的寻址MOVX,因为C语言中没办法详细描述存入的是ROM还是RAM(寄存器),所以在软件中添加了这一个语句起到代替汇编指令的作用,对应的还有data是存入RAM的意思。

unsigned char code table[] 用 code 表示代码编译完了,数据会放到程序存储区(ROM)当中.如果不用,数据会放到随机储存器单中(RAM)(寄存器).

一个单片机的随机存储器是有限制的。51单片机的RAM是128个字节。你每定义一个char的变量,它占用的就是RAM中的一个字节。用unint占用的是两个字节。
一个芯片内部的RAM非常宝贵。

51单片机中的ROM有4kb(4千个字节),远远大于RAM中的128b.所以把这个固定的编码数据放在ROM中可以节约宝贵的RAM空间。

数码管静态和动态显示

动态显示驱动:数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
静态显示通常只有一个数码管的情况下用,直接把段码送到数码管就可以了。阴极直接接地。如果数码管较多一般是不用的,因为IO口不够。动态显示,对于共阴极数码管,把所有数码管的阳极并联后接到单片机IO口上作为段码。把所有阴极顺次接到单片机IO口上作为位码。通过控制位码实现控制单一数码管显示,通过控制段码来控制显示内容。然后通过循环点亮的形式依次点亮各个数码管,并保留一小段时间,只要时间合适就可以让人的视觉看起来都是亮的。


四位数码管引脚图(共阳极)




2016年5月27日星期五

单片机的基本时序

机器周期和指令周期


1:震荡周期:也称时钟周期,是指单片机提供时钟脉冲信号的震荡源的周期;
2:状态周期:每个状态周期为时钟周期的2倍,是震荡周期二分频后得到的。
3:机器周期:一个机器周期包含6个状态周期s1--s6, 也就是12个时钟周期.在一个机器周期内,CPU可以完成一个独立的操作。
4:指令周期:它是指cpu完成一条操作所需要的全部时间。每条指令执行时间都是有一个或几个机器周期组成。

2015年10月25日星期日

蜂鸣器

无源的蜂鸣器,就要通过IO口输出振荡信号来驱动蜂鸣器
蜂鸣器简介:蜂鸣器根据结构不同分为压电式蜂鸣器和电磁式蜂鸣器;而两种蜂鸣器又分为有源蜂鸣器和无源蜂鸣器,这里的源特指振荡源;有源蜂鸣器直接加电就可以响起,无源蜂鸣器需要我们给提供振荡源。理想的振荡源为一定频率的方波。

只有当有一定频率的电流从正极流向负极,蜂鸣器才会叫。
三极管在这些方波的控制下导通,截止(图,可以看单片机教程上的),就会有和方波频率相同的电流流过蜂鸣器。

改变控制方波的频率就可以控制蜂鸣器音调,产生各种不同的音色,音调的声音。控制方波的频率越高,蜂鸣器的声音越尖。反之,越低沉。改变控制方波的的高低电平占空比,则可以控制蜂鸣器的声音大小.


图中(a)(b)改变了频率。图(c)(d)改变了占空比,频率一样。

如果系统采用了无源蜂鸣器,所以需要我们通过编程来控制I/0口的翻转来产生一定频率的方波信号。如果采用默认频率0.5KHZ的标准方波。可以算出周期T = 2ms 脉宽t = 1ms,因此我们可以通过简单的延时函数延时1ms。然后控制P口的电平高低产生0.5KHZ的方波信号;

本程序只是通过简单延时达到驱动蜂鸣器的效果。
#include <reg52.h>
sbit buzzer = P1^5;
void delayms(unsigned int xms)   //延时函数 ,延时xms
{
      unsigned int i , j;
          for(i = 0; i < xms; i++)
              for(j = 0; j < 110; j++);
}

void fengming()    //蜂鸣函数,脉宽t = 1ms 周期T = 2ms 频率f = 0.5khz 实际发现延时1ms的时候效果最好
{
        buzzer = 0; //
P1.5口送低电平
        delayms(1);   //
延时1ms
        buzzer = 1;   //
P1.5口送高电平
        delayms(1);   //
延时1ms
}





2015年10月4日星期日

K1-K4 按键状态显示

名称:K1-K4 按键状态显示
说明:K1、K2 按下时 LED 点亮,松开时熄灭, K3、K4 按下并释放时 LED 点亮,再次按下并释放时熄灭;

              #include<reg51.h>
   2          #define uchar unsigned char
   3          #define uint unsigned int
   4        
   5          sbit LED1 = P2^0;
   6          sbit LED2 = P2^1;
   7          sbit LED3 = P2^2;
   8          sbit LED4 = P2^3;
   9        
  10          sbit K1 = P0^0;
  11          sbit K2 = P0^1;
  12          sbit K3 = P0^2;
  13          sbit K4 = P0^3;
  14        
  15          //延时,用来防抖
  16          void delayMS(uint x)
  17          {
  18   1              uchar i;
  19   1              while(x--)
  20   1              {
  21   2                    
  22   2                      for(i = 0; i < 120; i++);
  23   2                    
  24   2              }
  25   1      }
  26          //主程序
  27          main()
  28          {
  29   1              P0 = 0xff;//给P0和P2口赋值;高电平;
  30   1              P2 = 0xff;
  31   1              while(1)
  32   1              {
  33   2                      LED1 = K1;//K1端接地,当按下K,P0^0变为0(低电平)
  34   2                      LED2 = K2;
  35   2                      if(K3 == 0)
  36   2                      {
  37   3                              while(K3==0);//按着k3不放,就循环。等待,什                                                    // 么也不干,一旦放开,继续执                                                      // 行;
  38   3                              LED3 =~ LED3;
  39   3                      }
  40   2                      if(K4 == 0)
  41   2                      {
  42   3                              while(K4 == 0);
  43   3                              LED4 =~ LED4;
  44   3                      }
  45   2                      delayMS(10);
  46   2              }
  47   1            
  48   1      }

        理解if(K3 == 0)
              {
                  while(K3 == 0);
                  LED3 = LED3;
               }


一旦K3 == 0 也就是if 的条件为true,那么必须把if里面的所以东西执行完。

  类比c语言:if(k == 0){
                          k=9;//虽然这步k 已经是9 了,但是还是要把下面的表达式子                               //  执行完
                          led = 1;
                          }

单片机sbit p1_1 = p1^1 的理解????

sbit p1_1 = P1^1;
p1_1 = 1;

P1^1是位,相当于地址,P1^1不是变量,不能写成P1^1 = 0;

P1.1是端口名字,不能用它当变量,因为不符合c的变量命名规则;

sbit 定义的是位变量,赋值只能是0或者1;

因为P1^1是地址,通过sbit,定义变量p1_1代表了P1^1的空间,这空间的名字为p1_1.
给变量p1_1赋值,就相当于把值放在了P1^1里面;

相当于c语言 int c = 5;把5付给变量c,系统自动给c分配了一片内存,内存的名字为c;这里只是自动的,但是在单片机要用 sbit p1_1 = P1^1人工设置。