51单片机学习总结(自学)

1、模块化编程

51单片机学习总结(自学)_第1张图片

51单片机学习总结(自学)_第2张图片

51单片机学习总结(自学)_第3张图片

51单片机学习总结(自学)_第4张图片

c语言模块化编程实现思路设计代码

51单片机学习总结(自学)_第5张图片

具体的程序实现代码如下所示

1:程序的头文件

51单片机学习总结(自学)_第6张图片

2:程序的函数文件

51单片机学习总结(自学)_第7张图片

3:程序的主文件控制函数的实现

51单片机学习总结(自学)_第8张图片

第一章单片机led灯

led 介绍

51单片机学习总结(自学)_第9张图片

单片机的工作原理:cpu通过配置寄存器控制我们的硬件电路实现我们的功能

51单片机学习总结(自学)_第10张图片

二进制转换为16进制:进制转换关系对应表

二进制转换16进制网址

51单片机学习总结(自学)_第11张图片

点亮51单片机的第一个led灯和让单片机的led灯实现亮灭亮灭的效果(采用16进制的方式实现)

目前我使用的是清翔电子的51单片机(建议按照自己购买的单片机观看对应的学习视频)

51单片机学习总结(自学)_第12张图片

led灯单个亮灭效果代码如下所示该单片机led灯的口为P1
 

#include 

	// P1 是第一个led晶体管1111 1110 倒数转换为16进制

void main(){
	P1 = 0xFE;  // 点亮第一个单片机的led灯
	P1 = 0x55; 	// 单片机的亮灭效果
	

	while(1){// 添加while循环让单片机停止或者开始
	      
	}

}

实现led灯的闪烁效果:编写延迟函数的方式

#include 
#include 

void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);

}



void main(){
	  while(1){// 循环实现led灯的亮灭情况
		    P1 = 0xFE;
		  	Delay500ms();// 函数的调用
				P1 = 0xFF;
				Delay500ms();
		}
}

led的流水灯显示 

#include 
#include 

void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);

}



void main(){
	  while(1){// 循环实现led灯的亮灭情况
		    P1 = 0xFE; // 1111 1110
		  	Delay500ms();
				P1 = 0xFD; // 1111 1101
				Delay500ms();
				P1 = 0xFB; // 1111 1011
		  	Delay500ms();
				P1 = 0xF7; // 1111 0111
				Delay500ms();
				P1 = 0xEF; // 1110 1111
		  	Delay500ms();
				P1 = 0xDF; // 1101 1111
				Delay500ms();
				P1 = 0xBE; // 1011 1111
		  	Delay500ms();
				P1 = 0x7F; // 0111 1111
				Delay500ms();
		}
}

使用函数实现200毫秒轮动的流水灯

#include 
#include 

void Delay500ms(unsigned int xms)		//@11.0592MHz 单片机的系统中int 表示的是16位的,在计算机中是32位或者是64位的
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}

void main(){
	  

	  while(1){
				// 循环实现led灯的亮灭情况
		    P1 = 0xFE; // 1111 1110
		  	Delay500ms(200); // 自定义200毫秒
				P1 = 0xFD; // 1111 1101
				Delay500ms(200);
				P1 = 0xFB; // 1111 1011
		  	Delay500ms(200);
				P1 = 0xF7; // 1111 0111
				Delay500ms(200);
				P1 = 0xEF; // 1110 1111
		  	Delay500ms(200);
				P1 = 0xDF; // 1101 1111
				Delay500ms(200);
				P1 = 0xBE; // 1011 1111
		  	Delay500ms(200);
				P1 = 0x7F; // 0111 1111
				Delay500ms(200);
		}

}

第二章独立按键

2.1独立按键介绍

51单片机学习总结(自学)_第13张图片

独立按键原理图

51单片机学习总结(自学)_第14张图片

2.2独立按键控制led亮灭同时使用延时的方式防止抖动的出现

51单片机学习总结(自学)_第15张图片

#include 
#include 

void Delay500ms(unsigned int xms)		//@11.0592MHz 单片机的系统中int 表示的是16位的,在计算机中是32位或者是64位的
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}
void main(){
	  while(1){
			 if(P3_0 == 0){
					P1_0 = 0;
				  Delay500ms(500);
			 }else{
					P1_0 = 1;
				  Delay500ms(500);
			 }
       
		}
}

