找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2895|回复: 0
打印 上一主题 下一主题
收起左侧

适合于单片机初学者的例题

[复制链接]
跳转到指定楼层
楼主
ID:721552 发表于 2020-4-5 11:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  
数据类型
  
位数
字节数
值域
  
sbit
  
1

0~1
  
signed char
  
8
1
-128~+127
  
unsigned char
  
8
1
0~255
  
signed short
  
16
2
-32768~+32767
  
unsigned short
  
16
2
0~65535
  
signed int
  
16
2
-32768~+32767
  
unsigned int
  
16
2
0~65535
  
signed long
  
32
4
-2147483648~2147483647
  
unsigned long
  
32
4
0~4294967295
  
float
  
32
4
0.175494E-38~0.402823E+38
  
sfr
  
8
1
0~255
  
sfr16
  
16
2
0~65535



51基本数据类型
unsigned char data *p=0x00; 访问内部RAMunsigned char xdata *q=0x01; 访问外部RAMunsigned char code *x=0x02; 访问ROM

C51程序设计实例

例1:把存放在程序存储区3800H-3805H单元中的6个常数读到内部RAM的20H开始的单元。

#include<reg51.h>

unsignedchar code *p=0x3800;

unsignedchar data  *q=0x20;

voidmain (void)

{

       unsigned char i;

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

      {

              *(q+i)=*(p+i);  

      }

}


例2:从20H单元开始存放32个带符号数,要求统计出大于0、小于0和等于0的个数并存放在单片机内部RAM的60H,61H,62H单元中。

#include<reg51.h>

chardata *p=0x20;

unsignedchar data *q=0x60;

voidmain(void)

{

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

   {

        if(*(p+i)>0)

       {

            *q=*q+1;     

        }

        else if (*(p+i)<0)

        {

             *(q+1)=*(q+1)+1;

         }

         else

         {

              *(q+2)=*(q+2)+1;

         }

   }

}


例3:将片外数据存储器中7000H-70FFH单元全部清零。

#include<reg51.h>

unsignedchar xdata  *p=0x7000;

voidmain (void)

{

       unsigned char i;

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

      {

              *(p+i)=0;  

      }

}


例1:P1口接八个共阴极发光二极管,试编写程序令发光二极管循环点亮。

#include<reg51.h>

voiddelay(unsigned int n) 延时n(ms)

{

     unsigned int i,j;

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

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

}

voidmain (void)

{

       unsigned char i;

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

      {

              P1=(1<<i);  左循环,左移

            delay(250);  延时250ms,代表n

      }

}


例2:电路如下图。8051的P1.0、P1.1、P1.2、P1.3分别接入四支发光二极管VD0、VD1、VD2、VD3,P3.0、P3.1、P3.2、P3.4分别接入四支开关S0、S1、S2、S3。

开关断开,对应的发光二极管亮。

开关闭合,对应的发光二极管灭。



#include<reg51.h>                       (见课本)

voidmain (void)

{

       while(1)

      {

              switch(P3&0x0f)

             {

                  case 0x01: P1=P1|0x01;break;

                  case 0x02: P1=P1|0x02;break;

                  case 0x04: P1=P1|0x04;break;

                  case 0x08: P1=P1|0x08;break;

                  default:;

              }

      }

}


中断

#include<reg51.h>

       void init(void)//中断初始化

       {

IT0=1; //设为下降沿触发

        EX0=1; //开外部中断0

        EA=1;//开总中断

       }

       void main(void)

       {

        init();

        While(1);

       }

       void ex0() interrupt 0  //中断子函数

       {

        P1=0xff;

      IE1=0;

       }


例:通过/INT0的下降沿实现数码管增计数,/INT1的下降沿实现数码管减计数。计数范围0-9




#include<reg51.h>

unsignedchar LED[10]={0x3f,0x06,....};

unsignedchar i;

voidmain(void)

{

    IT0=1;IT1=1;   

    EX0=1;EX1=1;EA=1; (固定套路)

    while(1);

}

