打印

求助:很急!关于STC 8位单片机上电后,无法进入串口接收中断的问题

[复制链接]
7373|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小小财迷|  楼主 | 2013-7-7 19:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用的stc的一款很普通的8位单片机,做RS485通信。发现,单片机第一次加电之后,无法进入串口的接收中断,我中断优先级3个两个定时器分别是中断优先级1和2,串口UART是3级,可是当我重新给单片机加电之后,一切又恢复正常,能进入接收中断,反反复复都这样,求遇到过的和大神们支支招,万分感谢。

相关帖子

沙发
lirunze| | 2013-7-7 20:02 | 只看该作者
放弃STC吧

使用特权

评论回复
板凳
小小财迷|  楼主 | 2013-7-7 20:08 | 只看该作者
没办法啊,公司为了降低成本。这个问题很纠结啊,会不会中断优先级的问题,我的硬件电路各个信号正常啊,rst复位时间给了700ms,足够了啊,为何第一次加电会进不了接收中断呢,初始化程序里EA和ES我都开了

使用特权

评论回复
地板
wuzx-61| | 2013-7-7 20:24 | 只看该作者
我相信楼主有能力解决!

使用特权

评论回复
5
sxhhhjicbb| | 2013-7-7 21:01 | 只看该作者
要相信是你自己没用好.要相信你可以解决好....否则你可能真的解决不了.

使用特权

评论回复
6
coody| | 2013-7-7 21:07 | 只看该作者
串口是慢速事件(即使用115200bps),你可以下载STC官网例程测试一下。
STC官网例程在“技术支持”下面大约12、13行有“另一种风格测试程序包”有完整工程可供测试。

使用特权

评论回复
7
coody| | 2013-7-7 21:12 | 只看该作者
另外,建议放弃的朋友,这不是一种好的方式。
我相信任何人用任何一种MCU,都不可能一点问题都不会遇到,即使是很简单的MCU。如果一遇到问题就放弃,那么,你将没有MCU可用。
现在流行的STM32,我看到论坛上有那么多人碰到我认为根本不是问题的问题,但是奇怪的是,没有人建议他放弃。

几年前我放弃过STM32做的一个项目,原因是:STM32F103进入待机模式(大约3uA电流),PA0唤醒等效于复位,这个是我的项目不允许的。。。。

使用特权

评论回复
8
teddeng| | 2013-7-8 00:11 | 只看该作者
STC哪来的三个中断优先级?你是不是误解了同一中断优先级下同时中断时响应优先级和中断嵌套的概念?

使用特权

评论回复
9
小小财迷|  楼主 | 2013-7-8 09:13 | 只看该作者
谢谢你们,我也问了几个朋友,他们说是硬件问题,不是中断优先级的问题,就是第一次上电,接收中断接不了数据,下面是我的中断部分程序:#include "../inc/MySerial.h"
void UART_Interrupt_Receive(void) interrupt 4
{
        unsigned char temp;
        if(RI)                                   //RI由硬件置1,请求CPU处理接收数据
        {
                RI = 0;
                temp=SBUF;
                //--------------------------------
                if(PassWord==1)                                //Version 1.0版自定义协议
                {
                        if(ReceiveConter>10) ReceiveConter=0;
                        switch(ReceiveConter)
                        {
                                        case 0:
                                                if(temp==0x55||temp==0xf0)
                                        {
                                                ReceiveData[0]=temp;
                                                ReceiveConter++;
                                        }
                                        else
                                        {
                                                ReceiveConter=0;
                                        }
                                        break;
                                case 1:
                                        if(temp==0xaa||temp==0x0f)
                                        {
                                                ReceiveData[1]=temp;
                                                ReceiveConter++;
                                        }
                                        else
                                        {
                                                ReceiveConter=0;
                                        }
                                        break;
                                case 10:
                                        if(temp==0x0d)
                                        {
                                                ReceiveData[10]=temp;
                                                ReceiveConter=0;
                                                ReceiveFinish_f=1;
                                        }
                                        else
                                        {
                                                ReceiveConter=0;
                                        }
                                        break;
                                default:
                                        ReceiveData[ReceiveConter]=temp;
                                        ReceiveConter++;
                                        break;
                                }
                        }
                //--------------------------------
                else if(PassWord==3)                    //Version 3.0版自定义协议
                {
                        switch(ReceiveConter)
                        {
                                case 0:
                                        if(temp==0x55||temp==0xf0)
                                        {
                                                ReceiveData[ReceiveConter]=temp;
                                                ReceiveConter++;
                                        }
                                        else
                                        {
                                                ReceiveConter=0;
                                        }
                                        break;
                                case 1:
                                        if(temp==0xaa||temp==0x0f)
                                        {
                                                ReceiveData[ReceiveConter]=temp;
                                                ReceiveConter++;
                                        }
                                        else
                                        {
                                                ReceiveConter=0;
                                        }
                                                break;
                                default:
                                        if((ReceiveConter>=2)&&(ReceiveConter<5))
                                        {
                                                ReceiveData[ReceiveConter]=temp;
                                                ReceiveConter++;
                                        }
                                        else if((ReceiveConter>=5)&& ((ReceiveConter+1)<ReceiveData[4]))
                                        {
                                                ReceiveData[ReceiveConter]=temp;
                                                ReceiveConter++;
                                        }
                                        else if(((ReceiveConter+1)==ReceiveData[4])&&(temp==0x16))
                                        {
                                                ReceiveData[ReceiveConter]=temp;
                                                ReceiveConter=0;
                                                ReceiveFinish_f=1;
                                        }
                                        else
                                        {
                                                        ReceiveConter=0;
                                        }
                                        break;
                        }
                }
        }
}


void Timer_Init (void)
{
     TMOD = 0x11;             // 16 位定时器/ 计数器,TL0、TH0 全用

     TH0  = 0xda;              // set to reload immediately
     TL0  = 0xe8;              // Init reload value             T0:10mS

     TH1  = 0xed;              // set to reload immediately
     TL1  = 0x74;              // Init reload value             T1:5mS

     ET0  = 1;               // enable Timer0 interrupts
     TR0  = 1;               // start Timer0
     ET1  = 1;               // enable Timer1 interrupts
     TR1  = 1;               // start Timer1
}


void serial_port_initial() // 使用独立波特率发生器作为波特率发生器
{
    EA=1;
    SCON = 0x50;        //0101,0000 8 位可变波特率,无奇偶校验位
        switch(SetupData[93])
        {case 1:BRT = RELOAD_COUNT1;break;                //600
        case 2:BRT = RELOAD_COUNT2;break;                //1200
        case 3:BRT = RELOAD_COUNT3;break;                //2400
        case 4:BRT = RELOAD_COUNT4;break;                //4800
        case 5:BRT = RELOAD_COUNT5;break;                //9600
        default:BRT = RELOAD_COUNT2;break;}                //1200
    AUXR |= 0x11;   //T0x12,T1x12,UART_M0x6,BRTR,  S2SMOD,BRTx12,XRAM,S1BRS
                    //Baud = Fosc/(256 - RELOAD_COUNT)/32/12 (12T 模式)(!!!采用!!!)
                    //Baud = Fosc/(256 - RELOAD_COUNT)/32 (1T 模式)
                    //BRTR = 1,启动独立波特率发生器
                    //S1BRS = 1,串口1 选择独立波特率发生器作为波特率发生器,
                    //此时定时器1 可以释放出来作为定时器,计数器,时钟输出使
        RI=0;
    ES = 1;         //允许串口中断
}
复位电路

我用Multisim仿得,复位时间(VCC---2.4V)有700ms,实际测量也相差不多。

使用特权

评论回复
10
kalay| | 2013-7-8 09:43 | 只看该作者
我使用STC的有五六年了,情况还是比较不错的(早期STC的EEPROM频繁上电时有丢失数据情况),根据你描述的现象,逻辑上应该美哦与什么问题,你主要还是检查你的硬件情况,特别是电源情况,是不是断电时间长了以后,初次上电电源不稳无法满足单片机正常工作的需要,可以考虑关闭其他所有中断,仅开启串口中断,使用排除法检测是什么出了问题,祝你成功!

使用特权

评论回复
11
wh6ic| | 2013-7-8 10:01 | 只看该作者
STC部分芯片有四级中断优先级。
看你的情况可能是硬件复位不正常,你的第二次上电是否电源未关闭,而是用的开关之类,上电速度比较快?用电平复位脚控制复位试试。

也有软件问题可能性, 比如某个变量没有在串口接收前赋合适的初值,例如PassWord;  另外中断服务中没有处理TI发送标志;

使用特权

评论回复
12
小小财迷|  楼主 | 2013-7-8 11:59 | 只看该作者
谢谢kalay。wh6ic,我每次都是完全切断电源的,没有用开开控制复位,就上电复位一次。PASSWORD没问题,我做的485通信,下位机带了好多台,RI   TI完全没问题的,就是这种情况不确定的,不知道什么时候上电,哪台下位机就出问题了,进不了中断:'(

使用特权

评论回复
13
XZL| | 2013-7-8 13:39 | 只看该作者
Are you sure REN is active? Mybe other slave computer make some error!

使用特权

评论回复
14
lichuanfa| | 2013-7-8 14:27 | 只看该作者
本帖最后由 lichuanfa 于 2013-7-8 14:30 编辑

感觉STC虽然串口号称兼容51,但是感觉还是有点小小的区别的

使用特权

评论回复
15
小小财迷|  楼主 | 2013-7-8 15:01 | 只看该作者
大家感觉八成是硬件问题吧。。。真纠结啊

使用特权

评论回复
16
elife| | 2013-7-8 23:04 | 只看该作者
楼主,你的TI是如何处理的?中断中添加TI清除处理,初始化TI = 0试一下.

使用特权

评论回复
17
nyf1972| | 2013-7-9 00:02 | 只看该作者
重来没有发现这个问题 如下是我的代码
void Uart0Handler (void )  interrupt 4 using 1
        {//该串口主要用于下载以及对控制器模块的监控上,不接受其他命令
        if(TI)
                {
                TI=0;
                if(Uart0SendEn)
                        {
                        if(Txd0DataLenth--)               
                                {
                                SBUF=*pUart0TxdData++;
                                }
                                else
                                {
                                Uart0SendEn=0;//不再允许重复发送
                                }
                        }
                }
        if(RI)
                {
                RI=0;
                *pUart1RxdData++=SBUF;

                //每次接受间隔必须大于1秒,300ms后就可以进行协议解析
                Timer8Base10ms=30;
                Timer8Base10msEn=1;
                }
        }


如下是初始化代码:
void UART_Init()
        {
        SCON=0X50;//8位 无
        S2CON=0X50;//8位 uart1
        BRT=0xFD;//        晶体为11.059200,波特率发生器的溢出率为:11059200/12/3=307200; (PCON中SMOD为0 )工作在模式1 ,波特率为9600?
//        AUXR=0X11;//UART0使用独立的波特率发生器          T0,T1,使用 12分频 串口使用12分频
//        AUXR=0X00;
        AUXR=0X11; //UART0使用独立的波特率发生器 ,UART1 默认为使用独立的波特率发生器
        AUXR1=0X10; //串口2移动移动大P4.3 ,P4.2
        pUart0RxdData=&Rxd0BuffData;
        pUart1RxdData=&Rxd1BuffData;

        }


void Interrupts_Init()
        {
    IE= 0x92; //允许UART0 和定时器0中断,
        IE2=0X1;//2010.8.2 增加 允许UART1中断
        IP=0X10;//IP=0X00;
        IP2=0;//IP2=1;         //UART1最高优先级
        EA=1;
        }
  最后希望对你有帮助,祝你成功

使用特权

评论回复
18
江枫渔火| | 2013-7-9 14:18 | 只看该作者
大多数问题是因为使用者的问题,别动不动就怀疑芯片。同样的51,各个厂家生产的也有差异,也需要学习和了解。这些折腾过之后都会成为实际经验,而不是书上那些没用的千篇一律的教条。
别因为自己习惯了哪个厂家的芯片,就去抨击另外一个厂家生产的,他自己搞不懂的芯片。
如果所有的知识都能在书上学会,你是很容易被替代的。

使用特权

评论回复
19
LM_BEST| | 2014-12-7 23:09 | 只看该作者
你好,我使用STC15的单板也遇到了串口中断无法响应的问题,能否请教一下,你这个问题是怎么解决的? 我看到你之前发的帖子也遇到了这个问题。谢谢!

使用特权

评论回复
20
coody| | 2014-12-8 11:01 | 只看该作者
LS,STC有15系列的库函数方式的例程可以参考,单串口或双串口。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

144

帖子

2

粉丝