ToB企服应用市场:ToB评测及商务社交产业平台

标题: 单片机学习笔记——入门51单片机 [打印本页]

作者: 用户国营    时间: 2024-7-16 21:33
标题: 单片机学习笔记——入门51单片机
一、单片机基础先容

1.何为单片机

单片机,英文Micro Controller Unit,简称MCU 。内部集成了中央处理器CPU、随机存储器ROM、只读存储器RAM、定时器/盘算器、中断系统和IO口等一系列电脑的常用硬件功能 单片机的使命是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(比方电机,LED等)的控制 。单片机跟盘算机相比,单片机算是一个袖珍版盘算机,一个芯片就能构成完整的盘算机系统。但在性能上,与盘算机相差甚远,但单片机资本低、体积小、布局简单,在生存和工业控制领域大有所用。 同时,学习利用单片机是了解盘算机原理与布局的最佳选择。
单片机工作的基本时序
我们都知道在学校是通过铃声来控制所有班级的上下课时间,我们都知道单片机实验指令的过程就是从ROM取出一条指令实验来完成它在各个地方的作用,那它什么时间取指令这个是次序呢?这里引入一个时序的周期,每访问一次ROM的时间,就是一个机器周期的时间
1个机器周期 = 6个状态周期 = 12个时钟(振荡)周期  
时钟周期:即单片机的基本时间单位,若晶体的频率=12MHZ,那时钟周期 = 1/12MHZ,一个时钟周期 = 1/12MHZ = 1/12000 000每秒
机器周期:即12x1/12 000 000 =0.000001s = 1us,访问一次ROM取指令的时间就是1us
2.单片机命名规则


3.单片机内部布局


重点需记:单片机管脚
1.电源:Vcc:正极     Gnd:负极             2.XTAL:单片机时钟引脚,外接晶振
3.RST:复位


4.开发板先容


开发板原理图


二、单片机的一些基础项目

2-1、点亮一个led灯

  1. #include <REGX52.H>
  2. void main()
  3. {
  4.         P2=0x7f;//1111 1110  d1   16 15
  5.                 //0111 1111  d8    7 16
  6.                 //1011 1111  d7   11 16
  7.        
  8.        
  9. }
复制代码
通过高低电平控制led亮否
2-2、led闪灼

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. //延时函数
  4. void Delay500ms()                //@11.0592MHz
  5. {
  6.         unsigned char i, j, k;
  7.         _nop_();
  8.         i = 4;
  9.         j = 129;
  10.         k = 119;
  11.         do
  12.         {
  13.                 do
  14.                 {
  15.                         while (--k);
  16.                 } while (--j);
  17.         } while (--i);
  18. }
  19. void main()
  20. {
  21.         while(1){
  22.         P2=0xfe;//亮
  23. Delay500ms();//延时500ms
  24.         P2=0xff;//灭
  25. Delay500ms();//延时500ms
  26.         }
  27. }
复制代码
通过延时函数使led闪灼
2-3、流水灯

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. void Delay500ms()                //@11.0592MHz
  4. {
  5.         unsigned char i, j, k;
  6.         _nop_();
  7.         i = 4;
  8.         j = 129;
  9.         k = 119;
  10.         do
  11.         {
  12.                 do
  13.                 {
  14.                         while (--k);
  15.                 } while (--j);
  16.         } while (--i);
  17. }
  18. void main()
  19. {
  20.         while(1){
  21.         P2=0xfe;//1111 1110
  22. Delay500ms();
  23.         P2=0xfd;//1111 1101
  24. Delay500ms();
  25.                 P2=0xfb;//1111 1011
  26. Delay500ms();
  27.                 P2=0xf7;//1111 0111
  28. Delay500ms();
  29.                 P2=0xef;//1110 1111
  30. Delay500ms();
  31.                 P2=0xdf;//1101 1111
  32. Delay500ms();
  33.                 P2=0xbf;//1011 1111
  34. Delay500ms();
  35.                 P2=0x7f;//0111 1111
  36. Delay500ms();
  37.         }
  38. }
