搜索
bottom↓
回复: 7

pic16f886串口接收中断进不去

[复制链接]

出0入0汤圆

发表于 2014-9-1 16:15:24 | 显示全部楼层 |阅读模式
代码如下:
//所选芯片: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自动清零
        }
}

大神支招

出0入0汤圆

 楼主| 发表于 2014-9-1 16:16:55 | 显示全部楼层
RA3电平没变化

出0入4汤圆

发表于 2014-9-1 16:32:27 | 显示全部楼层
串口2条IO设为输入了没有?

出0入0汤圆

 楼主| 发表于 2014-9-1 16:44:52 | 显示全部楼层
刚才的有点乱,我重新发一遍
我是在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自动清零
        }
}

出0入0汤圆

 楼主| 发表于 2014-9-1 16:45:40 | 显示全部楼层
sunliezhi 发表于 2014-9-1 16:32
串口2条IO设为输入了没有?

SPEN=1 时自动就设好了,datasheet这么说的

出0入4汤圆

发表于 2014-9-1 16:58:11 | 显示全部楼层
本帖最后由 sunliezhi 于 2014-9-1 17:18 编辑

不是的吧? 我用16f648A要设置2条IO的
是有点不一样:
                       16f886.pdf   page151:  When the SPEN bit is set the RX/DT I/O pin is automatically configrued as an input, ....
                       16f648.pdf   page73 :   Bit SPEN(RCSTA<7>) and  bits TRISB<2:1> have to be set in order to configure pins RB2/TX/CK and RB1/RX/DT as the Universal Synchronous Asynchronous Receiver Transmitter.

出0入0汤圆

发表于 2014-9-1 18:56:10 | 显示全部楼层
代码没什么大问题
注意:for (unRvCount = 10; unRvCount>=0; unRvCount--)
应该改为:
for (unRvCount = 10; unRvCount>0; unRvCount--)

出0入0汤圆

 楼主| 发表于 2014-9-2 10:47:33 | 显示全部楼层
知道了,是虚拟示波器设置有误
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 18:10

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表