历史上的今天
返回首页

历史上的今天

今天是:2025年03月02日(星期日)

2020年03月02日 | 51单片机中断、串口通信综合程序

2020-03-02 来源:51hei

正在初学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

                        {

推荐阅读

史海拾趣

Alan Industries Inc公司的发展小趣事

随着产品技术的不断提升,Alan Industries Inc.开始积极拓展市场。公司制定了详细的市场营销策略,通过线上线下的多渠道推广,成功将产品打入国内外市场。同时,公司还注重品牌建设,通过优质的产品和服务赢得了消费者的信任和口碑。随着品牌知名度的提升,公司的市场份额不断扩大,成为电子行业中的佼佼者。

CONEXANT公司的发展小趣事

作为一家在半导体和通信领域具有深厚技术底蕴的公司,Conexant始终致力于技术创新和市场拓展。在不断变化的市场环境中,Conexant紧跟行业趋势,加大在新技术研发和市场推广方面的投入。通过持续创新和市场拓展,Conexant成功巩固了在行业内的领先地位,并为全球用户提供了更加优质的产品和服务。

这些故事只是CONEXANT公司在电子行业发展中的一部分,它们展示了公司在不同时期的战略决策、技术创新和市场拓展能力。这些成就不仅为CONEXANT公司赢得了业界的尊重和认可,也为整个电子行业的发展做出了重要贡献。

聚辰(Giantec)公司的发展小趣事

在快速发展的同时,港源公司始终不忘履行社会责任。公司秉承绿色环保、节能减排的理念,在生产经营活动中以预防为主、全员参与为行动纲领,防治污染、节废减排。港源公司选用绿色环保RoHS材料,严格管控生产制造过程,确保生产出的产品符合国际环保标准。此外,公司还积极参与社会公益活动,为社会和谐发展贡献自己的力量。

艾吉芯(Agertech)公司的发展小趣事

在电子行业的快速发展中,艾吉芯公司凭借其在半导体芯片研发领域的深厚积累,成功推出了一系列高性能的半导体分立器件。这些产品不仅满足了市场对功率半导体的高效、稳定需求,更在技术创新方面取得了显著突破。艾吉芯公司通过持续的研发投入和严格的生产质量控制,确保了产品的可靠性和竞争力,逐渐在市场中树立起了良好的口碑。

Chen Yang Technologies GmbH & Co KG公司的发展小趣事

随着业务的发展,Chen Yang Technologies意识到单靠自身力量难以实现快速扩张。因此,公司开始积极寻求与其他电子行业巨头的战略合作。通过与这些公司的合作,Chen Yang Technologies不仅获得了更多的资金支持和技术资源,还成功进入了新的市场领域。这些合作使得公司的业务范围得到了极大的拓展,同时也提升了公司的品牌影响力。

General Instrument公司的发展小趣事
保持设备运行环境的温湿度适宜,定期清理灰尘。

问答坊 | AI 解惑

HTCAD 土石方量计算软件

HTCAD是一套基于AutoCAD平台上开发的土方工程量计算绘图软件,针对各种复杂地形况,软件采用了方格网法计算土石方量。软件具有良好的交互性,界面友好,贴近设计人员的设计思路,能够在最短的时间内计算出土石方量。适用于工业设计院总图专业,规划 ...…

查看全部问答>

机器人讲座 第二讲

机器人讲座 第二讲   …

查看全部问答>

开关电源要降低纹波主要要在三个方面下功夫

1、储能电感。储能电感在工作频率下的Q值越大越好,很多人只注意到电感量,其实Q值的影响要大得多,电感量只要满足要求允许在很大范围内波动。 2、滤波电容。滤波电容的ESR和ESL是非常重要的参数,越低越好,仅追求容量是远远不够的,当然在满 ...…

查看全部问答>

单片机原理和应用课件

正在学单片机传个课件上去 与大家共享了…

查看全部问答>

【晒电路】麦克风放大电路

前几天发过一个电路,有噪声.但没人给解答.后来又重新用TDA2822做了一个麦克风放大的,用在对讲电路中,效果很好,没有一点噪声. 因为开始自己寻找这方面的电路找了很久,但照图弄出来效果都不理想.所以就想把自己的贴出来,给需要的同行一点帮助. 本电 ...…

查看全部问答>

底板和芯片模块如何连接

有一个问题有点疑惑,以前没弄过焊接开发板的事,现在想想要是想把模块芯片焊接到开发板上那么引脚该怎么连啊,比如我想连接编解码芯片到开发板上,用iic总线传输控制信号,spi接口传输数据,通用i/o口传一些中断等信号,那么这块芯片怎么和开发板 ...…

查看全部问答>

求教:TCPMP线程问题!?

小弟调用tcpmp的common.dll来做开发 Context_Init((tchar_t*)name, (tchar_t*)version, id, (tchar_t*)cmdline, application);                                 ...…

查看全部问答>

视频设备开发

请教高手 我现在有几副图象要显示在电视机上,图象存在EEPROM中,不知用什么样的图象处理芯片?原先红白机中用了UM6538,但其象素太低,不知有何芯片替代? …

查看全部问答>

evc 编译完成 如何调试该程序?

我的意思是,用evc ide 直接连接 sdk 开发板(2410) 直接下载到板子上执行。 板子上已经用pb 4.2 编译的wince 下载完毕。 我目前只能evc ide 下载到 evc 的 模拟器上执行。 如何,让evc ide 连接 sdk (2410)直接执行呢? 需要配置什么?…

查看全部问答>

S3C2440中的Uart串口地址问题

请教S3C2440中的Uart串口地址问题:UART0的发送缓冲区地址为0X50000020,接收缓冲区地址为0X50000024,中间只相差4个字节,怎么来的64字节的FIFO缓冲区呢? 谢谢!…

查看全部问答>