-----------------------------------------------------
   在冰城哈尔滨邮购了一套郭天翔的单片机教程和实验板,利用业余时间学习了一下。目前仍在学习中。。在学习过程中记录了一些学习笔记,发表在我的博客里,
-----------------------------------------------------
  
先贴一张具有里程碑意义的照片吧,这是我用C语言程序点亮的第一个发光二极管。

源程序如下:
#include
sbit deng1=P1^0;
void main()
{
deng1=0;
}
再来看看我邮购了些什么东西

盒子里有实验板、芯片、学习光盘、串口线、杜邦线、...
有了实验板,因为可以不断地修改程序,下载,观察执行结果。
要是把C语言看成梯形图,把单片机看成PLC 把P口看成I/O,这不就是一个微型的PLC嘛。。
PLC要几千块,而这个STC的片子只要8元钱,甚至还可以申请免费的样片。
下面就开始说流水灯
课程在流水灯程序的基础上加入了蜂鸣器驱动语句,但源程序是蜂鸣器一直响。我改动了
一些程序,加入了关闭,和延时的语句,经过修改与实验,蜂鸣器可以随着灯的亮灭交替发声了:)
这的确让我感到非常喜悦!非常有成就感。
入门阶段,例举让高手们见笑了。不足之处,请多指教:)
实践!没有实践等于零!这是我得出的最大感悟。
下面贴上流水灯的C语言程序
#include               //定义头文件
#include     //定义循环左移头文件
#define uint unsigned int   //定义子程序变量类型为 unsigned int型
#define uchar unsigned char     //定义uchar为unsigned char 型
void delay(uint);               //字程序声明
uchar temp;       //定义给P1口赋值的变量temp为uchar型
sbit beep=P2^3;      //定义蜂鸣器的信号口为P2口的第4位
void main()       //主函数
{
temp=0x7f;                  //给temp变量赋值0xfe
P1=temp;      //把temp的值给P1口
         
   while(1)     //开始循环 while()内不为1则{}中的程序循环执行
   {
    temp=_crol_(temp,1);//让temp里的值11111110左移一位
    delay(50);    //调用子程序延时
    P1=temp;    //将移位后的值11111101传给P1口
    beep=0;     //打开蜂鸣器
    delay(50);    //调用延时程序
    beep=1;     //关闭蜂鸣器
   
              
   }      //返回temp=_crol_(temp,1)语句再一次开始左移,循环
}
void delay(uint z)        //字程序
{
uint x,y;     //定义变量
for(x=100;x>0;x--)          //x=100 如果x>0则执行for(y=z;y>0;y--);
   for(y=z;y>0;y--);       //执行完for(y=z;y>0;y--);后,执行X-1
  
  
          //返回第二步x>0? 依次循环
}
但如果把二极管的发光时间调长一些就会发现亮和灭的时间是不一样的。
这是刚开始容易忽略的问题
程序改动如下,
#include
#include
#define uint unsigned int
#define uchar unsigned char
uchar temp;
sbit beep=P2^3;
void delay(uint);
void main()
{
  
        temp=0xfe;
while(1)
{

    P1=temp;
    beep=0;
    delay(540);
    temp=_crol_(temp,1);
    P1=0xff;
    beep=1;
    delay(540);
  
   }


}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
   for(y=110;y>0;y--);
}
在移位后给P1口送全1,让P1口关闭二极管发光时同样时间,把蜂鸣器的0和1加进去就可以了。
同理,再来看发光管来回流动的题目
8个发光管来回流动,每个管亮100MS,流动时让蜂鸣器发出“嘀嘀”声。
分析:来回流动这里要用到位左移和位右移命令,每个管亮100MS可以调用延时子程序,
流动时发出滴滴声就是亮的时候蜂鸣器响,灭的时候蜂鸣器不响,并且蜂鸣器时序要和循环移位时序相同。
题目并没有时间要求,要一直循环下去,所以要用到WHILE语句,左位移后右位移需要调用FOR语句给
位移次数做以限制。下面对程序的每一条语句加以说明。
#include                 //定义头文件
#include             //定义移位命令头文件
#define uint unsigned int              //定义变量类型
#define uchar unsigned char        //定义变量类型
void delay (uint);                 //子程序说明
uchar temp,num;                 //定义8位变量为uchar型
sbit beep=P2^3;                 //定义蜂鸣器输出
void main()                     //主函数开始
{
    temp=0xfe;               //首先给变量temp赋值11111110
       while(1)                 //开始while语句内的无限循环
       {
          for(num=0;num<7;num++) //让变量num=0 执行for后面{}内的程序,执行完一次后num+1,
这时判断num+1的值是否小于7,如果小于,继续执行{}中的内容1次,再加1,再判断,一直到num的值大于7后
跳出该循环。这条语句的作用就是当num从0遍到6遍时,循环移位刚好完成7次 完成第一次左位移。
           {
     P1=temp;             //把刚才temp的值11111110传给P1口,让第一个灯亮
           beep=0;                  //让蜂鸣器开始响
           delay(100);               //调用延时子程序,让第一个灯亮并让蜂鸣器响子程序延时的时间,100MS
           P1=0xff;                 //给P1口送全1,让P1口灭掉。
           beep=1;                  //当然,这时要把蜂鸣器关掉
delay(100);                //调用延时程序,让P1口灭并且让蜂鸣器停止延时子程序设定的时间,和亮的时间是相同的
temp=_crol_(temp,1);       //时间一到开始左移命令,把11111110左移一位,temp的值变为11111101,把这个值传送给P1口
                                    开始for语句循环。直到灯从第一位变到第8位,跳出FOR循环
           }                     //下面该右循环了,
       for(num=0;num  // 同理,开始右循环的计数
           {                       左循环执行6次跳出后temp 里的值是0111 1111 ,
           P1=temp;               把0111 1111给P1口
           beep=0;
           delay(100);               开始延时100MS
           P1=0xff;               P1口灭,等待100MS
           beep=1;
           delay(100);
temp=_cror_(temp,1);     时间到了以后temp移位 传给P1 P1 变为10111111 当灯变为11111110时正好是6次,也是就是说当Num =7时跳出FOR循环
                            程序调转到★处开始第二次左位移,这时P1 口又从11111110开始了
           }
       }  
}
void delay(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
       for(y=110;y>0;y--); 
}
比较容易混淆和头疼的是左循环和右循环的次数
用二进制移位来说明一下
刚开始的值为
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 1   第0次FOR循环
1 1 1 1 1 0 1 1   第1次FOR循环
1 1 1 1 0 1 1 1   第2次FOR循环
1 1 1 0 1 1 1 1   第3次FOR循环
1 1 0 1 1 1 1 1   第4次FOR循环
1 0 1 1 1 1 1 1   第5次FOR循环
0 1 1 1 1 1 1 1   第6次FOR循环
当num=7时 因为已经不小于7了,所以跳出FOR 循环
而跳出后,temp里的值是0111 1111 把这个值送给P1 开始延时
0 1 1 1 1 1 1 1  
1 0 1 1 1 1 1 1   0
1 1 0 1 1 1 1 1   1
1 1 1 0 1 1 1 1   2
1 1 1 1 0 1 1 1   3
1 1 1 1 1 0 1 1   4
1 1 1 1 1 1 0 1   5
1 1 1 1 1 1 1 0   6
多么详细的叙述啊。。。
继续
用发光管演示二进制累加器每次加一的显示过程。</SPAN>
 
#include
#define uint unsigned int
#define uchar unsigned char
uchar temp;
void delay(uint);
sbit beep=P2^3;
void main()
{
temp=0xfe;          
P1=temp;
   while(1)
   {
    beep=0;
    delay(100);
   
    P1=0xff;
    beep=1;
    delay(100);
    temp--;
    P1=temp;
   }
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
   for(y=110;y>0;y--);
}
程序里加入了蜂鸣器 让二极管显示二进制累加过程其实就是让0XFE每次减1
然后加入灭掉的时间,循环就可以了。
最后贴上流水灯的课后习题答案,都是经过实验板验证的。
【1】8个发光二极管间隔200MS由上到下,再由下到上,重复一次。全部熄灭,以300MS间隔闪烁5次。循环。
#include
#include
#define uint unsigned int
#define uchar unsigned char
void delay (uint);
void delay1 (uint);
uchar temp,num,num1,num2;
sbit beep=P2^3;
void main()
{
temp=0xfe;
   while(1)
   {
   for(num1=0;num1    {
          for(num=0;num     {
    P1=temp;
    beep=0;
    delay(200);
    temp=_crol_(temp,1);
    P1=0xff;
    beep=1;
    delay(200);
    }
   
    for(num=0;num     {
    P1=temp;
    beep=0;
    delay(200);
    temp=_cror_(temp,1);
    P1=0xff;
    beep=1;
    delay(200);
    }
   }
   temp=0xfe;
   P1=temp;
   beep=0;
   delay(200);
   for(num2=0;num2    {
   temp=0xff;
   P1=temp;
   beep=1;
   delay1(600);
   P1=0x00;
   beep=0;
   delay(600);
   }
   P1=0xff;
   beep=1;
   while(1);
   }
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
   for(y=110;y>0;y--);
}
void delay1(uint z)
{
uint x,y;
for(x=z;x>0;x--)
   for(y=110;y>0;y--);
}
说明:时间可能不太准,可以根据晶振微调。
-------------------------------------------------------------------------------------------------------
【2】 间隔300MS第一次一个管亮流动一次,第二次两个管亮,依次到8个管,重复这个过程。
#include
#include
#define uint unsigned int
#define uchar unsigned char
void delay (uint);
uchar temp,num;
sbit beep=P2^3;
void main()
{
temp=0xfe;
   while(1)
   {
            for(num=0;num     {
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0xfc;
      for(num=0;num     {
   
   
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0xf8;
      for(num=0;num     {
   
   
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0xf0;
    for(num=0;num     {
   
   
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0xe0;
    for(num=0;num     {
   
   
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0xc0;
    for(num=0;num     {
   
   
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0x80;
    for(num=0;num     {
   
   
    P1=temp;
    beep=0;
    delay(222);
   
    P1=0xff;
    beep=1;
    delay(222);
    temp=_crol_(temp,1);
    }
    temp=0x00;
    P1=temp;
    beep=0;
    delay(222);
    P1=0xff;
    beep=1;
    delay(222);
    temp=0xfe;
   
  
   }
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
   for(y=110;y>0;y--);
}
-------------------------------------------------------------------------------------------【3】间隔300MS先奇数亮再偶数亮,循环三次。一个灯上下流动循环三次,两个灯从两边往中间流动3次,再从中间往两边流动三次,全部闪烁3次关闭。
#include< reg52.h>                   //定义头文件
#include< intrins.h>     //定义循环头文件
#define uint unsigned int       
#define uchar unsigned char      //定义变量
uchar temp,temp1,temp2,a,b;    //声明变量
void delay();       //声明延时子程序
void main()                         //主函数开始
{
P1=0xff;                        //给P1口送1111 1111
   while(1)                    //开始while语句循环
   { for(b=8;b>0;b--)     //开始3次for循环
     {
     temp=0xaa;          //给P1口1010 1010
     P1=temp;
     delay();            //延时
     temp=0x55;     //给P1口0101 0101
     P1=temp;
     delay();     //延时
     }
    for(a=5;a>0;a--)    //开始3次for循环
     {
     temp=0xfe;    //给temp赋值1111 1110
     for(b=7;b>0;b--)    //开始7次位移
      {
       P1=temp;              //P1口为1111 1110
        
       delay();              //延时
       temp=_crol_(temp,1); //1111 1110 左移一位变为1111 1101
       P1=temp;     //把1111 1101给P1
          delay();     //延时
      
      }
                 }
            temp1=0xfe;                 //temp1=1111 1110 temp2=01111111
    temp2=0x7f;
    for(b=8;b>0;b--)            //循环3次
             {
    for(a=8;a>0;a--)           
     {
     temp=temp1&temp2;       //让temp=1111 1110 或0000 0001 等于1000 0001
     P1=temp;     //让P1口等于1000 0001
     delay();                //延时
     temp1=_crol_(temp1,1); //让temp1循环左移
     temp2=_cror_(temp2,1); //让temp2循环右移
     }
    }
   }
}
void delay()                            //子程序延时程序
{ uint a,b;
for(a=100;a>0;a--)
for(b=100;b>0;b--);
 
 
 阅读全文>>