单片机总复习

发布于:2025-07-07 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、理论:

1.进制转化:

十进制转成二进制:除以2取余,从右向左写。

二进制转成十进制:从右向左每位依次为2的0次方,2的1次方,2的2次方,依次递增,再加起来。

二进制转成十六进制:从右向左,每四位一划分。

2.四个周期:

(1)振荡周期:

晶振频率分之一。

(2)状态周期:

振荡周期*2.

(3)机器周期:

振荡周期*12.

(4)指令周期:

(1~4)*机器周期

3.定时原理:

二、实验:

1.让一个LED点亮

#include <REGX51.H>
  void main()
  {
   while(1)
  {
  P2=0xfb;//1111 1011
  }
  }

2.让一个LED闪烁

#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
void delay_10us(u16 t)
{
while(t--);
}
void main()
{
P2=0xfe;//1111 1110
delay_10us(50000);
P2=0xff;
 delay_10us(50000);
}

3.实现流水灯

#include <REGX51.H>
 typedef unsigned int u16;
 typedef unsigned char u8;
 void delay_10us(u16 t)
 {
 while(t--);
 }
 void main()
 {
 u8 i=0;
 P2=~(0x01);
 for(i=0;i<8;i++)
 {
 P2=~(0x01<<i);
 delay_10us(50000);
 }
 }

4.

#include <REGX51.H>
 typedef unsigned int u16;
 typedef unsigned char u8;
 void delay_10us(u16 t)
 {
 while(t--);
 }
 void main()
 {
 while(1)
 {
 P2=0xfc;//1111 1100
 delay_10us(50000);
 P2=0xf3;//1111 0011
  delay_10us(50000);
 P2=0xcf;//1100 1111
  delay_10us(50000);
 P2=0x3f;//0011 1111
  delay_10us(50000);
  }
  }

5. 

#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
void delay_10us(u16 t)
{
while(t--);
}
void main()
{
while(1)
{
P2=0x7e;//0111 1110
delay_10us(50000);
P2=0xbd;//1011 1101
delay_10us(50000);
P2=0xdb;//1101 1011
delay_10us(50000);
P2=0xe7;//1110 0111
delay_10us(50000);
P2=0xdb;//1101 1011
delay_10us(50000);
P2=0xbd;//1011 1101
delay_10us(50000);
}
}

6. 

#include <REGX51.H>
 typedef unsigned int u16;
 typedef unsigned char u8;
 void delay_10us(u16 t)
 {
 while(t--);
 }
 void main()
 {
 u8 i=0;
 while(1)
 {
 P2=~(i++);
 delay_10us(200000);
 }
 }

7.独立按键实验 

#include <REGX51.H>
 typedef unsigned int u16;
 typedef unsigned char u8;
 void delay_10us(u16 t)
 {
 while(t--);
 }
void main()
{
P2_0=0;
while(1)
{
if(P3_1==0)
{
delay_10us(50000);
while(P3_1==0)
delay_10us(50000);

P2_0=~P2_0;
}
}
}

8.

#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;

void delay_10us(u16 t)
{
    while(t--);
}

void main()
{
   u8 i=0;
   P2=~0x01;
   while(1)
   {
   if(P3_1==0)
   {
   delay_10us(50000);
   while(P3_1==0)
   delay_10us(50000);
   i++;
   if(i>=8)
   i=0;
   P2=~(0x01<<i);
   }
   if(P3_0==0)
     {
   delay_10us(50000);
   while(P3_0==0)
   delay_10us(50000);
   if(i==0)
   i=7;
   else
   i--;
   P2=~(0x01<<i);
   }
   }
   }

9.静态数码管

第一步:定位哪个LED亮:给P2_2.3.4赋值。注意顺序:P2_4是高位,即如果P2_4=1,P2_3=1,P2_2=0,那就是110,即Y6---LED7亮。

看每个LED灯,假设LED7亮E,即afged亮,也就是P0_7---P0_0赋予0111 1001.(注意顺序是从P0_7---P0_0,从下往上,亮的给1)即P0=0x79。

#include <REGX51.H>
 void main()
 {
  P2_4=1 ;
  P2_3=1 ;
  P2_2=0 ;
  P0=0x79;
  }

10.动态数码管

注意:1.先定义数码管数组。

2.注意延时函数的写法。

3.亮某数码管用Switch,一定要注意数码管的顺序。

4.亮P0之后要消影。

#include <REGX51.H>
unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.空
 void delay(unsigned int xms)    
{
   unsigned char i,j;
   while(xms--)
   {
   i=2;
   j=239;
   do
   {
   while(--j);
   }
   while(--i);
   }
}

void light(unsigned char location,number)
{
switch (location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=led[number];
delay(1);
P0=0x00;
}
void main()
{
while(1)
{
 light(1,2);
 light(2,0);
light(3,0);
light(4,6);
light(5,0);
light(6,7);
light(7,2);
light(8,6);
}
}




11.

#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
u8 led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};//0.1.2.3.4.5.6.7
u16 count=0;
void delay(unsigned int xms)    
{
   unsigned char i,j;
   while(xms--)
   {
   i=2;
   j=239;
   do
   {
   while(--j);
   }
   while(--i);
   }
}

void main()
{
P2_4=1;
P2_3=1;
P2_2=1;
P0=led[0];
delay(1);
P0=led[0];
while(1)
{
if(P3_1==0)
{
delay(500);
while(P3_1==0)
delay(500);
count++;
P0=led[count];
 if(count>7)
 P0=led[7];
 }
 if(P3_0==0)
 {
  delay(500);
while(P3_0==0)
delay(500);
P0=led[0];
}
}
}

12.外部中断实验按下后灯翻转 

#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
 void delay_10us(u16 t)
 {
 while(t--);
 }
void  Timer0_Init()
{
TMOD=TMOD&0xF0;
TMOD=TMOD|0x01;
TH0=64535 /256;
TL0=64535%256;
TF0=0;
TR0=1;
ET0=1;
EX1=1;
EA=1;
}
 void main()
 {
  Timer0_Init();
  while(1)
  {
  }
  }
  void Timer0_Routine() interrupt 1
  {
  delay_10us(1000);
  if(P3_0==0)
  {
  delay_10us(1000);
  while(P3_0==0)
  delay_10us(1000);
  P2_0=~P2_0;
  }
  }

13.定时器实验定时后1s,led翻转

#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
u16 count=0;
void  Timer0_Init()
{
TMOD=TMOD&0xF0;
TMOD=TMOD|0x01;
TH0=(65536 - 9216) /256;
TL0=(65536 - 9216)%256;
TF0=0;
TR0=1;
ET0=1;
EX1=1;
EA=1;
}
 void main()
 {
  Timer0_Init();
  while(1)
  {
  }
  }
  void Timer0_Routine() interrupt 1
  {
   TH0 = (65536 - 9216) / 256;  // 重新赋值初值
    TL0 = (65536 - 9216) % 256;
   count++;
    if (count >= 100) {  // 10ms * 100 = 1s
        count = 0;
        P2_0 = ~P2_0;  // LED状态翻转
    }

  }

14.

typedef unsigned char u8;
u8 num = 0;
u16 count=0;
void  Timer0_Init()
{
TMOD=TMOD&0xF0;
TMOD=TMOD|0x00;
TH0=(8192 - 9216)>> 5;
TL0=(8192 - 9216) & 0x1F;
TF0=0;
TR0=1;
ET0=1;
EX1=1;
EA=1;
}
 void main()
 {
  Timer0_Init();
  while(1)
  {
  }
  }
  void Timer0_Routine() interrupt 1
  {
   TH0 = (8192 - 9216) >> 5;  // 重新赋值初值
    TL0 = (8192 - 9216) & 0x1F;
   count++;
    if (count >= 40) { 
        count = 0;
        num++;
        if(num>15)
        {
        num=0;
        }
        P2 =~num;  
    }

  }

15. 

 #include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
