[PIC®/AVR®/dsPIC®产品] 新手请教:dsPIC33EP512MC806 串口中断异常

[复制链接]
2941|2
 楼主| 102856 发表于 2017-6-27 20:44 | 显示全部楼层 |阅读模式
刚接触PIC单片机,现在用dsPIC33系列单片机做一个串口收发测试:采用串口接收中断,大概每隔5ms接收20个字节的数据,并将接收到的数据通过另一个串口转发出去,波特率设的是115200;现在测试时发现串口正常接收发送一段时间后,停止发送,等过一段时间后,又开始接收发送.总是间断性工作,一直查不出是怎么回事,在线仿真,就运行不了.代码如下,请大神帮忙看一下有没有问题,应该如何解决?


  1. #include "P33ep512mc806.h"


  2. // DSPIC33EP512MC806 Configuration Bit Settings

  3. // 'C' source line config statements

  4. /*******系统初始化**********************
  5. 将时钟配置为外部高速石英振荡器,其余均采用默认模式。
  6. *************************************/
  7. #define DELAY_76uS asm volatile ("REPEAT, #4201"); Nop();
  8. #define DELAY_8uS asm volatile ("REPEAT, #467"); Nop();

  9. // FGS
  10. #pragma config GWRP = OFF               // General Segment Write-Protect bit (General Segment may be written)
  11. #pragma config GSS = OFF                // General Segment Code-Protect bit (General Segment Code protect is disabled)
  12. #pragma config GSSK = OFF               // General Segment Key bits (General Segment Write Protection and Code Protection is Disabled)

  13. // FOSCSEL
  14. #pragma config FNOSC = PRIPLL           // Initial Oscillator Source Selection bits (Primary Oscillator (XT, HS, EC) with PLL)
  15. #pragma config IESO = OFF               // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)

  16. // FOSC
  17. #pragma config POSCMD = HS              // Primary Oscillator Mode Select bits (HS Crystal Oscillator Mode)
  18. #pragma config OSCIOFNC = OFF           // OSC2 Pin Function bit (OSC2 is clock output)
  19. #pragma config IOL1WAY = ON             // Peripheral pin select configuration (Allow only one reconfiguration)
  20. #pragma config FCKSM = CSDCMD           // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)

  21. // FWDT
  22. #pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler bits (1:32,768)
  23. #pragma config WDTPRE = PR128           // Watchdog Timer Prescaler bit (1:128)
  24. #pragma config PLLKEN = ON              // PLL Lock Wait Enable bit (Clock switch to PLL source will wait until the PLL lock signal is valid.)
  25. #pragma config WINDIS = OFF             // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
  26. #pragma config FWDTEN = ON              // Watchdog Timer Enable bit (Watchdog timer always enabled)

  27. // FPOR
  28. #pragma config FPWRT = PWR128           // Power-on Reset Timer Value Select bits (128ms)
  29. #pragma config BOREN = ON               // Brown-out Reset (BOR) Detection Enable bit (BOR is enabled)
  30. #pragma config ALTI2C1 = OFF            // Alternate I2C pins for I2C1 (SDA1/SCK1 pins are selected as the I/O pins for I2C1)

  31. // FICD
  32. #pragma config ICS = PGD1               // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1)
  33. #pragma config RSTPRI = PF              // Reset Target Vector Select bit (Device will obtain reset instruction from Primary flash)
  34. #pragma config JTAGEN = OFF             // JTAG Enable bit (JTAG is disabled)

  35. // FAS
  36. #pragma config AWRP = OFF               // Auxiliary Segment Write-protect bit (Aux Flash may be written)
  37. #pragma config APL = OFF                // Auxiliary Segment Code-protect bit (Aux Flash Code protect is disabled)
  38. #pragma config APLK = OFF               // Auxiliary Segment Key bits (Aux Flash Write Protection and Code Protection is Disabled)


  39. unsigned char flag=0,head=0,head1=0xa5;


  40. //配置PLL,将系统时钟配置为60MHz,外部输入时钟为12MHz。
  41. void System_Colck(void)
  42. {
  43.     CLKDIVbits.PLLPRE = 0;              //N1 = 2  24/2=12MHz
  44.     PLLFBDbits.PLLDIV = 8;              //M = 10  12*10=120MHz
  45.     CLKDIVbits.PLLPOST = 0;             //N2 = 2 120/2 = 60MHz
  46.     while (OSCCONbits.COSC!= 0b011)
  47.     while (OSCCONbits.LOCK!= 1) {};     //PLL 配置完成
  48. }

  49. /****************UART1_TX初始化***************/
  50. void UART1_TX_Init(void)
  51. {
  52.     RPOR2bits.RP68R = 0b000001;               //将GPIORP68配置为UART1_TX
  53.     U1MODEbits.STSEL = 0;                     //1个停止位
  54.     U1MODEbits.PDSEL = 0;                     //8位数据,无奇偶校验位
  55.     U1MODEbits.ABAUD = 0;                     //禁止自动调整波特率
  56.     U1MODEbits.BRGH = 0;                      //UART标准模式,每个周期内产生16个时钟信号
  57.     U1BRG = ((30000000/115200)/16)-1;         //设置波特率为115200
  58.     U1STAbits.UTXISEL0 = 0;
  59.     U1STAbits.URXISEL1 = 0;                   //发送中断模式选择,当一个字符被传输到发送移位寄存器时产生中断
  60.     IEC0bits.U1TXIE = 1;                      //使能发送中断
  61.     U1MODEbits.UARTEN = 1;                    //使能UART
  62.     U1STAbits.UTXEN = 1;                      //发送使能
  63. }

  64. /****************UART1_RX初始化***************/
  65. void UART1_RX_Init(void)
  66. {
  67.     RPINR18bits.U1RXR = 0b1000101;              //将GPIORP65配置为UART1_RX
  68.     TRISDbits.TRISD3 = 1;                       //寄存器映射
  69.     U1MODEbits.STSEL = 0;                       //1个停止位
  70.     U1MODEbits.PDSEL = 0;                       // 8位数据,无奇偶校验位
  71.     U1MODEbits.ABAUD = 0;                       //禁止自动调整波特率
  72.     U1MODEbits.BRGH = 0;                        //UART标准模式,每个周期内产生16个时钟信号
  73.     U1BRG = ((30000000/115200)/16)-1;           //设置波特率为115200
  74.     IEC0bits.U1RXIE = 1;                        //使能接收中断
  75.     IPC2bits.U1RXIP=1;
  76.     U1STAbits.URXISEL = 0b00;                   //接收中断模式选择,接收到任意一个字符产生中断
  77.     U1MODEbits.UARTEN = 1;                      //使能UART   
  78. }

  79. /****************UART3_TX初始化***************/
  80. void UART3_TX_Init(void)
  81. {
  82.     RPOR7bits.RP97R = 0b011011;              //将GPIORP97配置为UART2_TX
  83.     U3MODEbits.STSEL = 0;                    //1个停止位
  84.     U3MODEbits.PDSEL = 0;                    //8位数据,无奇偶校验位
  85.     U3MODEbits.ABAUD = 0;                    //禁止自动调整波特率
  86.     U3MODEbits.BRGH = 0;                     //UART标准模式,每个周期内产生16个时钟信号
  87.     U3BRG = ((30000000/115200)/16)-1;        //设置波特率为115200
  88.     U3STAbits.UTXISEL0 = 0;
  89.     U3STAbits.URXISEL1 = 0;                  //发送中断模式选择,当一个字符被传输到发送移位寄存器时产生中断
  90.     IEC5bits.U3TXIE = 1;                     //使能发送中断
  91.     U3MODEbits.UARTEN = 1;                   //使能UART
  92.     U3STAbits.UTXEN = 1;                     //发送使能
  93. }

  94. /****************UART3_RX初始化***************/
  95. void UART3_RX_Init(void)
  96. {
  97.     RPINR27bits.U3RXR = 0b1100000;         //将GPIORP96配置为UAR3_RX
  98.     TRISFbits.TRISF0 = 1;                  //寄存器映射
  99.     U3MODEbits.STSEL = 0;                  //1个停止位
  100.     U3MODEbits.PDSEL = 0;                  // 8位数据,无奇偶校验位
  101.     U3MODEbits.ABAUD = 0;                  // 禁止自动调整波特率
  102.     U3MODEbits.BRGH = 0;                   //UART标准模式,每个周期内产生16个时钟信号
  103.     U3BRG = ((30000000/115200)/16)-1;      //设置波特率为115200
  104.     U3STAbits.URXISEL = 0b00;              //接收中断模式选择,接收到任意一个字符产生中断
  105.     IEC5bits.U3RXIE = 1;                   //使能接收中断
  106.     U3MODEbits.UARTEN = 1;                 //使能UART
  107. }

  108. int main()
  109. {
  110.     System_Colck();                             //时钟初始化
  111.     System_Init();                              //系统初始化
  112.     UART1_RX_Init();                            //UART1_RX初始化
  113.     UART1_TX_Init();                            //UART1_TX初始化
  114.     UART3_RX_Init();                            //UART3_RX初始化
  115.     UART3_TX_Init();                            //ART3_TX初始化
  116.     IFS0bits.U1RXIF = 0;
  117.     while(1)
  118.     {
  119.        //UART1_TX_Init();
  120.        //DELAY_76uS;
  121.        //U1TXREG = head1;
  122.     }

  123. }

  124. void __attribute__((__interrupt__, auto_psv)) _U1TXInterrupt(void)//UART1发送中断
  125. {
  126.     IFS0bits.U1TXIF = 0;
  127. }

  128. void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void)//UART1接收中断
  129. {

  130.    
  131.         //UART1_RX_Init();
  132.     if(U1STAbits.OERR == 1)
  133.     {
  134.         U1STAbits.OERR = 0;
  135.     }


  136.     while(U1STAbits.URXDA ==1)
  137.     {
  138.         head=U1RXREG;
  139.                 U3TXREG = head;
  140.     }
  141.         IFS0bits.U1RXIF = 0;
  142. }

  143. void __attribute__((__interrupt__, auto_psv)) _U3TXInterrupt(void)////UART3发送中断
  144. {
  145.     IFS5bits.U3TXIF = 0;
  146. }
  147. void __attribute__((__interrupt__, auto_psv)) _U3RXInterrupt(void)//UART3接收中断
  148. {
  149.    
  150.     IFS5bits.U3RXIF = 0;
  151. }






STM32F103ZE 发表于 2017-7-1 21:49 | 显示全部楼层
程序跑死了,看门狗拉复位了吧。
2个串口开四个中断,不好弄,别开那么多中断,用定时跑轮询安全,就开一个定时器中断多好。
kingkits 发表于 2017-7-3 11:47 | 显示全部楼层
1  你发送时应该有缓冲区,在发送中断出现时,读取缓冲区并发送一个字节到硬件端口
2  如果你的发送中断不用,就不要打开。
3
   if(U1STAbits.OERR == 1)
    {
        U1STAbits.OERR = 0;
    }
   这里应该清除接收缓冲区并直接返回
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

11

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部