复制代码
位运算做法:
2-4、流水灯plus

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. //任意延时函数——1ms的延时函数执行x次循环
  4. void Delay1ms(unsigned int xms)                //@11.0592MHz
  5. {
  6.         unsigned char i, j;
  7.   while(xms)
  8.         {
  9.         _nop_();
  10.         i = 2;
  11.         j = 199;
  12.         do
  13.         {
  14.                 while (--j);
  15.         } while (--i);
  16.         xms--;}
  17. }
  18. void main()
  19. {
  20.         while(1){
  21.         P2=0xfe;//1111 1110
  22. Delay1ms(100);
  23.         P2=0xfd;//1111 1101
  24. Delay1ms(100);
  25.                 P2=0xfb;//1111 1011
  26. Delay1ms(100);
  27.                 P2=0xf7;//1111 0111
  28. Delay1ms(100);
  29.                 P2=0xef;//1110 1111
  30. Delay1ms(100);
  31.                 P2=0xdf;//1101 1111
  32. Delay1ms(100);
  33.                 P2=0xbf;//1011 1111
  34. Delay1ms(100);
  35.                 P2=0x7f;//0111 1111
  36. Delay1ms(100);
  37.         }
  38. }
复制代码
通过任意延时函数去简化步骤
3-1、通过独立按键控制led闪灼

  1. #include <REGX52.H>
  2. void main()
  3. {
  4.         while(1)
  5.         {
  6.                 if(P3_1==0)//低电平 按下按键接地为0
  7.                 {
  8.                         P2_0=0;//d1亮
  9.                 }
  10.                 else {
  11.                         P2_0=1;
  12.                 }
  13.         }
  14. }
复制代码
3-2、通过独立按键控制led状态

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. void Delay(unsigned int xms)                //@11.0592MHz
  4. {
  5.         unsigned char i, j;
  6. while(xms){
  7.         _nop_();
  8.         i = 2;
  9.         j = 199;
  10.         do
  11.         {
  12.                 while (--j);
  13.         } while (--i);
  14.         xms--;
  15. }
  16. }
  17. void main()
  18. {
  19.         while(1)
  20.         {
  21.                 if(P3_1==0)
  22.                 {
  23.                  Delay(20);//取消前摇
  24.                         while(P3_1==0);//判断何时松手
  25.                         Delay(20);//取消后摇
  26.                        
  27.                         P2_0=~P2_0;//按位取反
  28.         }
  29. }
  30. }
复制代码
取消按键时的抖动,使单片机稳定判定状态。按一次亮,按一次灭。
3-3、通过独立按键控制led完成二进制

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. void Delay(unsigned int xms)                //@11.0592MHz
  4. {
  5.         unsigned char i, j;
  6. while(xms){
  7.         _nop_();
  8.         i = 2;
  9.         j = 199;
  10.         do
  11.         {
  12.                 while (--j);
  13.         } while (--i);
  14.         xms--;
  15. }
  16. }
  17. void main()
  18. {
  19.         unsigned int lednum=0;
  20.         while(1)
  21.         {
  22.                 if(P3_1==0)
  23.                 {
  24.                         Delay(20);
  25.                         while(P3_1==0);
  26.                         Delay(20);
  27.                        
  28.                         lednum++;
  29.                         P2=~lednum;
  30.         }
  31. }
  32. }
复制代码
也可以直接用P2--;取代末了两句,完成二进制运算。
3-4、用独立按键控制led灯移位

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. void Delay(unsigned int xms)                //@11.0592MHz
  4. {
  5.         unsigned char i, j;
  6. while(xms){
  7.         _nop_();
  8.         i = 2;
  9.         j = 199;
  10.         do
  11.         {
  12.                 while (--j);
  13.         } while (--i);
  14.         xms--;
  15. }
  16. }
  17. void main()
  18. {
  19.         unsigned int lednum=0;
  20.         P2=~0x01;
  21.         while(1)
  22.         {
  23.                 if(P3_1==0)//k1
  24.                 {
  25.                         Delay(20);
  26.                         while(P3_1==0);
  27.                         Delay(20);
  28.                        
  29.                         lednum++;
  30.                         if(lednum>=8)
  31.                                 lednum=0;
  32.                         P2=~(0x01<<lednum);
  33.         }
  34.                 if(P3_0==0)//k2
  35.                 {
  36.                         Delay(20);
  37.                         while(P3_0==0);
  38.                         Delay(20);
  39.                        
  40.                        
  41.                         if(lednum==0)
  42.                                 lednum=7;
  43.                         else lednum--;
  44.                         P2=~(0x01<<lednum);
  45. }
  46. }
  47.         }
复制代码
4-1 静态数码管

1.常见数码管


2.控制数码管表现的原理图


3.管脚界说(对应字母控制对应位置亮):上面的为共阴极、下面的为共阳极(可以明白为3,8管脚处为供电,三角形尖尖有一横的是负极,所有共阴极),两个图中的数字为引脚:



4.下面为多个数码管,PCB板的4个为一体,同样上面为共阴极、下面为共阳极的原理图:


5.STC89C52实现数字表现

①原理图是共阴极(上面给0、下给1亮)


②138译码器:输入3(ABC,读的时间是从下读 C B A )个口,控制输出8个口,输出口连接共阴极的,是0还是1,在这里控制:使能端连接(按下图给1和0就可以用了)


通过CBA给数字0和1二进制转换10进制(得到数字几)就控制Y几,Y0头上“—”是表示低电平有效(即给0):

③双向缓冲,高电平往低电平送数据



CC2电容作用:滤波电容,稳定电源,确定电路稳定性,提高电路工作性能可靠运行;
RP4:排阻,限流,防止电流过大

④这里的P01......P07,就是用P0口,后面代码就是通过P0口控制灯的




只有Y5为0,其他Y0...Y7都为1;




读取次序都是从下到上


⑤代码控制公共端,从下往上写:



二进制101转换为1十进制为5,控制Y5,即公共端的LED6;


要表现下图的数字6


代码实现如下(P2控制共阴极,P0控制表现数字)及结果;




 ⑥优化操作代码:通过数组,子函数来优化代码

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
  4. void Nixie(unsigned char Location,Number)
  5. {
  6.         switch(Location)
  7.         {
  8.                 case 1:P2_4=1;P2_3=1;P2_2=1;break;
  9.                 case 2:P2_4=1;P2_3=1;P2_2=0;break;
  10.                 case 3:P2_4=1;P2_3=0;P2_2=1;break;
  11.                 case 4:P2_4=1;P2_3=0;P2_2=0;break;
  12.                 case 5:P2_4=0;P2_3=1;P2_2=1;break;
  13.                 case 6:P2_4=0;P2_3=1;P2_2=0;break;
  14.                 case 7:P2_4=0;P2_3=0;P2_2=1;break;
  15.                 case 8:P2_4=0;P2_3=0;P2_2=0;break;
  16.         }
  17.         P0=NixieTable[Number];
  18. }
  19. void main()
  20. {
  21.         Nixie(7,10);
  22.         while(1);
  23.         }
复制代码
要表现的数字对应的值


4-2、动态数码管 

  1. #include <REGX52.H>
  2. #include <INTRINS.H>
  3. unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
  4. void Delay (unsigned int xms)                //@11.0592MHz
  5. {
  6.         unsigned char i, j;
  7. while(xms--){
  8.         _nop_();
  9.         i = 2;
  10.         j = 199;
  11.         do
  12.         {
  13.                 while (--j);
  14.         } while (--i);
  15. }
  16. }
  17. void Nixie(unsigned char Location,Number)
  18. {
  19.         switch(Location)
  20.         {
  21.                 case 1:P2_4=1;P2_3=1;P2_2=1;break;
  22.                 case 2:P2_4=1;P2_3=1;P2_2=0;break;
  23.                 case 3:P2_4=1;P2_3=0;P2_2=1;break;
  24.                 case 4:P2_4=1;P2_3=0;P2_2=0;break;
  25.                 case 5:P2_4=0;P2_3=1;P2_2=1;break;
  26.                 case 6:P2_4=0;P2_3=1;P2_2=0;break;
  27.                 case 7:P2_4=0;P2_3=0;P2_2=1;break;
  28.                 case 8:P2_4=0;P2_3=0;P2_2=0;break;
  29.         }
  30.         P0=NixieTable[Number];
  31.         Delay(1);//保证亮度
  32.   P0=0x00;//清零
  33. }
  34. void main()
  35. {
  36.         while(1){
  37.         Nixie(2,1);
  38. // Delay(20);
  39.         Nixie(3,2);
  40. // Delay(20);
  41.         Nixie(4,3);
  42. //        Delay(20);
  43.         }
  44. }
复制代码

注释掉上面的延时调用,旁边的管会有些影响,需要消影,段选、位选影响造成串位,如下代码消除


了解



5-1、模块化编程 


1)驱动,先会用,后续有详细内容:



2)模块化,功能函数用点C文件写,点H文件声明函数,在main函数文件引入头文件直接调用:



3)注意事项



