• 【无标题】


    一、外部中断

    中断初始化(3步)

    1、打开中断;
    2、打开外部中断开关
    3、设置中断的触发方式

    直接在主函数中搞吧 简单粗暴一点

    main()
    {
    	LED=0xff;       //P1口初始值 关闭led灯
    	EA=1;          //全局中断开 打开总中断
    	EX0=1;         //外部中断0开
    	IT0=0;         //设置外部中断的触发方式:电平触发
    	while(1)
    	{
    		//在此添加其他程序,中断程序可以跟此处的程序同步执行
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    外部中断程序

    void Key_INT(void) interrupt 0 using 1
    {
    	LED =~LED; //触发中断后,反转当前LED的状态
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查看手册

    在这里插入图片描述
    发现外部中断0的触发引脚(开关)是 P32引脚,所以把P_32接地(图中显示 低电平有效嘛,给0不就对了),即可触发外部中断0


    二、定时器中断

    定时器中断初始化(5步)

    1、设置定时器模式
    2、设置定时器初值
    3、打开中断;
    4、打开定时器中断开关;
    5、打开定时器开关

    定时器中断初始化配置

    void Init_Timer0(void)		  //定时器初始化子程序
    {
    	TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     
    	TH0=0x0D8;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
    	TL0=0x0F0;
    	EA=1;            //总中断打开
    	ET0=1;           //定时器中断打开
    	TR0=1;           //定时器开关打开
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    定时器中断程序

    interrupt 中断号一定要写 程序是靠识别这个进入的,using写不写无所谓。

    中断号可以在开发手册或百度上找到
    在这里插入图片描述

    void Timer0(void) interrupt 1 using 0
    {
    	TH0=0x0D8;  //重新赋值,方式1是16位计数器 最大装载值为65536
    	TL0=0x0F0;  //每次计时10ms
    	cnt++;
    	/*用户代码部分*/
    	if(cnt == 100)//计时 满1s 执行
    	{
    		LED=~LED;        //指示灯反相,可以看到闪烁
    		cnt = 0;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    主函数调用定时器初始化函数

    main()
    {
    	Init_Timer0();
    	while(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    要先在main函数里先调用定时器0初始化配置,才能正常使用它。
    1.待计时达到我们设置的数值时,程序会自动跳入定时器中断程序
    在这里插入图片描述
    2.进入以后 会重新给TH、TL重新赋值,以便下一次的计数。(程序会一直以设置的时长为周期反复进入中断)这便是定时器中断
    在这里插入图片描述

    三、串口

    涉及寄存器

    1、SCON(Serial Control 串口控制)98H

    用于设置串行口的工作方式、监视串行口的工作状态、控制发送与接收的状态等。
    它是一个既可以字节寻址又可以位寻址8位特殊功能寄存器
    其格式如下图

    在这里插入图片描述

    其中SM2TB8RB8这几位基本没有用到,不用管。
    只要:
    ——SM0SM1RENTIRI 就行啦!
    ——SerialMode0、ReceiveEnable、TransmitInterrupt、ReceiveInterrupt(展开了记好理解)!
    我的理解是:
    1、SM0 SM1的位置是和我们的逻辑相反的(SM0=0 SM1=1 是方式一 );
    2、方式0 不算串口,它是 移位寄存器 用来扩展IO口用的;
    3、并且用的比较多的是方式一 ,我们只要收发数据嘛,一就够了。其它方式的了解一下就行啦;
    3、发送完一帧数据后,要用软件把TI清零,才能再发送下一帧;
    4、接收完一帧数据后,要用软件把RI清零,才能再接收下一帧;

    2、PCON

    就一位用到了SMOD,用来设置波特率 加不加倍的。
    在这里插入图片描述

    3、IE -InterruptEnable 中断允许控制寄存器(A8H)

    作用:CPU对中断系统所有中断以及某个中断源的开放和屏蔽是由中断 允许寄存器E控制的。
    在这里插入图片描述
    EnableAll Interrupt、EnableSeria lnterrupt、EnableTimer Interrupt、EnableExternal Interrupt
    使能所有中断、使能串口中断、使能定时\计数器中断、使能外部中断

    串口初始化配置(5步)

    1、用定时器设置波特率、工作方式
    __a.设置T1的工作方式;【TMOD寄存器】
    __b.设置T1的初值,装载 TH1、TL1;(波特率)
    __c.启动T1;【TCON寄存器中的TR1
    2、打开串口接收位;【SCON寄存器REN
    3、设置串口工作方式SM0 SM1;【SCON寄存器】

    注意SM0 和 SM1的位置 与 我们正常的逻辑相反

    如需串行口在中断方式工作时,要进行中断 设置编程IE寄存器
    打开总开关EA;打开串口使能为ES

    void main()
    {
    	TMOD=0x20;		   //用定时器--方式2   
    	TH1=0xfd;		   //设置串口波特率 9600 
    	TL1=0xfd;
    	TR1=1;			  //打开定时器
    	REN=1;            //串口 接收使能
    	SM0=0;			  //SM0  SM1 = 0 1 --串口工作方式1
    	SM1=1;
    	EA=1;             //开启总中断
    	ES=1;			  //串口使能
    	while(1)
    	{
    		if(num==1)    //判断是否有串口数据的传送
    		{
    			ES=0;     //禁止串口中断
    			num=0;    //清空串口数据的传送标志位
    			SBUF=a;	 //发送数据a到SBUF,即将单片机的数据发送到计算机
    			while(!TI);	//等待串口发送完成
    			TI=0; 	//串口发送完成标志位清零
    			ES=1;		//允许 串口进行下一次的中断
    		}
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    串口在接收到一帧有效数据后由于硬件置位RI=1。然后会进入到下面的串口中断中。
    进入 串口接收中断
    1. 先把标志位RI清零,方便接收下一条数据帧;
    2. 把接收到的数据从SBUF中取出,赋给a,再把num=1
    ___explain: 51的SBUF串行口数据缓冲寄存器,具有输入和输出功能(名称相同,但是物理上是独立的,只是占用同一个地址);
    —换句话说,SBUF既是接收缓冲器又是发送缓冲器,同一时间只能为一种,要么接收,要么发送。a=SBUF是把接收缓冲器中的数据赋给aSBUF=a是把a中的数据赋给发送缓冲器
    !!一句话概括:通过读写缓冲器SBUF实现数据收发功能!!!
    3. 回到主函数,此时的串口数据传送标志位num=1 所以 走if分支,此时把串口接收关闭了,再把串口数据的传送标志位num=0清空。在SBUF=a,这就是把单片机接收到的数据给发出来在电脑屏幕上显示给你看,然后进入while(!IT),等待一帧数据发送完成(即发完一帧数据后TI会被(硬件)置1)。退出while后,把TI给清零,方便下一次数据的发送。再ES=1打开串口使能位。等待下一次串口收发。

    void ser() interrupt 4
    {
    	RI=0;			//RI由硬件置为1 表示收到,进入中断以后 就用软件清零 
    	a=SBUF;			//把接收到的数据赋给`接收缓存区`
    	num=1;			//再把 num置为1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    什么是波特率(比特率)?

    在这里插入图片描述


    每天进步一点点 笔记仅供自学,用来回看复习,不一定适合你,如有错误请指出。

  • 相关阅读:
    【原创】xenomai+linux双内核下的时钟管理机制
    java计算机毕业设计基于安卓Android的电子废弃物回收利用APP
    含文档+PPT+源码等]精品基于PHP实现的社团活动小程序[包运行成功]计算机PHP毕业设计微信小程序项目源码
    表白墙(前端+后端+数据库)
    LeetCode0461.汉明距离 Go语言AC笔记
    【蓝桥杯省赛真题46】python数字币统计 中小学青少年组蓝桥杯比赛 算法思维python编程省赛真题解析
    javaWeb过滤器Filter(二)
    SD/SDIO(1):SD总线协议介绍
    数据库操作语言:DML(data management lauguage)
    基于遗传算法的BP神经网络在汇率预测中的应用研究(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/m0_55251293/article/details/127755569