voidex0() interrupt 0    允许中断后执行interrupt程序,当为/INT0中断时,对应向量0,选择该程序进行;若为……

{

    if(i<9)

   {

       P0=LED[++i];

   }

   else;

}

voidex1() interrupt 2

{

    if(i>0)

   {

       P0=LED[--i];

   }

   else;

}






中断与查询相结合的方式进行外部中断


voidex0() interrupt 0

{

    switch(P1&0x0f)

   {

        case 0x01: DV1();break;

        case 0x02: DV2();break;

        case 0x04: DV3();break;

        case 0x08: DV4();break;

        default:;

   }

   IE0=0; //低电平触发中断

}


定时器

方式0

例:应用定时器T0产生1ms定时,并使P1.0输出周期为2ms的方波,方式0。已知晶振震荡频率为6MHz。

TH0=(213-500)/25  (初值的计算与写入)

TL0=(213-500)%25


#include<reg51.h>

sbitled=P1^0;(定义接口P1.0,使C51单片机识别接口为P1.0)

voidmain (void)

{

    TMOD=0x00;

    TH0=(213-500)/25;

    TL0=(213-500)%25;

    TR0=1;

while(1)

  {

       if(TF0==1)

      {

           led=~led;

           TH0=(213-500)/25;

           TL0=(213-500)%25;       四句话

           TF0=0;

       }

       else;

   }

}


方式1

例:用定时器T1产生25Hz方波,由P1.0输出,采用查询方式进行控制,方式1。已知晶振震荡频率为12MHz。

#include<reg51.h>

sbitled=P1^0;

voidmain(void)

{

    TMOD=0x10;

    TH1=(216-20000)/28;

    TL1=(216-20000)%28;

      TR1=1;

    while(1)

    {

         if(TF1==1)

        {

led=~led;

            TH1=(216-20000)/28;

            TL1=(216-20000)%28;

            TF1=0;

        }

         else;

    }

}


例:利用定时器T0工作方式1,实现一个发光二极管以1s亮灭闪烁。12MHz晶振。

(使用中断的方式,定时时间超过单片机所允许的时间)



#include<reg51.h>

sbitled=P1^0;

unsignedchar num;

voidmain(void)

{

    TMOD=0x01;

    TH0=(216-50000)/28;

    TL0=(216-50000)%28;      六句话

     ET0=1;EA=1;TR0=1;

     while(1)

      {

          if(num==20)

          {

              led=~led;

              num=0;

          }

      }

}

voidT0() interrupt 1

{

    num++;

    TH0=(216-50000)/28;

    TL0=(216-50000)%28;

}


方式2

例:用定时器T1,工作方式2计数,要求每计满156次,将P1.7取反。

#include<reg51.h>

sbitled=P1^7;

voidmain(void)

{

    TMOD=0x60;

    TH1=28-156;

    TL1=28-156;

    TR1=1;

    while(1)

    {

         if(TF1==1)

         {

              led=~led;

              TF1=0;

         }

     }

}



(见课本,方式0、1、2的综合)


方式3(只适用于T0)

例:应用T0方式3,分别设定200μs和400μs定时并使P1.0和P1.1分别产生周期为400μs和800μs方波。晶振6MHz。采用中断控制方式。

#include<reg51.h>

sbitled1=P1^0;

sbitled2=P1^1;

voidmain(void)

{

    TMOD=0x03;

    TH0=28-100;   //200μs

    TL0=28-200;   // 400μs

    ET0=1;ET1=1;EA=1;

    TR0=1;TR1=1;

     while(1);

}

voidtime0() interrupt 1

{

     TL0=28-200;

     led2=~led2;

     TF0=0;

}

void time1() interrupt 3

{

     TH0=28-100;

     led1=~led1;

     TF1=0;

}


   

串行口   

例1:请编写在数码管上循环显示0-9这10个数字的程序。串行通信方式0,定时器间隔1s。



   




#include<reg51.h>

unsignedchar led[10]={0x03,….};

unsignedchar num,I;

voidmain(void)

{

       TMOD=0x01;

       TH0=(216-50000)/28;

       TL0=(216-50000)%28;

       TR0=1;

       ET0=1;

       EA=1;

       SCON=0x00;

       while(1)

       {

            if(num==20)

           {

                  num=0;

                  SBUF=led[i++];

                  if(i==10)

                  {

                       i=0;

                   }

            }   

       }

}

voidT0() interrupt 1

{

    num++;

    TH0=(216-50000)/28;

    TL0=(216-50000)%28;

    TF0=0;

}


例2:根据电路图,编写从16位扩展口读入10个字节数据,并把它们转存到内部RAM的20H~29H中。S/L=0并行置入16位数据;S/L=1允许串行移位输出


#include<reg51.h>

unsignedchar data *p=0x20;

unsignedchar i,j;

void main(void)

{

     SCON=0x10;             //方式0

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

    {

         P1&=0xfe;          //P1.0置0

         P1|=0x01;          //P1.0置1

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

        {

              while(!RI);       //等待数据接收完成

              *p++=SBUF;    //将数据缓存区中接收到的数据给了20H

              RI=0;          //响应中断后该标志位必须及时清零,为下一次做准备

        }

    }

}

第一个for循环是为了分5次接收字节,每次接收16位数,也就是2个字节;第二个for循环是将一次接收的2个字节转存RAM

先让P1.0=0,是为了置入16位数;置入后让P1.0=1,是为了允许串行移位输出

C51拓展

存储器拓展

例,下图采用的是译码法还是片(线)选法?74LS139、74LS373起到什么作用?2#芯片的寻址范围是什么?执行unsigned char xdata *r22= 0x4000;语句后,r22变量中的值将存储于哪一个芯片中?



下图采用的是译码法。

74LS139作用是地址译码。

2000H~3FFFH。

存储于3#芯片中。        




38译码器,数电中的知识点,eg. CBA—001—Y1口,从而对应2#芯片

                                    010—Y2口,从而对应3#芯片











P2.7P2.6 P2.5

只有这三种选法,因为外部RAM使能必须保证/CE为低电平

外部
I/O拓展

例题:利用74LS244作为输入口接8路开关,读取开关状态,并将读取状态通过74LS273驱动发光二极管显示出来。





#include <reg51.h>

unsignedchar xdata *p=0xbfff;(分析)

unsignedchar xdata *q=0x7fff;

unsignedchar buffer;

voidmain(void)

{

       buffer=*p;

       *q=buffer;

}

输入缓冲,输出锁存

常用作输入拓展的芯片:74LS244、74LS373

注:74LS244是8位三态门,当/1G、/2G均为低电平时,允许输入数据;否则,为高阻态。

    74LS373的/E=0时才允许输入

常用作输出拓展的芯片:74LS377、74LS273

注:74LS377的E=0时才可将数据打入锁存器

74LS273的CLK=0时才可将数据打入锁存器

(具体讲解想见课本)


A/D拓展



1111 1110 1111 1***

                                  P2.0                            P0.2 P0.1 P0.0

例题:设有一个8路模拟量输入的巡回检测系统,采样数据依次存放在外部RAM 2000H-2007H单元中,要求采用中断方式。

#include <reg51.h>   

unsignedchar  xdata *p=0xfef8;   //一定要写正确,对通道的选择

unsignedchar  xdata  *q=0x2000;

unsignedchar num=1;

voidmain(void)

{

     IT0=0;

     EX0=1;

     EA=1;

     *p=0x00;  //写什么都行,需要送出地址

     while(1);

}

voidad() interrupt 0

{

     *q=*p;

     p++;

     q++;

     num++;

    if(num==8)

    {

         EX0=0;

         EA=0;

    }

    *p=0x00;  //写什么都行,需要送出地址

     IE0=0;

}

单片机程序例题.docx

2.32 MB, 下载次数: 8, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表