4)预编译



5)延时函数文件



6)头文件延迟



7)主函数文件步伐入口:



8)数码管模块,用到的头文件要引用:



9)数码管模块头文件



10)函数调用



11)表现




5-2 、LCD1602调试工具-------



1)调试工具原理图



2)模块化代码,下完放到自己工程目录下:




3)将下好的两个文件添加到工程:





4)文件重要内容如下:



5)main函数调用:



6)表现其他管脚辩论,所有会一起表现:



7)其他函数的调用及功能,可以设置表现位置和范围:



8)需要用到延迟函数:可以直接将前面模块化文件复制到工程目录下,添加进来引用即可;

9)娱乐:小计时器

  1. #include <REGX52.H>
  2. #include "LCD1602.h"
  3. #include "Delay.h"
  4. int Result=0;
  5. void main()
  6. {
  7.         LCD_Init();//初始化
  8.        
  9.         while(1)
  10.                 {
  11.                 Result++;
  12.                         Delay(1000);
  13.                         LCD_ShowNum(1,1,Result,3);
  14.                 }//计时器
复制代码

6-1.矩阵键盘

1)基础先容:



P14-P17给0就代表扫描,其他给1(没选中),一次只能扫描一行;P10-P13给0表示按下,给1表示没按下;(逐列扫描)


2.代码实现:

①:创建工程并把“Delay”与“LCD1602”的模块参加此工程中。

②:编写MatrixKey(矩阵)代码

  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. unsigned char MatrixKey()
  4. {
  5.         unsigned char KeyNumber=0;
  6.        
  7.         P1=0xff;      //按列扫描
  8.         P1_3=0;       //控制扫描的列
  9.         if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}    //while判断何时松手
  10.         if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
  11.         if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
  12.         if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
  13.        
  14.         P1=0xff;
  15.         P1_2=0;
  16.         if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
  17.         if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
  18.         if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
  19.         if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
  20.        
  21.         P1=0xff;
  22.         P1_1=0;
  23.         if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
  24.         if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
  25.         if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
  26.         if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
  27.        
  28.         P1=0xff;
  29.         P1_0=0;
  30.         if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
  31.         if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
  32.         if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
  33.         if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
  34.        
  35.        
  36.         return KeyNumber;
  37. }
  38.        
复制代码
③.编写主函数

  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. #include "LCD1602.h"
  4. #include "matrixKey.h"
  5. unsigned char KeyNum;
  6. void main()
  7. {
  8.         LCD_Init();   //LCD上电初始化
  9.         LCD_ShowString(1,1,"Helloworld");
  10.         while(1)
  11.         {
  12.                 KeyNum=MatrixKey();
  13.                 if(KeyNum){
  14.                         LCD_ShowNum(2,1,KeyNum,2);
  15.         }
  16. }
  17.         }
复制代码
④.软件利用小本领

快速天生常用格式代码:


设置,完成后双击就可以天生了:



6-2.矩阵键盘暗码锁

1):把6-1文件全部cv到6-2工程文件中

2):代码实现

  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. #include "LCD1602.h"
  4. #include "matrixKey.h"
  5. unsigned char KeyNum;
  6. unsigned int Password,count;
  7. void main()
  8. {
  9.         LCD_Init();
  10.         LCD_ShowString(1,1,"Helloworld");
  11.         while(1)
  12.         {
  13.                 KeyNum=MatrixKey();
  14.                 if(KeyNum){
  15.                         if(KeyNum<=10){                                  //s1~s10按下密码
  16.                                 if(count<4){
  17.                                 Password*=10;
  18.                                 Password+=KeyNum%10;       //这两句是用来实现四位密码的显示
  19.                                 count++;                 //计数  防止按下的密码数超过四位       
  20.                                 }
  21.                                 LCD_ShowNum(2,1,Password,4);//更新显示
  22.                         }
  23.                        
  24.                         if(KeyNum==11){    //s11设置为确认键
  25.                                 if(Password==2345){
  26.                                         LCD_ShowString(1,14,"OK ");
  27.                                         Password=0;  //密码清零
  28.                                         count=0;      //计数清零
  29.                                         LCD_ShowNum(2,1,Password,4);//更新显示
  30.                         }
  31.                                 else {LCD_ShowString(1,14,"ERR");
  32.                                         Password=0;  //密码清零
  33.                                         count=0;      //计数清零
  34.                                         LCD_ShowNum(2,1,Password,4);//更新显示
  35.                                 }
  36.         }
  37.                        
  38.            if(KeyNum==12){  //定义S12为取消键
  39.                          Password=0;
  40.                          count=0;
  41.                          LCD_ShowNum(2,1,Password,4);
  42.                  }
  43. }
  44.         }
  45. }