每次按下一次led取反显示:独立按键控制LED显示二进制(也就是按位取反)

#include 
#include 

void Delay500ms(unsigned int xms)		//@11.0592MHz 单片机的系统中int 表示的是16位的,在计算机中是32位或者是64位的
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}
// P3_0 表示的是第一个独立按键 
// P1_0 表示的是第一个led灯
void main(){
	  unsigned char LEDNum = 0;
	  while(1){
			 if(P3_1 == 0){
				  Delay500ms(20);
				  while(P3_1 == 0);
					Delay500ms(20);
				  LEDNum++;
				  P1 = ~LEDNum; 
			 }
       

		}

}

独立按键控制LED的移位

#include 
#include 

void Delay(unsigned int xms)		//@11.0592MHz 单片机的系统中int 表示的是16位的,在计算机中是32位或者是64位的
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}
// P3_0 表示的是第一个独立按键 
// P1_0 表示的是第一个led灯
void main(){
	  unsigned char LEDNum =0;
    // 独立按键代码移位的实现
	  P1 = ~0x01;
	  while(1){
			  if(P3_1 == 0){
				Delay(20);
			  // 检测是否松手
			  while(P3_1 == 0);
			  Delay(20);
			  LEDNum++;
			  if(LEDNum >= 8){
				    LEDNum = 0;
				}
				P1 = ~(0x01 << LEDNum);
		   }
		}

}

单片机LED灯使用独立按键控制led灯左右移动

#include 
#include 

void Delay(unsigned int xms)		//@11.0592MHz 单片机的系统中int 表示的是16位的,在计算机中是32位或者是64位的
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}
// P3_0 表示的是第一个独立按键 
// P1_0 表示的是第一个led灯
void main(){
	  unsigned char LEDNum =0;
    // 独立按键代码移位的实现
	  P1 = ~0x01;
	  while(1){
			  if(P3_1 == 0){
				Delay(20);
			  // 检测是否松手
			  while(P3_1 == 0);
			  Delay(20);
			  LEDNum++;
			  if(LEDNum >= 8){
				    LEDNum = 0;
				}
			 P1 = ~(0x01 << LEDNum);
		   }
			 if(P3_0 == 0){
				Delay(20);
			  // 检测是否松手
			  while(P3_0 == 0);
			  Delay(20);
				if(LEDNum == 0){
						LEDNum = 7;
				}else{
						LEDNum--;
				}			  			
				P1 = ~(0x01 << LEDNum);
		   }
		}

}

第三章:数码管

数码管原理图

51单片机学习总结(自学)_第16张图片

数码管的应用场景

51单片机学习总结(自学)_第17张图片

单个数码管共阴极数码管需要给正集高电平1点亮

51单片机学习总结(自学)_第18张图片

数码管分为共阳极和共阴极数码管

四位数码管

51单片机学习总结(自学)_第19张图片

数码管锁存器的概念很重要74H573锁存芯片的工作原理

OE上面加一行表示的是低电平有效,如果是高电平的话不能正常的进行数据的存储和锁存

双向数据缓冲器(74HC245):作用是提高驱动能力(内部置有电源)。

OE通常表示"Output Enable",也可以称为输出使能。

LE通常表示"Latch Enable",也可以称为锁存使能。

OE(使能,接地时工作);

DIR(direction,控制A到B,或者B到A);

锁存芯片的原理图

当输出使能为低电平,锁存使能为高电平时,能让锁存器的两端连通可以正常的将输入的数据存储到晶体管中,当锁存使能为低电平时数据锁存保存的是之前输入的数据,后面无论如何修改数据都晶体管的显示也不会发生改变(也就是晶体管显示的还是上次显示的数据这个就是数据的锁存)

51单片机学习总结(自学)_第20张图片

上拉电阻的作用:开漏状态表示的是可以输出低电平可以输出高电平

数码管的静态显示和锁存器的应用

数码管的静态显示案例一

#include 
#include 
sbit wei = P2^7; 		// 位选择器
sbit duan = P2^6;   // 段选择器
unsigned char leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义

                         };

