搜索
bottom↓
回复: 11

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

[复制链接]

出0入0汤圆

发表于 2014-10-8 17:04:05 | 显示全部楼层 |阅读模式
刚用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;                
     }
   }
}

跑不到中断里。

出0入0汤圆

发表于 2014-10-8 17:09:14 | 显示全部楼层
1. 請檢查MCU是否在工作。
2. 請檢查所有與串口有關的寄存器是否已正確配置。
3. 請檢查中斷程序是否真的未曾執行。

出0入0汤圆

 楼主| 发表于 2014-10-8 18:17:33 | 显示全部楼层
MCU是在工作的,中断程序入口也进入了,因为PIC的所有中断是共用一个入口的,其它中断的功能都正常,就是不能进到这个里面 if (RCIE&&RCIF),串口初始化在上面,我看不出有什么不对,能帮忙看看吗?

出0入0汤圆

发表于 2014-10-8 21:52:17 | 显示全部楼层
直接在中断里 LED_GREEN = ~LED_GREEN;   看看led

出0入0汤圆

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

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

出0入0汤圆

发表于 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);
        }
}
发个范例仅供参考,有问题概不负责。

出0入0汤圆

 楼主| 发表于 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   ...  ,中断是能进入的,因为定时器中断程序部分功能正常。

出0入0汤圆

 楼主| 发表于 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();
发上来看看?

出0入0汤圆

 楼主| 发表于 2014-10-9 09:18:14 | 显示全部楼层
lonely9391 发表于 2014-10-8 21:52
直接在中断里 LED_GREEN = ~LED_GREEN;   看看led

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

出0入0汤圆

发表于 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;
        }
}

出0入0汤圆

发表于 2014-10-9 10:53:17 | 显示全部楼层
if (RCIE&&RCIF)改为if(RCIF)
增加一行  RCIF = 0

出0入0汤圆

 楼主| 发表于 2014-10-10 08:22:00 | 显示全部楼层
SPBRGL=19;   //MCU使用时钟,内部RC16Mhz,9600波特率

搞了一个低级错误,SPBRGL=25或者SPBRGL=0x19 就 ok了 。
谢谢大家的热心帮助!   
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-5 14:20

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

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