复制代码

7.定时器先容

1)先容,Delay前面CPU是一直在等的,用定时器在Delay时可以去检测按键,提高CPU利用率:















2)模式1最常用:



3)模式:时钟--计数最大65535(计数系统TL0\TH0:每来一个脉冲+1方法计数)-TF0(标记位,到最大了回到0)-中断:



4)非门与门图形为控制部分(TR0是否启动暂定)

5)定时器部分:



6)时钟可以由系统提供(上图,晶振),也可以由外部T0P提供(如下图引脚)



7)C/T,给1连上面为控制器,给0连接下面为定时器(如下图):



8)中断系统:



9)中断资源



10)定时器和中断系统



11)定时器相关寄存器





7-1.独立按键控制流水灯的模式

1.TMOD寄存器工作模式,定时器0配置利用(不可位寻址,只能整体赋值)



2.定时器模式1:门控端给0,就是tr0单独控制:C/T,T这里有一横表示低电平有效,就给0是用T(定时器模式),给1用C(控制器模式),M1,M0工作模式选择



3.TCON控制寄存器(可位寻址,可以单独每一位赋值)



中断溢出标记位:
TF=0(等于1产生中断);
TR0=1(定时器是否开启,给1开始,电机开始工作);
IE0、IT0:控制外部中断引脚,可以不配置

4.定时器配置  TH0\TL0




TH0\TL0 分开储存


代码优化,TMOD题目(不可位寻址)配置两个的时间,后面的会把前面的覆盖;
因此,可采用“与或”法设定TMOD



 


5.中断配置T0-->ET0=1--EA=1,PT0=0




6.定时器配置完成,模块化编程

  1. #include <REGX52.H>
  2. void Timer0_Init(void)                //1ms@11.0592MHz
  3. {
  4.         TMOD &= 0xF0;                //设置定时器模式
  5.         TMOD |= 0x01;                //设置定时器模式
  6.         TL0 = 0x66;                //设置定时器初值
  7.         TH0 = 0xFC;                //设置定时器初值
  8.         TF0 = 0;                //清除TF0标志
  9.         TR0 = 1;                //定时器0开始计时
  10.         ET0=1;    //下面三行为中断的配置
  11.         EA=1;
  12.         PT0=0;
  13. }
复制代码

 7.定时器中断函数模板

  1. void Timer0_Routine() interrupt 1  //中断函数
  2. {
  3.         static unsigned int T0Count;
  4.         TL0 = 0x66;                //设置定时器初值
  5.         TH0 = 0xFC;                //设置定时器初值
  6.         T0Count++;
  7.         if(T0Count>=1000)   //每隔1s
  8.         {               
  9.          T0Count=0;
  10.         }
  11. }
复制代码
8.独立按键模块

  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. unsigned char Key()
  4. {
  5.        
  6.         unsigned char KeyNumber=0;
  7.        
  8.         if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
  9.         if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
  10.         if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
  11.         if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
  12.        
  13.         return KeyNumber;
  14. }
复制代码
9.主函数

  1. #include <REGX52.H>
  2. #include "Timer0.h"
  3. #include "key.h"
  4. #include <INTRINS.H>
  5. unsigned char KeyNumber,LEDmode;
  6. void main()
  7. {
  8.         P2=0xfe;  //与INTRINS.H中的循环左右移函数共同实现流水灯
  9.         Timer0_Init(); //上电初始化
  10.         while(1)
  11.         {
  12.                 KeyNumber=Key();
  13.                 if(KeyNumber)
  14.                 {
  15.                         if(KeyNumber==1)
  16.                         {
  17.                                 LEDmode++;
  18.                                 if(LEDmode>=2) LEDmode=0;
  19.                         }
  20.                        
  21.                 }
  22.                
  23.         }
  24. }
  25. void Timer0_Routine() interrupt 1  //中断函数
  26. {
  27.         static unsigned int T0Count;
  28.         TH0=64535/256;
  29.         TL0=64535%256;        
  30.         T0Count++;
  31.         if(T0Count>=1000)   //每隔1s
  32.         {
  33.                 T0Count=0;
  34.          if(LEDmode==0) P2=_crol_(P2,1);
  35.          if(LEDmode==1) P2=_cror_(P2,1);
  36.         }
  37. }
