51单片机学习总结doc.docx
《51单片机学习总结doc.docx》由会员分享,可在线阅读,更多相关《51单片机学习总结doc.docx(10页珍藏版)》请在冰点文库上搜索。
51单片机学习总结doc
51单片机学习总结
51单片机学习总结
1、什么是单片机
在一片集成电路芯片上集成微处理器、存储器、I/O接口电路,从而构成了单芯片微型计算机,即单片机。
Intel公司推出了MCS-51系列单片机:
集成8位CPU、4K字节ROM、128字节RAM、4个8位并口、1个全双工串行口、2个16位定时/计数器。
寻址范围64K,并有控制功能较强的布尔处理器。
2、单片机的作用
用到单片机的项目经验介绍手持粮库温度寻检设备毕设答辩打分器电话台灯
自动感应水龙头
凡是与控制或简单计算有关的电子设备都可以用单片机来实现,再根据具体实际情况选择不同性能的单片机,如:
atmel,stc,pic,avr,凌阳,80C51,arm等工业自动化:
数据采集、测控技术。
智能仪器仪表:
数字示波器、数字信号源、数字万用表、感应电流表等。
消费类电子产品:
洗衣机、电冰箱、空调机、电视机、微波炉、手机、IC卡、汽车电子设备等。
通讯方面:
调制解调器、程控交换技术、手机、小灵通等。
武器装备:
飞机、军舰、坦克、导弹、航天飞机、鱼雷制导、智能武器等。
等等…..
3、学习单片机之前预备知识
(1)数字电路中只有两种电平:
高和低定义单片机为TTL电平:
高+5V低0V
(2)RS232电平:
计算机的串口高-12V低+12V
所以计算机与单片机之间通讯时需要加电平转换芯片(3)进制转换与逻辑、算术运算(4)C语言基础(5)80C51了解
80C51是MCS-51系列中的一个典型品种;其它厂商以8051为基核开发出的CMOS工艺单片机产品统称为80C51系列。
(6)
总线(BUS)是计算机各部件之间传送信息的公共通道。
微机中有内部总线和外部总线两类。
内部总线是CPU内部之间的连线。
外部总线是指CPU与其它部件之间的连线。
外部总线有三种:
数据总线DB(DataBus),地址总线AB(AddressBus)和控制总线CBControlBus)。
(7)
CPU:
由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄存器;RAM:
用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示的数据;ROM:
用以存放程序、一些原始数据和表格;
I/O口:
四个8位并行I/O口,既可用作输入,也可用作输出;
T/C:
两个定时/记数器,既可以工作在定时模式,也可以工作在记数模式;五个中断源的中断控制系统;一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;
片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。
最高振荡频率取决于单片机型号及性能。
(8)
C51数据存储类型例:
数据类型变量名
charvar1;bitflags;
unsignedcharvextor[10];int;
注意:
变量名不能用C语言中的关键字表示。
(9)
包含的头文件(可以在安装目录下INC目录下查看)
通常有:
reg51.hreg52.hmath.hctype.hstdio.hstdlib.habsacc.h常用有:
reg51.hreg52.h
(定义特殊功能寄存器和位寄存器);math.h(定义常用数学运算);(10)中断服务程序的格式函数名()interruptnusingm{
函数内部实现….}
(11)I/O口定义sbitbeep=P2^3;
(12)单片机的基本时序机器周期和指令周期
(1)振荡周期:
也称时钟周期,是指为单片机提供时钟脉冲信号的振荡源的周期,TX实验板上为11.0592MHZ。
(2)状态周期:
每个状态周期为时钟周期的2倍,是振荡周期经二分频后得到的。
(3)机器周期:
一个机器周期包含6个状态周期S1~S6,也就是12个时钟周期。
在一个机器周期内,CPU可以完成一个独立的操作。
(4)指令周期:
它是指CPU完成一条操作所需的全部时间。
每条指令执行时间都是有一个或几个机器周期组成。
MCS-51系统中,有单周期指令、双周期指令和四周期指令。
4、学习单片机目标
最小系统能够运行起来的必要条件。
1.电源2.晶振3.复位电路对单片机任意IO口的随意操作1.输出控制电平高低2.输入检测电平高低。
定时器:
重点掌握最常用的方式2
中断:
外部中断、定时器中断、串口中断串口通信:
单片机之间、单片机与计算机间
扩展阅读:
51单片机串口通信学习总结
51单片机串口通信学习总结
1.近距离的单片机点对点通信:
如果两个51单片机系统之间的距离很短,可以通过将它
们的自带串口直接相连的方法实现双机通信,连接时注意要将一方的TXD和另一方的RXD引脚相连。
2.如果通信距离较远,可以利用RS-232C接口延长通信距离,但必须将单片机的TTL电
平和RS-232C标准电平进行转换,如常用的MAX232,。
内部结构基本可分三个部分:
第一部分是电荷泵电路。
由1、2、3、4、5、6脚和4只电容构成。
功能是产生+12v和-12v两个电源,提供给RS-232串口电平的需要。
第二部分是数据转换通道。
由7、8、9、10、11、12、13、14脚构成两个数据通道。
其中13脚(R1IN)、12脚(R1OUT)、11脚(T1IN)、14脚(T1OUT)为第一数据通道。
8脚(R2IN)、9脚(R2OUT)、10脚(T2IN)、7脚(T2OUT)为第二数据通道。
TTL/CMOS数据从T1IN、T2IN输入转换成RS-232数据从T1OUT、T2OUT送到电脑DB9插头;DB9插头的RS-232数据从R1IN、R2IN输入转换成TTL/CMOS数据后从R1OUT、R2OUT输出。
第三部分是供电。
15脚GND、16脚VCC(+5v)。
硬件电路设计:
注意:
怎样连线单片机与MAX232同名相对,RR,TT
MAX232与DB9异名相对,RT,TR
串口通信主要包括:
串口数据发送和接收。
发送实例:
/******************************************************作者:
淋哥电子
说明:
本程序实现串口数据发送,从0到10每隔500ms发送一次******************************************************/
#include//单片机52头文件,存放着单片机的寄存器#defineuintunsignedint//宏定义#defineucharunsignedchar
voiddelay_ms(ucharms);//声明一个ms级延时函数voidUART_Init(void);//声明串口初始化函数
voidUART_Send_Byte(ucharbyte);//声明串口发送单字节函数voidmain(void)//主函数{
uchari=0;//定义一个变量UART_Init();//串口初始化while
(1)//死循环{UART_Send_Byte(i);//串口发送单字节数据delay_ms(500);//延时500msif(++i>10)//i自加到10清0i=0;}}
//定义delay_ms函数voiddelay_ms(ucharms){uchari;while(ms--){for(i=0;i
接收实例:
1)
/******************************************************作者:
淋哥电子
说明:
本程序实现串口数据接收(查询法)单片机晶振11.0592M
******************************************************/
#include//单片机52头文件,存放着单片机的寄存器#defineuintunsignedint//宏定义#defineucharunsignedchar
voidUART_Init(void);//声明串口初始化函数
voidUART_Send_Byte(ucharbyte);//声明串口发送单字节函数voidmain(void)//主函数{
uchari=0;//定义一个变量UART_Init();//串口初始化while
(1)//死循环{if(RI)//检测接收完成标志位置1{RI=0;//清零接收完成标志位i=SBUF;//读取接收到的数据UART_Send_Byte(i);//串口发送单字节数据}}}
//定义UART_Init函数voidUART_Init(void){SCON=0x50;//设定串行口工作方式,8位数据位,允许接收T2CON=0x34;//设置定时器2,作为波特率发生器RCAP2L=0XD9;//9600波特率的低8位RCAP2H=0XFF;//9600波特率的高8位}
//定义UART_Send_Byte函数voidUART_Send_Byte(ucharbyte){SBUF=byte;//缓冲区装载要发送的字节数据while(TI==0);//等待发送完毕,TI标志位会置1TI=0;//清零发送完成标志位}
2)
/******************************************************作者:
淋哥电子
说明:
本程序实现串口数据接收(中断法)单片机晶振11.0592M
******************************************************/
#include//单片机52头文件,存放着单片机的寄存器#defineuintunsignedint//宏定义#defineucharunsignedchar
voidUART_Init(void);//声明串口初始化函数
voidUART_Send_Byte(ucharbyte);//声明串口发送单字节函数voidmain(void)//主函数{UART_Init();//串口初始化while
(1)//死循环{}}
//定义UART_Init函数voidUART_Init(void){SCON=0x50;//设定串行口工作方式,8位数据位,允许接收T2CON=0x34;//设置定时器2,作为波特率发生器RCAP2L=0XD9;//9600波特率的低8位RCAP2H=0XFF;//9600波特率的高8位ES=1;//允许串口中断EA=1;//允许总中断}
//定义UART_Send_Byte函数voidUART_Send_Byte(ucharbyte){SBUF=byte;//缓冲区装载要发送的字节数据while(TI==0);//等待发送完毕,TI标志位会置1TI=0;//清零发送完成标志位}
uchari=0;//定义一个变量//串口中断服务程序
voidUART(void)interrupt4{if(RI)//检测接收完成标志位置1{RI=0;//清零接收完成标志位i=SBUF;//读取接收到的数据UART_Send_Byte(i);//串口发送单字节数据}}
重点说明:
51单片机可以通过SBUF寄存器对串行接收或发送寄存器进行访问,两个寄存器共用一个地址99H,但在物理上是两个独立的寄存器,有指令操作决定访问哪一个。
eg:
接收时,我们写“a=SBUF;”
发送时,我们写“SBUF=a;”
实例一:
/******************************************************作者:
淋哥电子
说明:
本程序实现在上位机上用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“IgetX”单片机晶振11.0592M
******************************************************/
#include//单片机52头文件,存放着单片机的寄存器#defineuintunsignedint//宏定义#defineucharunsignedcharucharuart_flag,a,i;
ucharcodetable[]={"Iget"};
voidUART_Init(void);//声明串口初始化函数
voidUART_Send_Byte(ucharbyte);//声明串口发送单字节函数voidmain(void)//主函数{UART_Init();//串口初始化while
(1)//死循环{if(uart_flag==1)//接收到{ES=0;//关串口中断for(i=0;iUART_Send_Byte(a);//发送接收到的字符ES=1;//允许串口中断uart_flag=0;//中断标志位置0}}}
//定义UART_Init函数voidUART_Init(void){SCON=0x50;//设定串行口工作方式,8位数据位,允许接收T2CON=0x34;//设置定时器2,作为波特率发生器RCAP2L=0XDC;//9600波特率的低8位RCAP2H=0XFF;//9600波特率的高8位ES=1;//允许串口中断EA=1;//允许总中断}
//定义UART_Send_Byte函数voidUART_Send_Byte(ucharbyte){SBUF=byte;//缓冲区装载要发送的字节数据while(TI==0);//等待发送完毕,TI标志位会置1TI=0;//清零发送完成标志位}
//串口接收中断服务程序voidUART(void)interrupt4{if(RI)//检测接收完成标志位置1{RI=0;//清零接收完成标志位a=SBUF;//读取接收到的数据uart_flag=1;//中断标志位置1}}
实例二:
/***********************************************************************************************************
作者:
淋哥电子说明:
本程序实现:
单片机上电后等待从上位机串口发送来的命令,当收到上位机以十六进制发送来的01后,向上位机发送字符串“Turnonad!
”同时在数码管以每秒刷新显示AD值
当收到上位机以十六进制发送来的02后,向上位机发送字符串“TurnoffAD!
”当收到上位机发送来的其他任何数据,向上位机发送字符串“Error!
!
”单片机晶振11.0592
***********************************************************************************************************/
#include//单片机51头文件,存放着单片机的寄存器#include//为了使用空指令加载的头文件#include
#defineucharunsignedchar#defineuintunsignedint
sbitsmg1=P2^6;//数码管位选sbitsmg2=P2^5;//数码管位选sbitsmg3=P2^4;//数码管位选
ucharflag_uart;//串口中断标志ucharflag_time;//1s钟标志ucharflag_on;//AD运行标志uchara;uchari;
uchart0_num;//T050ms定时标志
ucharad_val;//AD采集得到的值(二进制表示)floatad_vo;//实际电压标准值
unsignedcharcodetable[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管段选显示0--9
sbitcs=P3^3;////ad的cs控制管脚定义sbitwr=P3^5;//ad的wr控制管脚定义sbitrd=P3^4;//ad的rd控制管脚定义
voiddelay(uintcount)//delay{
uinti;
while(count){
i=200;while(i>0)i--;count--;}}
voidinit(void){TMOD=0x21;//定计0工作方式1,定计1工作方式2TH0=(65536-50000)/256;//定计0赋初值TL0=(65536-50000)%256;TH1=0XFD;//定计1赋初值TL1=0XFD;TR1=1;//开定计1ET0=1;//开定计0中断SCON=0X50;//串口控制寄存器:
SM0=0,SM1=1,REN=1EA=1;//开总中断ES=1;//开串口中断}
/*************读AD0804子程序*******************************/unsignedcharadc0804(void)//读AD0804子程序{unsignedcharaddata,i;rd=1;wr=1;//int1=1;//读ADC0804前准备P1=0xff;//P1全部置一准备cs=0;wr=0;wr=1;//启动ADC0804开始测电压rd=0;//开始读转换后数据i=i;i=i;//无意义语句,用于延时等待ADC0804读数完毕addata=P1;//读出的数据赋与addaterd=1;cs=1;//读数完毕return(addata);//返回最后读出的数据}
/*************数码管显示程序*******************************/voiddisplay(inttemp){
/****************************************************/smg3=1;smg2=1;delay
(1);
P0=table[temp/100];//显示百位smg1=0;delay
(1);smg1=1;
/****************************************************/
smg3=1;
P0=table[temp%100/10];//显示十位smg2=0;delay
(1);smg2=1;
/****************************************************/smg1=1;
P0=table[temp%10];//显示个位smg3=0;delay
(1);smg3=1;
/****************************************************/}
/*************主程序*******************************/voidmain(void){init();//初始化while
(1){if(flag_uart==1)//接收到数据{flag_uart=0;//串口中断标志置0ES=0;//关串口中断,若不关闭,每发送一个字节,程序就会申请进入串口中断,从而导致程序出错
TI=1;//发送标志置1switch(flag_on){case0:
puts("TurnonAD!
");TR0=1;break;case1:
puts("TurnoffAD!
");TR0=0;break;case2:
puts("Error!
");break;default:
break;}while(!
TI);//等待发送完毕TI=0;//发送完毕,手动清ES=1;}if(flag_time==1){flag_time=0;ad_val=adc0804();//将AD采集回来的8位二进制数赋给ad_valad_vo=(float)ad_val*5.0/256.0;//以浮点数表示AD实际采集到的电压标准值
ES=0;TI=1;printf("Thevoltageis%fV\\n",ad_vo);while(!
TI);TI=0;ES=1;}display(ad_val);}}
/*************定计0中断服务子程序*******************************/voidtimer0(void)interrupt1{TH0=(65536-50000)/256;//定计0重装初值TL0=(65536-50000)%256;t0_num++;if(t0_num==20){t0_num=0;flag_time=1;}}
/*************串口中断服务子程序*******************************/voidser(void)interrupt4{RI=0;//清零接收完成标志位a=SBUF;//读取接收到的数据flag_uart=1;//串口中断标志位置1if(a==1)flag_on=0;elseif(a==2)flag_on=1;elseflag_on=2;}
说明:
printf()和puts()的区别:
1)puts()自带换行符;
2)printf()可以在后面追加要输出的变量,而puts()只能输出字符串
友情提示:
本文中关于《51单片机学习总结》给出的范例仅供您参考拓展思维使用,51单片机学习总结:
该篇文章建议您自主创作。