void Delay(unsigned int xms)		
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
}

void main(){
			// 打开锁存器
			duan = 1; 
			// 段选控制数码管显示什么值
			P0 = leddata[8];
			// 关闭锁存器
			duan = 0;	
			// 延迟函数
			Delay(5);
	

	    // 共阴极数码管加0的时候未选通
			// 打开位选择器
			wei = 1;
			// 数码管全部点亮
			P0 = 0;
			// 关闭段选择器
			wei = 0;
			while(1){
				 
			}
}

数码管的静态显示案例二

#include 
#include "main.h"
#include 
#define unit unsigned int
#define uchar unsigned char 
	
sbit  beep = P2^3;
sbit wei  = P2^7; 		// 位选择器
sbit duan = P2^6;     // 段选择器

void main(){
	  // 打开位锁存器
    wei = 1;
	  P0 = 0xfe; // 高电平的16进制位0x06
	  //关闭位锁存器
	  wei = 0;
	  Delay(500);
	  // 打开段选择器
	  duan = 1;
	  P0 =0x06;
	  // 关闭段选择器
	  duan = 0;
	  // 延迟函数500毫秒
	  Delay(500);
	  // while循环一直循环条件为true
	  while(1){
		  

		}

}

练习:明白数码管的显示原理,是让数码管从0显示到9中间延时500毫秒。

#include 
#include 
#include "Util.h"
// 初始化数组
unsigned char leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x00  //自定义
 };
void main(){
	   // 使用for循环遍历数组
	   int i = 0;
	   // 计算数组的长度
	   int len = sizeof(leddata)/sizeof(leddata[0]);
	   for(i = 0; i< len; i++){
		         // 打开断选择器
			 duan = 1;
			 P0 = leddata[i];
			 duan = 0;
			 Delay(500);
			 // 打开位选择器
			 wei = 1;
			 P0 = 0;
			 wei = 0;	
		 }

}

数码管的动态显示

数码管动态显示1-4

#include 
#include 
#include "Util.h"
// 初始化数组
unsigned char leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x00  //自定义
 };


void main(){ 
            // 第一位数码管
              wei = 1;
              P0 = 0xfe;
              wei = 0;
              duan = 1;
              P0 = leddata[1];
              duan = 0;
            Delay(500);
              // 第二位数码管
              wei = 1;
              P0 = 0xfd;
              wei = 0;
              duan = 1;
              P0 = leddata[2];
              duan = 0;
              Delay(500);
                // 第三位数码管
              wei = 1;
              P0 = 0xfb;
              wei = 0;
              duan = 1;
              P0 = leddata[3];
              duan = 0;
                Delay(500);
              // 第四位数码管
              wei = 1;
              P0 = 0xf7;// 11110111
              wei = 0;
              duan = 1;
              P0 = leddata[4];
              duan = 0;
                Delay(500);
	  
	
}

第四章:定时器和计数器

定时器和计数器:两个功能既可以定时也可以计数,但是每次使用只能使用一个

使用定时器和计数器的使用步骤

  • 1:启动
  • 2:机器周期
  • 3:初值寄存器
  • 4:每经过一个及其周期自动加一
  • 5:溢出

第五章:蜂鸣器

51单片机学习总结(自学)_第21张图片

蜂鸣器的工作原理 :通过电流的通断来实现,在电流的一通一断之间实现蜂鸣器的功能发出声音

51单片机学习总结(自学)_第22张图片

蜂鸣器的原理图:给I/0口一个逻辑0那么E级别和B级别的时候就会导通蜂鸣器就会工作反之就不会工作

51单片机学习总结(自学)_第23张图片

这个用一个简单的图进行描述就是

51单片机学习总结(自学)_第24张图片

51单片机学习总结(自学)_第25张图片

单片机的上拉电阻单片机IO空的电压是很小的无法直接驱动设备工作,单片机不是功率器件只适合做控制用不适合驱动功率器件

三极管的工作原理

51单片机学习总结(自学)_第26张图片

蜂鸣器代码的实现(这里使用模块化编程的方式让代码更加的简洁)