复制代码




7-2.时钟 

1.把LCD1602液晶表现、延迟、定时器、的代码复制到工程目录下,导入;

2.主函数包含其他模块头文件并初始化;



3.复制定时器中断函数到main函数下:





4.界说变量,秒计数、分、小时并表现:



5.代码综合

  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. #include "LCD1602.h"
  4. #include "Timer0.h"
  5. unsigned char Sec,Min,Hour;
  6. void main()
  7. {
  8.         LCD_Init();//³õʼ»¯
  9.         Timer0_Init();
  10.         LCD_ShowString(1,1,"CLOCK:");
  11.         LCD_ShowString(2,1,"  :  :");
  12.         while(1)
  13.         {
  14.         LCD_ShowNum(2,1,Hour,2);
  15.         LCD_ShowNum(2,4,Min,2);
  16.         LCD_ShowNum(2,7,Sec,2);
  17.         }
  18. }
  19. void Timer0_Routine() interrupt 1  
  20. {
  21.         static unsigned int T0Count;
  22.         TL0 = 0x66;               
  23.         TH0 = 0xFC;               
  24.         T0Count++;
  25.         if(T0Count>=1000)   
  26.         {
  27.                 T0Count=0;
  28.     Sec++;
  29.                 if(Sec>=60)
  30.                 {
  31.                         Sec=0;
  32.                         Min++;
  33.                         if(Min>=60)
  34.                         {
  35.                                 Min=0;
  36.                                 Hour++;
  37.                                 if(Hour>=24)
  38.                                 {
  39.                                         Hour=0;}
  40.                                 }
  41.                         }
  42.                 }
  43.                
  44.         }
复制代码


8-1串口先容

1)先容



2)向单片机发送数据(下面框),返回(上框)



3)DB9串口传输数据(注意利用的电压是否同等)利用RS232或RS485电平



4)知识点

①硬件电路



注:最少需要三根线实现双向通信:TXD,RXD,GND。VCC不一定需要,可独立供电。
②电平尺度 

 

 差分信号优点:传送距离远(1km+)   TTL与RS232(10m)

③常见通信接口比较


 CAN总线:常用于汽车领域,由于利用的是差分信号传输,传输距离远、稳定。
通信方式的相关术语:

 
④51单片机里的UART串口 


 

 
 

 
   中心部分用来控制波特率,依靠定时器来约定速率,T1的溢出率通过分频后来控制收发器的采样时间。
  SBUF:收发数据后,会产生相应的TI(发送中断)/RI(接收中断),继而进入中断函数,进行相应的中断函数内部的操作。

 
 配置ES、EA,PS此时不需要配置,由于只有一个中断,不需要进行优先级判定。

 
 配置好SCON和PCON,读SBUF,配置定时器T1,打开EA和ES,即串口可以开始工作。

8-2.实际配置串口 

1)将延迟函数复制过来并导入工程里面;

2)配置串口控制寄存器,配置模式1最常用,REN允许接收给1,不允许接收给0(也可以给1表面不给发就行);







3)TI、RI发送完置1(硬件只负责),但必须软件复位置0;





 故SCON=0x40
PCON
4)配置定时器



这里定时器1,没有定时器0,所有要把高位修改(不影响高低位配置用“”& |“”这两个方式)


选择8位自动重载模式



5)可以直接用STC-isp来配置串口 


系统频率根据板子选择,波特率4800,波特率发生器选择8位自动重载,时钟12T

6)发送数据的函数


7)发送单项数据




8)模块化



9)数据表现模式 





8-3.串口实例实现 

1)每一秒发送一个递增的数字


 
 2)电脑通过串口控制LED灯,并且返回电脑读入的数据

1.需要打开串口的中断功能


SCON = 0x50;  EA=1;ES=1; 
注:要分清这里是禁止了定时器1的中断功能,只是让它的溢出率去开启串口收发的功能,中断的产生是由于串口收发数据产生的中断。
2.编写串口中断函数


串口中断函数模板:
  1. void UART_Routine() interrupt 4
  2. {
  3.          if(RI==1)
  4.          {
  5.                  
  6.                  RI=0;   //复位清0
  7.          }
  8. }
复制代码
 
3.整体代码

 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4