zqy 发表于 2014-10-8 17:04:05

求助!PIC16F1933串口不能接收数据

刚用PIC MCU,改一个原来工程师的程序增加串口接收PC数据,但是没有成功。
初始化如下:
BAUDCON=0B00000000;
   SPBRGH=0;
   SPBRGL=19;   //MCU使用时钟,内部RC16Mhz,9600波特率
SPEN=1;
   SYNC=1;
   RCIE=1;
   GIE=1;
   PEIE=1;
   CREN=1;

void interrupt rxi()
{
//串口中断程序

   if (RCIE&&RCIF)
{
   RCBUF= RCREG;

   if (RCBUF==0X55)
   {
       LED_GREEN=1;                
   }

   if (RCBUF!=0X55)
    {
       LED_GREEN=0;                
   }
   }
}

跑不到中断里。

qlb1234 发表于 2014-10-8 17:09:14

1. 請檢查MCU是否在工作。
2. 請檢查所有與串口有關的寄存器是否已正確配置。
3. 請檢查中斷程序是否真的未曾執行。

zqy 发表于 2014-10-8 18:17:33

MCU是在工作的,中断程序入口也进入了,因为PIC的所有中断是共用一个入口的,其它中断的功能都正常,就是不能进到这个里面 if (RCIE&&RCIF),串口初始化在上面,我看不出有什么不对,能帮忙看看吗?

lonely9391 发表于 2014-10-8 21:52:17

直接在中断里 LED_GREEN = ~LED_GREEN;   看看led

zw_7627 发表于 2014-10-8 22:23:25

zqy 发表于 2014-10-8 18:17
MCU是在工作的,中断程序入口也进入了,因为PIC的所有中断是共用一个入口的,其它中断的功能都正常,就是不 ...

在SIM下不能跑到RCIE&RCIF这句? 有接收数据吗?

yklstudent 发表于 2014-10-8 22:54:18

void Init_Usart(void)
{
        TRISCbits.TRISC6 = 1;
        TRISCbits.TRISC7 = 1;
        TXREG = 0x00;
        RCREG = 0x00;
        TXSTA = 0b00100110;
        RCSTA = 0b10010000;
        BAUDCON = 0b01001000;
#if 1
        SPBRGL = CAL_BAUDRATE_L();
        SPBRGH = CAL_BAUDRATE_H();
#else
        SPBRGL = ((uint16_t)(_XTAL_FREQ/(4*BAUDRATE)-1))%256;
        SPBRGH = ((uint16_t)(_XTAL_FREQ/(4*BAUDRATE)-1))/256;
#endif
        PIR1bits.RCIF = 0;
        PIE1bits.RCIE = 1;
}

void Usart_Tranmit(uint8_t *ucData, uint8_t ucLen)
{
        uint8_t i;
        for(i=0; i<ucLen; i++)
        {
                TXREG = *ucData++;
                while(!PIR1bits.TXIF);
        }
}
发个范例仅供参考,有问题概不负责。

zqy 发表于 2014-10-9 09:04:52

zw_7627 发表于 2014-10-8 22:23
在SIM下不能跑到RCIE&RCIF这句? 有接收数据吗?

   

       
void interrupt rxi()
{
   if(T0IF&&T0IE)       //定时器中断程序
   {
   TMR0-=PERIOD;   // 装计时器初值
   T0IF = 0;         // 清定时器溢出标志
   SYScount++;      //
    }

//串口中断程序

   if (RCIE&&RCIF)
   {
      RCBUF= RCREG;

      if (RCBUF==0X55)
      {
      LED_GREEN=1;               
      }

      if (RCBUF!=0X55)
   {
      LED_GREEN=0;               
      }
    }
}

是能跑到中断里的,但是检测不到串口中断(RCIF=1),也就是说跑不到if (RCIE&&RCIF)
的函数内执行 RCBUF= RCREG   ...,中断是能进入的,因为定时器中断程序部分功能正常。

zqy 发表于 2014-10-9 09:16:13

yklstudent 发表于 2014-10-8 22:54
void Init_Usart(void)
{
        TRISCbits.TRISC6 = 1;



您这个是发送部分的,能发个接收的吗?我现在只用到接收的。PIC16F1933 TXD&RXD引脚没有共用模拟I/o,应该不用 设置TRISCbits.TRISC6 = 1;
和TRISCbits.TRISC7 = 1 吧;
#if 1
         SPBRGL = CAL_BAUDRATE_L();
         SPBRGH = CAL_BAUDRATE_H();
#else
         SPBRGL = ((uint16_t)(_XTAL_FREQ/(4*BAUDRATE)-1))%256;
         SPBRGH = ((uint16_t)(_XTAL_FREQ/(4*BAUDRATE)-1))/256;
#endif
上面是否如果使用内部RC振荡要较准波特率?能将CAL_BAUDRATE_L(); CAL_BAUDRATE_H();
发上来看看?

zqy 发表于 2014-10-9 09:18:14

lonely9391 发表于 2014-10-8 21:52
直接在中断里 LED_GREEN = ~LED_GREEN;   看看led

这样是可以看到LED引脚变化的。

yklstudent 发表于 2014-10-9 10:28:29

zqy 发表于 2014-10-9 09:16
您这个是发送部分的,能发个接收的吗?我现在只用到接收的。PIC16F1933 TXD&RXD引脚没有共用模拟I/o,应 ...

宏定义的内容一样,没必要重复发
至于接收,中断接收
基本的中断接收实例如下:
void interrupt ISR(void)
{
        uint8_t ucData = 0;
        if(PIR1bits.RCIF && PIE1bits.RCIE)
        {
                PIR1bits.RCIF = 0;
                ucData = RCREG;
        }
}

sdkw 发表于 2014-10-9 10:53:17

if (RCIE&&RCIF)改为if(RCIF)
增加一行RCIF = 0

zqy 发表于 2014-10-10 08:22:00

SPBRGL=19;   //MCU使用时钟,内部RC16Mhz,9600波特率

搞了一个低级错误,SPBRGL=25或者SPBRGL=0x19 就 ok了 。
谢谢大家的热心帮助!   
页: [1]
查看完整版本: 求助!PIC16F1933串口不能接收数据