分享

stc89c52rc单片机串口中断发送问题

 quasiceo 2016-01-11

stc89c52rc单片机串口中断发送问题

发表于 2014-5-1 00:33:04   2366 查看 20 回复 只看该作者 倒序浏览
我用串口中断发送数据,开始单片机发送正常,也能接受!当我再次将程序烧录到单片机就发现单片机不能正常工作了!我的单片机晶振是11.0592M的。波特率9600!单片机工作不正常的表现为:单片机运行熟读变得相当相当慢,比以前慢了许多!不知道是怎么回事,还请各位高手帮帮忙,看看我的程序哪里出了问题!在此谢过了!
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code ptrData[]     ={0x7e,0x04,0xa1,0x00,0x00,0x7e};   //命令
sbit djz = P2^4;                        //电机正转
uint txbuffer[];                        //串口发送缓存区
uint bufferhead,bufferCt;   //发送状态标志
void init()
{
        TMOD  = 0x21;           //定时器1工作方式2,定时器0工作方式1(用于延迟)
        SCON  = 0x50;
        TH1   = 0xfd;           //串口9600波特率初值
        TL1   = 0xfd;
        TR1=1;
        EA =1;
        ES =1;
        bufferhead=bufferCt=0;
}

void delay(uint i)
{
        uchar j;
        while(i--)
        {
                for(j=0;j<115;j++)          //1ms基准延时程序
                { ;        }
        }
}


void uart_senddata(uchar j)
{
        uint i;
        for(i=0;i<6;i++)
        {
                if(i!=4)
                {
                        txbuffer[bufferCt]=ptrData[i];//循环添加待发送数据
                        bufferCt++;
                }
                if(i==4)
                {
                        txbuffer[i]=j;
                        bufferCt++;
                }                                                       
        }
        TI=1;                                                                //命令数据存缓存期完毕后,立刻触发串口发送中断
}



void main()
{
        init();          
        delay(200);
        uart_senddata(4);
        delay(100);
        while(1)
        {
                djz=0;
                delay(500);
                djz=1;
                delay(500);
        }  
}

void uart_int(void) interrupt 4
{
        if(TI)                                                  //等待中断触发
        {
                TI=0;
                if(bufferCt)
                {
                        SBUF=txbuffer[bufferhead++];
                        bufferCt--;
                        if(bufferCt==0)
                        {
                                bufferhead = 0;          //当发送数据个数大于16时,bufferhead清零               
                        }
                }                               
        }       
}

你是不是烧录的时候没有设置晶振的参数啊
我用的stc-isp下载软件,对于这个单片机不需要设置晶振参数啊

          
     我也看不懂你的程序,不过有一点,如果你的单片机也接收数据,那么串口中断里面也要对串口接收触发的中断进行处理,就是清RI,如果不清除则不断触发中断。

谢谢你的帮助,还真是这个RI搞的鬼!

一般串口发送是不用中断的窝,因为发送是主动的。接收才用中断,因为接收是被动的。可以参考stc官网手册,发送一般用
SBUF = temp;
while(!TI);
TI =0 ;
这样的结构。

问题解决就好,一般串口中断都要判断TI和RI.清零再做出对应的中断操作.

恩恩,这个我知道,主要是开始我发这个数据的时候,时间有点长,照成我的数码管在扫描显示的时候发生抖动!当时是想到这么写,所以就这么弄了,用数码管中断扫描显示也能达到目标!只是上次遇到这个,想摸清这个原因!不过同样谢谢你的热心回答,谢谢!

可以用定时器中断不断扫描数码管,那么就不会出现抖动了。











发表于 2014-5-3 10:53:00    楼主|
依然落叶飘零 发表于 2014-5-3 09:48
可以用定时器中断不断扫描数码管,那么就不会出现抖动了。

恩恩,我两个都用了中断!对了,再问哥您一个问题咯!
我把这个电路的信号输出端(J1-2脚)接在了stc89c52单片机的外部中断口1口,可是每当出现一个物体遮挡过去之后,单片机的外部中断1服务函数执行了好几次,我设置的外部中断是单片机下降沿触发!我的服务函数里面没有加去抖延迟,因为中断函数里面不想出现那些延迟什么的函数,中断里加延迟感觉太不靠谱了。影响单片机其他程序的运效率!您有什么好的建议吗?也不知道rs触发器能不能做到硬件去抖!还有什么办法可以用硬件去掉这个电路电平变化的过程产生的抖动?或者程序上怎么修改比较好?

这是我的中断服务函数代码:
void tuiqiu() interrupt 2             //检测上升沿触发,快进快
{  
//假如没有加延迟去抖,下面的函数会被执行多次,中断里不加延迟!        

        if(score_over>0)           
        {
                if(T10s_flag==1)         //到了十秒的时间,说明电机要开始反转了
                {
                        count=201;                //从第二个十秒开始
                }
                else
                count=0;                    
                if(score_over>0)   
                {                                       
                        uart_senddata(m+5);                //发送地址位
                        m++;
                        if(m==13)
                        m=0;
                        score_over--;        
                        if(score_over==0)
                        {
                                djz=0;                              //停止电机
                                djf=0;
                                TR2=0;                            //关定时器2
                                T10s_flag=0;                   //10秒标志位清零
                                count=0;                         //10秒计数值清零
                                m=0;
                        }        
                }
        }
}




发表于 2014-5-3 11:52:06  
看了半天都没看懂你的电路时怎么工作的。Q1和D1是什么?实在不软件去抖动就加个rs触发器硬件去抖动吧。另附计数器模块电路给你参考下。

528583380_97203997.jpg (52.54 KB, 下载次数: 0)

528583380_97203997.jpg


发表于 2014-5-3 19:45:10  
Keil_ㄨ_亻訁仰 发表于 2014-5-3 00:08
恩恩,这个我知道,主要是开始我发这个数据的时候,时间有点长,照成我的数码管在扫描显示的时候发生抖动 ...

产生抖动的根本原因就是串口发送和数码管扫描这两个任务相互干扰。不知你有没了解过单片机上的多任务处理,像keil自带的rtxTiny微型操作系统,或者像ucosII操作系统。这样就可以实现多任务并,比起使用定时器中断扫描,程序流程会更加直观。



发表于 2014-5-4 08:55:48    楼主|
依然落叶飘零 发表于 2014-5-3 11:52
看了半天都没看懂你的电路时怎么工作的。Q1和D1是什么?实在不软件去抖动就加个rs触发器硬件去抖动吧。另附 ...

Q1是9013,npn三极管,这个电路实现的功能就是红外接收管接收到了红外信号,然后J1-2端就输出一个低电平,但是结果发现这个低电平相当不稳,抖动比较厉害,多次触发了外部中断!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多