外部中断、定时器、计数器,串口

外部中断、定时器、计数器,串口
串口相关(TMOD、SCON、PCON)寄存器的配置链接:https://blog.csdn.net/qq_36554582/article/details/82695138
学习如逆水行舟,不进则退,很久不用发现自己都已经将中断,定时器,计数器这部分忘完了,今天将它重新复习并整理,在便于以后学习的同时也警示自己。

同时感谢普中科技的C51单片机教程以及CSDN的一位作者:老马识途单片机,他的proteus教程写的很好,同时也对C语言进行了讲解,很适合初学者。

为了偷个懒,就发图了,自己画的,不好看,但是表述还是明确,如果不想看可以参考其他人写的。
在这里插入图片描述

为了避免多个页面,将中断函数都写在了一个页面,可直接在main()函数调用就行,

但是为了避免地址冲突,应单个运行,即仅在main()函数中取消一个子函数的注释。
#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

uchar counter=0;   //计数器

sbit key0 = P3^5;
sbit key1 = P3^4; 
sbit key2 = P3^3;
sbit key3 = P3^2;    

sbit led = P1^0;	 //定义P10口是led

//------------------------------------------------------//外部中断0
//外部中断0初始化函数
void Int0init()
{   //设置INT0
    EA = 1;     //开总中断
    EX0 = 1;    //开(INT0)外部中断0的中断允许
    IT0 = 1;    //选择电平负跳变(下降沿)触发方式
}
//外部中断T0中断函数
void int0(void) interrupt 0 using 0
{
  P1 = 0x0f;     //点亮LED
}
//------------------------------------------------------//外部中断1
//外部中断1初始化函数
void Int1init(void)
{  //设置INT1
    EA = 1;     //开总中断
    EX1 = 1;    //开外部中断1
    IT1 = 1;    //选择电平负跳变触发方式,
}
//外部中断T1中断函数
void int1(void) interrupt 2 using 0
{
  P1 = 0xf0;     //点亮LED
}
//------------------------------------------------------//定时器T0
//定时器T0初始化
void Timer0init()
{   //设置T0
    TMOD|=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动
    TH0=0XFC;	//给定时器赋初值,定时1ms
	TL0=0X18;	
	ET0=1;      //打开定时器0中断允许
	EA=1;       //打开总中断
	TR0=1;      //打开定时器	
}
void Timer0() interrupt 1
{
    static uint i; 
    TH0=0XFC;	//给定时器赋初值,定时1ms
    TL0=0X18;
    i++;
    if(i==1000)
    {
    	i=0;
    	led=~led;	
    }	
}
//------------------------------------------------------//计数器T0
//计数器T0外部计数方式统计计按键次数
void  Counter0init()
{  //设置T0    
    TMOD=0X06;   //使用定时器T0的计数工作方式,工作于工作方式2(8位自动重装)
    TH0=256-1;   //定时器T0的高8位赋值,计数值为1
    TL0=256-1;   //定时器T0的低8位赋值
    ET0=1;   //允许计数中断
    EA=1;    //开总中断
    TR0=1;   //启动计数方式工作
}
//T0计数中断服务函数
void Counter0(void) interrupt 1 using 0
{
    counter++;         //按键次数加1
    P1=counter;
}
//------------------------------------------------------//定时器T1
//定时器T1初始化
void Timer1init()
{   //设置T1
	TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
	TH1=0XFC;	//给定时器赋初值,定时1ms
	TL1=0X18;	
	ET1=1;//打开定时器1中断允许
	EA=1;//打开总中断
	TR1=1;//打开定时器		
}
void Timer1() interrupt 3
{
    static uint i;
    TH1=0XFC;	//给定时器赋初值,定时1ms
    TL1=0X18;
    i++;
    if(i==1000)
    {
    	i=0;
    	led=~led;	
    }	
}
//------------------------------------------------------//计数器T1
//计数器T1外部计数方式统计计按键次数
void  Counter1init()
{   //设置T1   
    TMOD=0X60;   //使用定时器T1的计数工作方式,工作于工作方式2(8位自动重装)
    TH1=256-1;   //定时器T1的高8位赋值,计数值为1
    TL1=256-1;   //定时器T1的低8位赋值
    ET1=1;   //允许计数中断
    EA=1;    //开总中断
    TR1=1;   //启动计数方式工作
}
//T1计数中断服务函数
void Counter1(void) interrupt 3 using 0
{
    counter++;         //按键次数加1
    P1=counter;
}
/*******************************************************/
void main(void)
{
    P1 = 0xff;   //关闭LED      
//    Int0init();//外部中断0初始化
//    Int1init();//外部中断1初始化
//    Timer0init();//定时器T0初始化
//    Counter0init();//计数器T0初始化
//    Timer1init();//定时器T1初始化
//    Counter1init();//计数器T1初始化
     while(1);
}

Proteus仿真电路图
在这里插入图片描述
串口相关(TMOD、SCON、PCON)寄存器的配置链接:https://blog.csdn.net/qq_36554582/article/details/82695138

发现很多人都在用串口程序,为了方便,我就给大家贴一个完整的串口收发程序:

//这是一个完整的虚拟串口收发程序
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int//毫秒级延时函数
void delayms(uint ms)
{
    uchar i;
    while(ms--)
        for(i = 0;i < 120;i++);
}
//字符发送函数
void putchar(uchar dat)   
{
    SBUF = dat;    //将待发送的字符送入发送缓冲器
    while(TI == 0);  //等待发送完成
    TI = 0;          //发送中断标志请0
}
//字符串发送函数
void putstring(uchar *dat)
{
    while(*dat != '\0')  //判断字符串是否发送完毕
    {
        putchar(*dat);   //发送单个字符
        dat++;           //字符地址加1,指向先下一个字符
        delayms(5);
    }
}
uchar receive(void)         
{   //数据接收函数 -- 和本例中断函数功能相同
 uchar dat; 
 while(RI==0);     //数据没有接收完毕时等待接收
 RI=0;             //接收完毕时清零
 dat=SBUF;         //将接收缓冲器中的数据存入dat
 putchar(dat);
 return dat;       //将接收到的数据返回
}
void Usartinit()
{
     SCON = 0X50;  //串口工作方式设置,串口方式1 ,允许接收
     TMOD = 0X20;  //定时器工作方式设置,T1工作于方式2
     PCON = 0X00;  //波特率倍增设置,不倍增
     TH1 = 0XFD;   //波特率设置
     TL1 = 0XFD;
     ES=1;  //打开串口接收中断
     EA = 1;    //打开总中断
     //TI = 0; 
     TR1 = 1;   //开启定时器
}

void Usart() interrupt 4
{
    uchar temp;
    if(RI == 0) return;  //如果没有接收中断标志,返回
    ES = 0;          //关闭串口中断
    RI = 0;          //清串行中断标志位                                                                                                                      
    temp = SBUF;     //接收缓冲器中的字符
    putchar(temp);   //将接收的字符发送出去
 //   P1=temp;
    ES = 1;          //开启串口中断
}
void main(void)
{
    uchar c=0;
    Usartinit();
    delaym--s(200);
    putstring("Receiving from 8051...\r\n");   
    //串口向终端发送字符串,结尾处回车换行
    putstring("----------------------\r\n");
    delayms(50); 
    while(1){
        P1= receive();
    }
}

虚拟串口仿真图
TX-----------------发送
RX----------------接收
在这里插入图片描述

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值