void Delay(unsigned int xms)		//@11.0592MHz 单片机的系统中int 表示的是16位的,在计算机中是32位或者是64位的
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}

蜂鸣器函数头文件(主要运用的是模块化开发实现)

#ifndef __BEER_H_
#define __BEER_H_
void Delay(unsigned int xms);

#endif

主程序代码

#include 
#include "main.h"
#include 
#define unit unsigned int
#define uchar unsigned char 
	
sbit  beep = P2^3;
void main(){
    int temp;
	  temp = 0xf0;
	  P1 = temp;
	  Delay(500);
	  while(1){
		   temp = _crol_(temp,1);
			 P1 = temp;
			// 在低电平和高电平之间来回的切换发出声音
			 beep = ~beep;
			 Delay(500);
		}
}

第六章:矩阵键盘

51单片机学习总结(自学)_第27张图片

51单片机学习总结(自学)_第28张图片

51单片机学习总结(自学)_第29张图片

51单片机学习总结(自学)_第30张图片

矩阵键盘和独立键盘的原理图

51单片机学习总结(自学)_第31张图片

矩阵键盘使用的是并行的IO口,独立键盘使用的是单个的IO口

51单片机学习总结(自学)_第32张图片

读取通过的电压:当按键按下的IO口会的电平会被拉低,当检测到电压为0V的时候判断键盘被按下,当我们的手松开的时候检测键盘没有按下电平回到5V。

按键的抖动问题:需要在段选的后面加延时

51单片机学习总结(自学)_第33张图片

6.1按单片机第一个按键实现数字自加效果,按第二个按键的时候实现数字自减效果

#include 
#include "main.h"
#include 
#define unit unsigned int
#define uchar unsigned char 
sbit  beep = P2^3;
sbit wei  = P2^7; 		// 位选择器
sbit duan = P2^6;     // 段选择器
sbit key_S2 = P3^0;   // P30的IO口独立按键S2
sbit key_S3 = P3^1;   // 第二个独立按键
uchar number;
//数组的定义
unsigned char code leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x00  //自定义
 };
// 功能函数
void diaplay(uchar i){
					uchar bai,shi,ge;
	        // 计算个位10位和百位
	        bai = i / 100; // 211 /100 = 2
	        shi = i % 100 / 10; // 211 % 100 / 10 = 1;
	        ge  = i % 10; // 211 % 10				
}
void main(){
					// 打开位锁存器
					wei = 1;
					P0 = 0xFE; // 高电平的16进制位0x06
					//关闭位锁存器
					wei = 0;
				  while(1){				
						if(key_S2 == 0){
							 	Delay(20);	// 按键抖动的消除
								if(key_S2 == 0){
									number++;
									if(number == 10){
									  number = 0;
										duan = 1;
										P0 = leddata[number]; 
										duan = 0;
									}
									// 添加松手检测
								  while(!key_S2){
										  

								  }
								}		
							}
						  // 按独立按键相减的代码
						if(key_S3 == 0){
							 	Delay(20);	// 按键抖动的消除
								if(key_S3 == 0){
									if(number > 0){
											number--;
									}
									while(!key_S3);
									
								}		
							}
							
						  //松手之后刷新显示
							duan = 1;
							P0 = leddata[number]; 
							duan = 0; // 锁存段选数据				
		}
}

矩阵键盘的识别

51单片机学习总结(自学)_第34张图片

矩阵键盘与独立键盘的识别和扫描

矩阵键盘二进制取值原理图

51单片机学习总结(自学)_第35张图片

6.2矩阵键盘和独立键盘的扫描代码,每当按下对应的按钮晶体管显示对应按钮的数值

#include 
#include "main.h"
#include 
#define unit unsigned int
#define uchar unsigned char 
sbit wei  = P2^7; 		// 位选择器
sbit duan = P2^6;     // 段选择器
uchar number;
uchar KeyValue;

unsigned char code leddata[]={          
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义          
 };
