51单片机中断、串口通信综合程序

发布者:平静心境最新更新时间:2020-03-02 来源: 51hei关键字:51单片机  中断  串口通信 手机看文章 扫描二维码
随时随地手机看文章

正在初学51的中断,定时器,串口等等,遇到很多瓶颈比如串口怎么发送变量的数值啦(加一个0x30就好),分享这个程序给初学者们啦


功能:

1. 开机以后,LED0和LED1实现0.5秒间隔闪烁2次,蜂鸣器同时鸣叫2次。

2. 之后,串口等待接收到一个字符'R',开始进入主循环体。

3. 主循环体中,LED0和LED1实现1秒间隔闪烁。

4. 串口接收到字符'D',回复LED当前状态和系统当前处于运行还是暂停状态,如果运行状态,收到字符'R',如果暂停状态,收到字符'P'。

5. 串口接收到字符'T',回复主循环体开始运行的时间和系统当前处于运行还是暂停状态,时间单位为秒,最大计数值65535,以每一位的ASCII码字符发送,最后加换行符。

6. 串口接收到其他字符,回复字符'W',且蜂鸣器高频率鸣叫2次。

7. 主循环体运行每分钟,蜂鸣器低频率鸣叫1次。

8. 开启INT0中断,按下S_INT0,可以暂停目前的程序运行,再次按下,可以继续运行,之前的所有都保持继续运行的状态,计数值也继续累加。暂停状态下, 依然可以响应串口的'D'和'T'的应答回复,具体暂停还是运行状态的解释,详见第4条要求。

9. 所有定时, 用T0方式1中断实现。

10. 串行口配置为方式1,4800波特率,中断接收,查询发送。


PS:定时器的初值为了方便是用晶振12HZ算的哦,想要精确延时的朋友记得换成11.0592算一下啦


用的STC89C52REC的迷你单片机


单片机源程序如下:

#include  

#include"main.h"    


void main()

{         

    init();


    for(i=0; i<2; i++)

        {

            LED0 = 0;

            LED1 = 0;

            beep = 0;

            delay(25);

                LED0 = ~LED0;

            LED1 = ~LED1;

            beep = 1;

            delay(25);

        }


while(1)            

{        

    while(g_b_enter_flag)

    {        

                if(LED0 == LED1)

            {

                    LED0 = 0;

                LED1 = 1;

                    delay(50);

                }

                LED0 = ~LED0;

            LED1 = ~LED1;

            delay(50);

    }//end of while(g_b_enter_flag)

        while(!g_b_enter_flag)

        {

            ;

        }

}//end of while(1)                 

}


//按键中断子程序 

void int0() interrupt 0

{

        g_b_enter_flag = ~g_b_enter_flag;//暂停和继续的切换

}  


//定时器中断子程序

void Timer0() interrupt 1 using 1

{

    TH0 = 0xB1; //重新加载初值

    TL0 = 0xE0;

        g_i_cnt++; 

        

        if(g_b_enter_flag)

    {

                 g_i_20ms_time++;  //记录主循环运行时间

        }


    if(g_i_20ms_time>50) //主程序运行1s  

        {

        g_i_1s_time++;

                g_i_totaltime++;

                g_i_20ms_time = 0;

    }

        if(g_i_1s_time>60) //运行一分钟

        {           

            beep = 0;

                cdelay(200);

                beep = 1;

                g_i_1s_time=0;        

                                                 

    }

        if(g_i_1s_time>65535)//最大计时值655353

        {

            g_i_1s_time = 0;

        }

}                


//精确延时

void delay(unsigned int z)            