bit key_flag = 0;  // 按键按下标志位
u16 count = 0;  // 定时器计数变量

// 10微秒延时函数,用于消抖
void delay_10us(u16 t) {
    while (t--);
}

// 定时器0初始化函数
void Timer0_Init() {
    TMOD &= 0xF0;
    TMOD |= 0x01;  // 设置定时器0为方式1
    TH0 = (65536 - 9216) / 256;  // 定时10ms初值,11.0592MHz晶振下
    TL0 = (65536 - 9216) % 256;
    TF0 = 0;
    TR0 = 0;  // 先不启动定时器,等按键按下再启动
    ET0 = 1;
    EA = 1;
}

// 外部中断0初始化函数
void EX0_Init() {
    IT0 = 1;  // 设置外部中断0为下降沿触发
    EX0 = 1;
    EA = 1;
}

void main() {
    P2_0 = 0;  // 初始LED亮
    Timer0_Init();
    EX0_Init();
    while (1);
}

// 外部中断0服务函数
void EX0_Routine() interrupt 0 {
    delay_10us(5000);  // 消抖
    if (P3_2 == 0) {  // 确认按键按下
        key_flag = 1;  // 设置按键按下标志
        P2_0 = 1;  // LED熄灭
        count = 0;  // 计数清零
        TR0 = 1;  // 启动定时器
        while (P3_2 == 0);  // 等待按键释放
    }
}

// 定时器0服务函数
void Timer0_Routine() interrupt 1 {
    TH0 = (65536 - 9216) / 256;
    TL0 = (65536 - 9216) % 256;
    if (key_flag) {  // 只有按键按下后才计数
        count++;
        if (count >= 100) {  // 10ms * 100 = 1s
            count = 0;
            key_flag = 0;  // 标志位清零
            P2_0 = 0;  // LED亮
            TR0 = 0;  // 停止定时器
        }
    }
}

16.

#include <REGX51.H>

// 外部中断0初始化函数
void EX0_Init() {
    IT0 = 1;  // 设置外部中断0为下降沿触发
    EX0 = 1;  
    EA = 1; 
}

void main() {
    P1 = 0x00;  // LED全灭
    EX0_Init(); 
    while (1)
    {
    }  
}

// 外部中断0服务函数
void EX0_Routine() interrupt 0 {
    if (P1_0 == 1) {
        P1_3 = 1;  // 若X1为高电平,点亮LED1
    }
    if (P1_1 == 1) {
        P1_4 = 1;  // 若X2为高电平,点亮LED2
    }
    if (P1_2 == 1) {
        P1_5 = 1;  // 若X3为高电平,点亮LED3
    }
}

17.矩阵按键实验

按下“矩阵按键”模块中S1-S16键,对应数码管最左边显示0-F

#include <REGX51.H>
  typedef unsigned int u16;
 typedef unsigned char u8;
 #define KEY P1
 #define light P0
 u8 led[]={0x3f,0x06,0x5b,0x4f,0x6b,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}
 u8 key_scan()
{
static u8 key_value=0;
  KEY=0X0F;
  if(  KEY!=0X0F )
  {
  delay_10us(1000);
    if(  KEY!=0X0F )
    {
     KEY=0X0F;
     switch(KEY)
     {
     case 0x07:key_value=1;break;
      case 0x0b:key_value=2;break;
       case 0x0d:key_value=3;break;
        case 0x0e:key_value=4;break;
        }
       KEY=0XF0;
       switch(KEY)
     {
     case 0x70:key_value=key_value;break;
      case 0xb0:key_value=key_value+4;break;
       case 0xd0:key_value=key_value+8;break;
        case 0xe0:key_value=key_value+12;break;
        }
        while( KEY!=0xf0) ;
        }
        }
        else
        key_value=0;
        return key_value;
        }

        void main()
        {
        u8 key=0;
        while(1)
        {
        key=key_scan();
        if(key!=0)
        P0=led[key-1];
        }
        }



18.

19.

20.

21.

22.

23.


网站公告

今日签到

点亮在社区的每一天
去签到