// 键盘的列扫描
void ketScan(){
	 /*
	   4*4键盘的扫描
	 */
	 
	
	
   P3 = 0xF0;
	 if(P3 != 0xF0){ // 判断键盘是否被按下
	     Delay(10);  // 软件消除抖动
       if(P3 != 0xF0){ // 列扫描
			    switch(P3){
						case 0xE0:
							KeyValue = 0; // 表示的是第一列被按下
						   break;
						case 0xD0:
							KeyValue = 1; // 表示的是第二例被按下
						   break;
						case 0xB0:
							KeyValue = 2; // 表示的是第三列被按下
						   break;
						case 0x70:
							KeyValue = 3; // 表示的是第四列被按下
						   break;		 
					}
					P3 = 0X0f;// 行扫描
					switch(P3){
						case 0x0e:
							KeyValue = KeyValue; // 表示的是第一行被按下
						   break;
						case 0x0D:
							KeyValue = KeyValue + 4; //  表示的是第二行被按下
						   break;
						case 0x0b:
							KeyValue = KeyValue + 8; // 表示的是第三行被按下
						   break;
						case 0x07:
							KeyValue = KeyValue + 12; // 表示的是第四行被按下
						   break;		 
					}
					// 松手检测
				while(P3 != 0X0f){
				  
				}
			 }		 
		 
	 }
	 // 独立按键键盘的扫描
	 P3 = 0XFF;
	 if(P3 != 0xff){
	    Delay(10); // 软件消抖
		  switch(P3){
				case 0xfe:
							KeyValue = 16; // 表示的是S2被按下
						   break;
						case 0xfD:
							KeyValue = 17; //  表示的是S3被按下
						   break;
						case 0xfb:
							KeyValue = 18; // 表示的是S4被按下
						   break;
						case 0xf7:
							KeyValue = 19; // 表示的是S5被按下
						   break;		 
			}
			while(P3 != 0xff); // 默认会回到最后的值
		  
	 }
	 
}
void main(){
					// 打开位锁存器
					wei = 1;
					// 高电平的16进制位0x06
					P0 = 0xFE; 
					//关闭位锁存器
					wei = 0;
	
	        while(1){
						ketScan(); // 调用键盘扫描函数
					  duan = 1;
						P0 = leddata[KeyValue]; // 显示按键的值
						duan = 0;
					}

}

第七章:8*8点阵屏

7.1点阵屏理论基础

51单片机学习总结(自学)_第36张图片

8*8点阵屏电路图

51单片机学习总结(自学)_第37张图片

如何赋值点亮led灯:要使用动态扫描的方式点亮led灯防止出现同时点亮的情况

51单片机学习总结(自学)_第38张图片

7.2:74HC595芯片的工作原理

51单片机学习总结(自学)_第39张图片

51单片机学习总结(自学)_第40张图片

51单片机学习总结(自学)_第41张图片

8*8点阵屏原理图

51单片机学习总结(自学)_第42张图片

7.3:74HC595芯片使用说明

7.4:点阵屏编程实战:点亮第一个点阵

#include 
sbit DIO = P3^4; // 串行数据口
sbit S_CLK = P3^5; //移位寄存器时钟
sbit R_CLK = P3^6; // 输出锁存器时钟

void main(){
	// ROW : 0x80 ,COL : 0xfe 通过传入和并出的方式将数据发送出去
	unsigned char i,dat;
	dat = 0xfe;
	for(i = 0; i<8;i++){
			S_CLK = 0;
	   	R_CLK = 0;
		  if(dat & 0x01){
			   DIO = 1;
			}else{
			   DIO = 0;
			}
			S_CLK = 1;	
			dat >>= 1;
	}
	

	dat = 0x80;
	for(i = 0; i<8;i++){
			S_CLK = 0;
	   	R_CLK = 0;
		  if(dat & 0x01){
			   DIO = 1;
			}else{
			   DIO = 0;
			}
			S_CLK = 1;		
			dat >>= 1;
	}
	R_CLK = 1;
	while(1);

}

点阵屏实战:显示汉字-->电 字符

#include 
#include 

sbit DIO = P3^4; // 串行数据口
sbit S_CLK = P3^5; //移位寄存器时钟
sbit R_CLK = P3^6; // 输出锁存器时钟

/*
		取模软件生成的自形码:0xef 0x01 0x6d 0x01 0x6d 0x01 0xee 0xe0 --> 电
*/
unsigned char code table[] = {
   0xe0, 0xee, 0x01, 0x6d, 0x01, 0x6d, 0x01, 0xef
};