{    

         g_i_cnt=0;

     while(g_i_cnt         {

               ;

         }

         g_i_cnt=0;         

}


//发送一个字符

void send(unsigned char byte)

{

        SBUF=byte;

        while(!TI);

        TI=0;

}


//不精确延时

void cdelay(unsigned int k)

{         

     unsigned int x,y;


         for(x=0; x         {  

             for(y=0;y<600;y++);

         }

}


//外部中断和定时器的初始化

void init()

{

    i=0;

        g_b_R_flag=0;//判断是否是第一次发送R

        g_b_enter_flag=0; //判断是否进入主循环,0为否,1为是

        g_i_cnt=0;        //精确延时用

        g_i_20ms_time=0;        //一个等于20ms

    g_i_1s_time=0; //一个等于1s

        g_i_totaltime=0;   //主程序运行总时间


        EX0 = 1;//开外部中断0

        IT0 = 0;//外部中断0低电平触发


    ET0 = 1;//打开定时器0中断

        TMOD |= 0X01; //定时器工作模式1,16位定时模式

        TR0 = 1;//启动定时器0

        TH0 = 0xB1;

        TL0 = 0xE0; //定时20ms


    ES = 1; //打开串口中断

    SCON = 0x50;//配置串口为模式 1

        REN = 1;//串口允许接收

        

        TMOD |= 0x20;//定时器1,工作模式2 8位自动重装

        TH1 = 0xFA;        //波特率4800

        TL1 = 0xFA;

        ET1 = 0; //禁止 T1 中断

        TR1 = 1;//启动定时器1

    EA = 1;        //打开总中断

}   


//UART中断服务函数

void InterruptUART() interrupt 4 using 1

{

    

        if(RI)//判断接收是否完成

        {

                RI = 0;//手动清零接收中断标志位        


                if((SBUF==0x52)&(g_b_R_flag==1))

                {

                    send('W');

                    beep=0;

                        cdelay(60);

                        beep=1;

                        cdelay(60);

                        beep=0;

                        cdelay(60);

                        beep=1;

                        cdelay(60);

                }

            if(SBUF==0x52)        //接受字母为R,开始进入主循环体

                {        

                    g_b_enter_flag = 1;

                        g_b_R_flag=1;

            }

                else if(SBUF==0x44)//接收字母为D,发送LED状态

                {

                        if(g_b_enter_flag)

                        {

                                send('R');

                                send('n');

                                if(LED0==1&&LED1==0)

                            {

                                 send('C');

                                send('O');

                                send('n');

                            }

                            else

                            {

                                send('O');

                                send('C');

                                send('n');

                            } 

                        }

                        else

                        {

[1] [2]
关键字:51单片机  中断  串口通信 引用地址:51单片机中断、串口通信综合程序

上一篇:深入理解单片机的串转并IC-74HC595的工作时序及用法
下一篇:完整的单片机霍尔测速程序+原理图

推荐阅读最新更新时间:2024-11-01 23:16

51单片机lcd1602
{ Uchar i; for (i=0;i 16;i++) { DispOneChar(i,1,dd++); dd &= 0x7f; if (dd 32) dd=32; } } // 显示光标定位 void LocateXY( char posx,char posy) { Uchar temp; temp = posx & 0xf; posy &= 0x1; if ( posy )temp |= 0x40; temp |= 0x80; LcdWriteCommand(temp,0); } // 按指定位置显示数出一个字符 void DispOneChar(Uchar x,Uchar y,Uchar Wd
[单片机]
12864点阵液晶显示模块与51单片机的接口及程序设计
显示器是人类与应用设备沟通的重要界面,近年来,随着电子技术的飞速发展,液晶显示技术在实际生活中得到了广泛应用。液晶显示模块以其微功耗、体积小、显示内容丰富、模块化以及接口电路简单等诸多优点在科研、生产和产品设计等领域中发挥着越来越重要的作用。LM3033B系列液晶显示模块是深圳TOPWAY公司生产的中文显示模块中的一员。采用了台湾的ST7920控制芯片,并提供了中文字库,为中文显示开发方面带来了更多的方便。本文以LM3033B-0BR3为例介绍了12864点阵液晶显示模块的引脚、结构、功能,详述了与AT89S52单片机的硬件接口电路及有关软件编程方法。 1 LM3033B-0BR3特点及操作 1.1 字符显示 每屏可显示
[单片机]
12864点阵液晶显示模块与<font color='red'>51单片机</font>的接口及程序设计
串口通信基本接线方法
目前较为常用的串口有9针串口(DB9)和25针串口(DB25),通信距离较近时( 12m),可以用电缆线直接连接标准RS232端口(RS422,RS485较远),若距离较远,需附加调制解调器(MODEM)。最为简单且常用的是三线制接法,即地、接收数据和发送数据三脚相连,本文只涉及到最为基本的接法,且直接用RS232相连。 1.DB9和DB25的常用信号脚说明  9针串口(DB9) 25针串口(DB25) 针号 功能说明 缩写 针号 功能说明 缩写 1 数据载波检测 DCD
[单片机]
<font color='red'>串口通信</font>基本接线方法
51单片机—用蜂鸣器播放音乐
#include reg52.h #include ./delay/delay.h //sbit key1 = P1^0; sbit beep = P2^7; #define SEGPORT P0 #define KEYPORT P1 sbit bit_select = P2^0; sbit seg_select = P2^1; unsigned char segdata = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; unsigned char bitdata = {0xfe,0xfd,0xfb
[单片机]
STM32是如何进入中断服务函数xxx_IRQHandler的
今天在看stm32的中断,一时间不理解stm32主函数是如何进入中断函数的,按C编程的理解,会有个特定的入口之类的,但是看demo过程中没有发现入口。 以串口中断服务函数void USART1_IRQHandler(void) 为例,首先用到串口中断,需要先设定串口中断初始化以及串口初始化,另外void USART1_IRQHandler(void) 中断服务函数也应该写好。 发现在stm32的启动文件startup_stm32f10x_md.s中写到 DCD USART1_IRQHandler 其中DCD是一条数据定义伪指令,用于分配一片连续的字存储单元并用指定的数据初始化。 库里定义 #define USART1 (
[单片机]
STM32F407-串口通信基本原理
1.处理器与外部设备通信的两种方式: 并行通信 -传输原理:数据各个位同时传输。 -优点:速度快 -缺点:占用引脚资源多 串行通信 -传输原理:数据按位顺序传输。 -优点:占用引脚资源少 -缺点:速度相对较慢 2.串行通信 按照数据传送方向,分为: 单工: 数据传输只支持数据在一个方向上传输 半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信; 全双工: 允许数据同时在两个方向上传输,因此,全双工通信是两个 单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。 3.串行通信的通
[单片机]
STM32F407-<font color='red'>串口通信</font>基本原理
以89C51单片机为控制核心的开关电源优化设计
引言   开关电源是利用现代电力电子技术控制功率开关管(MOSFET,IGBT)开通和关断的时间比率来稳定输出电压的一种新型稳压电源。从上世纪90年代以来开关电源相继进入各种电子、电器设备领域,计算机、程控交换机、通讯、电子检测设备电源、控制设备电源等都已广泛地使用了开关电源。利用单片机控制的开关电源,可使开关电源具备更加完善的功能,智能化进一步提高,便于实时监控。其功能主要包括对运行中的开关电源进行检测、自动显示电源状态;可以通过按键进行编程控制;可以进行故障自诊断,对电源功率部分实现自动监测;可以对电源进行过压、过流保护;可以对电池充放电进行实时控制。   开关电源的系统结构   通信用-48V开关电源结构图如图1所示:
[电源管理]
25.核心初始化之中断屏蔽-210
在210中屏蔽中断的机制和6410是一样的。而且两者都是向量中断,很多中断都是硬件实现的,不像2440。 但是在210中的中断屏蔽寄存器有4个: 四组屏蔽寄存器的地址: 所以屏蔽中断就是把上面的四个屏蔽寄存器设置为全1,设置为0仍是没有影响。 代码实现: 编译:
[单片机]
25.核心初始化之<font color='red'>中断</font>屏蔽-210
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved