pic16f886串口接收中断进不去

2020-02-06 10:30发布

代码如下:
//所选芯片:PIC16f886
#include  <pic.h>                                 //包含单片机内部资源预定义       

#define TRUE         1
#define FALSE   0  


void vInit(void);
void vUART0_Init(void);
void delay(void);

//__CONFIG (HS & WDTEN & PWRTEN & BOREN & LVPDIS
unsigned int  unCount = 0, unRvCount = 0, unSendCount = 0;
unsigned char ucFlag = 0, ucRvFlag = 0;
unsigned char ucRvData[10] = {0}, ucSendData[10] = {0};

void main(void)
{
        ANSEL = 0X00;                                //禁止模拟输入AN0~AN13
        ANSELH = 0X00;                               
        TRISA = 0X00;                                //PORTA0定义为输出
        PORTA = 0X00;
                                                                       
        vInit();
        vUART0_Init();
       
        while(1 == 1)
        {
//                TXREG = 0x21;
//                while(!TXIF);                        //TXIE置1时,TXIF被置1;待发送的最后一个字符写入TXREG时,TXIF被清零
                delay();
               
                asm("clrwdt");                        //清除看门狗
                if (unRvCount == 10)
                {
                        CREN = 0;
                       
                        for (unRvCount = 10; unRvCount>=0; unRvCount--)
                        {
                                ucRvData[10-unRvCount] = TXREG;
                                while(!TXIF);
                        }
                       
                        unRvCount = 0;
                        CREN = 1;
                }
               
        }

}

void delay(void)
{
        unsigned int x = 2000;
        while(--x){        NOP();}
}

void vInit(void)                                //芯片基本配置初始化函数
{
       
        OSCCON = 0X75;                                //内部振荡器选为8Mhz
        INTCON = 0x00;                                //关闭所有中断
        PIE1 = 0x00;                                 //外设中断禁止寄存器1

        //外部中断配置RB0引脚
        TRISB0 = 1;                                        //RB0定义为输入
        //TRISB1 = 0;                                        //RB1定义为输出
       
        RBPU = 0;
        WPUB |= 0X01;
        INTEDG = 1;                                           //外部中断引脚下降沿触发
        INTF = 0;                                        //外部中断标志位清零
        INTE = 1;                                        //外部中断允许
       
        //定时器0配置
        T0CS = 0;                                        //TMR0选为定时器模式,时钟Fosc/4       
        PSA = 0;                                        //预分频器分配给Timer0       
        PS0 = 0;                                        //PS<2:0>为011 TMR0 1:16  WDT 1:8                                                                          
        PS1 = 0;                     
        PS2 = 0;                                                                                                                            
                    
        TMR0 = 0x37;                                //写入TMR0时有两个指令周期的延时                                                                                                                                                        
        T0IF = 0;                                        //TMR0溢出中断标志位清零                                          
        T0IE = 1;                                        //允许TMR0溢出中断                  
       
        PEIE = 1;                                        //使能所有未屏蔽的外设中断
        GIE = 1;                                        //开放总中断
}

//通信初始化
void vUART0_Init(void)
{

        SPBRG = 51;                             //8M晶振 设置波特率2400  波特率:Fosc/[64(n+1)]
        BRGH  = 0;
        BRG16 = 0;                                        //BRG 8位定时器 异步
        SPEN  = 1;
        SYNC  = 0;
       
        TXSTA = 0x20;  // 0110 0001    //八九位数据、发送使能、异步通信
       
        RCIE = 1;                  //允许接收中断
        PEIE = 1;                                        //使能所有未屏蔽的外设中断
        GIE = 1;
       
        CREN = 1;
}

void interrupt ISR(void)                                 //中断服务程序
{
       
        if (T0IF)
        {
                TMR0 = 0X37;
                T0IF = 0;
                unCount++;
                if (unCount <= 10)
                {
                        RA0 = 1;
                }
                else
                {
                        RA0  = 0;
                }
               
                if (unCount == 20)
                {
                        unCount = 0;
                }
        }
       
        if (INTF)
        {
                INTF = 0;
                RA2 = ~RA2;
        }
       
        if(RCIF)
        {       
                RA3 = ~RA3;
                if (OERR)                        //溢出错误恢复
                {
                        CREN = 0;
                        CREN = 1;               
                }
                ucRvData[unRvCount++] = RCREG;                        //RCREG被读走时RCIF自动清零
        }
}

大神支招
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
xiaohunnanzi
1楼-- · 2020-02-06 14:57
RA3电平没变化
sunliezhi
2楼-- · 2020-02-06 16:44
串口2条IO设为输入了没有?
xiaohunnanzi
3楼-- · 2020-02-06 18:48
刚才的有点乱,我重新发一遍
我是在protues上仿真的,中断就是进不去啊

#include  <pic.h>                                 //包含单片机内部资源预定义       

//__CONFIG (HS & WDTEN & PWRTEN & BOREN & LVPDIS
unsigned int  unCount = 0, unRvCount = 0, unSendCount = 0;
unsigned char ucFlag = 0, ucRvFlag = 0;
unsigned char ucRvData[10] = {0}, ucSendData[10] = {0};

void delay(void);

void main(void)
{
        OSCCON = 0X75;                                //内部振荡器选为8Mhz
        INTCON = 0x00;                                //关闭所有中断
        PIE1 = 0x00;                                 //外设中断禁止寄存器1
               
        TRISC = 0X80;
        SPBRG = 51;                             //8M晶振 设置波特率2400  波特率:Fosc/[64(n+1)]
        BRGH  = 0;
        BRG16 = 0;                                        //BRG 8位定时器 异步
        SPEN  = 1;
        SYNC  = 0;
       
        TXSTA = 0x20;  
        CREN = 1;

        RCIE = 1;                  //允许接收中断                                                       
        PEIE = 1;                                        //使能所有未屏蔽的外设中断
        GIE = 1;                                        //开放总中断
       
        while(1 == 1)
        {
//                TXREG = 0x21;
//                while(!TXIF);                        //TXIE置1时,TXIF被置1;待发送的最后一个字符写入TXREG时,TXIF被清零
                delay();
               
                asm("clrwdt");                        //清除看门狗
               
                if (unRvCount == 10)
                {
                        CREN = 0;
                       
                        for (unRvCount = 10; unRvCount>=0; unRvCount--)
                        {
                                TXREG = ucRvData[10-unRvCount];
                                while(!TXIF);
                        }
                       
                        unRvCount = 0;
                        CREN = 1;
                }
               
        }

}

void delay(void)
{
        unsigned int x = 2000;
        while(--x){        NOP();}
}

void interrupt ISR(void)                                 //中断服务程序
{
       
        if(RCIF)
        {       
                RA3 = ~RA3;
                if (OERR)                        //溢出错误恢复
                {
                        CREN = 0;
                        CREN = 1;               
                }
                ucRvData[unRvCount++] = RCREG;                        //RCREG被读走时RCIF自动清零
        }
}
xiaohunnanzi
4楼-- · 2020-02-06 21:00
sunliezhi 发表于 2014-9-1 16:32
串口2条IO设为输入了没有?

SPEN=1 时自动就设好了,datasheet这么说的
sunliezhi
5楼-- · 2020-02-06 21:50
 精彩回答 2  元偷偷看……
yklstudent
6楼-- · 2020-02-07 02:51
代码没什么大问题
注意:for (unRvCount = 10; unRvCount>=0; unRvCount--)
应该改为:
for (unRvCount = 10; unRvCount>0; unRvCount--)

一周热门 更多>