void Send_Byte(unsigned char dat){
	  unsigned char i;
	  S_CLK = 0;
		R_CLK = 0;
		for(i = 0; i<8;i++){
				if(dat & 0x01){
					 DIO = 1;
				}else{
					 DIO = 0;
				}
				S_CLK = 1;	
				dat >>= 1;
				S_CLK = 0;
	  }
}

void main(){
	// ROW : 0x80 ,COL : 0xfe 通过传入和并出的方式将数据发送出去
	unsigned char j,ROW;
	while(1){
		  ROW = 0X80;
	    for(j = 0; j < 8; j++){
					Send_Byte(table[j]);
					Send_Byte(ROW);
					R_CLK = 1;
					ROW = _cror_(ROW,1); // 循环右移动
					R_CLK = 0;
			}
	}
}

显示电子两个数字的循环显示

#include 
#include 

sbit DIO = P3^4; // 串行数据口
sbit S_CLK = P3^5; //移位寄存器时钟
sbit R_CLK = P3^6; // 输出锁存器时钟

/*
		取模软件生成的自形码:0xef 0x01 0x6d 0x01 0x6d 0x01 0xee 0xe0 --> 电
*/
unsigned char code table[2][8] = {
   0xe0, 0xee, 0x01, 0x6d, 0x01, 0x6d, 0x01, 0xef,
	 0xe7, 0xe7, 0xe7, 0xe7, 0x80, 0xf7, 0xfb, 0xc3
};

void Send_Byte(unsigned char dat){
	  unsigned char i;
	  S_CLK = 0;
		R_CLK = 0;
		for(i = 0; i<8;i++){
				if(dat & 0x01){
					 DIO = 1;
				}else{
					 DIO = 0;
				}
				S_CLK = 1;	
				dat >>= 1;
				S_CLK = 0;
	  }
}

void main(){
	// ROW : 0x80 ,COL : 0xfe 通过传入和并出的方式将数据发送出去
	unsigned char j,k,ROW;
	unsigned int z;
	while(1){
		  for(k=0;k<2;k++){
				      for(z = 0; z <1000; z++){
							    ROW = 0X80;
							    for(j = 0; j < 8; j++){
											Send_Byte(table[k][j]);
											Send_Byte(ROW);
											R_CLK = 1;
											ROW = _cror_(ROW,1); // 循环右移动
											R_CLK = 0;
									}
							}
			   		 

			}
	
	}

}

第八章:中断系统

IO引脚

51单片机学习总结(自学)_第43张图片

中断系统的解释

51单片机学习总结(自学)_第44张图片

51单片机学习总结(自学)_第45张图片

51系列允许的5个中断源

51单片机学习总结(自学)_第46张图片

51单片机学习总结(自学)_第47张图片

51单片机学习总结(自学)_第48张图片

51单片机学习总结(自学)_第49张图片

外部中断案例

#include 
#include 

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;
sbit WE = P2^7;
sbit key_s2 = P3^0;
sbit flag = P3^7;// 外部中断信号产生脚
uchar num;
// 延时函数定义
void Delay(unsigned int xms)		
{
	unsigned char i, j;
  while(xms){
		i = 2;
		j = 239;
		do{
		   while(--j);
		}while(--i);
	  xms--;
	}
	
}

// 外部中断函数:外部中断1初始化
void initInterrupt(){
      EA  = 1; // 开启总中断
	    EX1 = 1; // 开外部中断1
	    IT1 = 1; // 开外部中断1下降沿触发
}
// 外部中断1服务函数
void initUtil() interrupt 2{
     P1 = ~P1;
}


// 程序主函数
void main(){
	  initInterrupt(); // 外部中断1初始化
    while(1){
		   if(key_s2 == 0){
			    Delay(20);
				  if(key_s2 == 0){
						 // 通过flag的操作产生下降沿
						 flag = 1;
						 flag = 0;
						 while(!key_s2);
					}
			 }
		}

}

计数器...

持续更新中......

你可能感兴趣的:(51单片机,学习,嵌入式硬件)