受腾讯软件大神指示,程序中能不用中断就不要使用中断,以免影响程序的正常运行。如果需要判断事件的产生,比如串口消息这种,直接查询标志位即可,于是,我的中断收发函数变成了这样
- if ( PIR1bits.RCIF )
- {
- if ( 2 == i )
- {
- uart_Start = 1;
- uart_Count = 0;
- }
- str[i] = RCREG;
- PIR1bits.RCIF = 0;
- i++;
- }
- if ( uart_Count & gt; 10 || 10 == i )
- {
- uart_Start = 0;
- uart_Count = 0;
- sendstring( str, i );
- i = 0;
- }
PIR1bits.RCIF是串口消息标志位,如果串口有消息会被置1,查询这个标志位就可以知道串口缓冲区有没有数据了,不再需要中断进入,把他们放在main函数的while(1)循环中就OK。uart_Count是串口接收定时器,如果开始串口接收,会从0每10ms自加一次。第二个if是串口发送函数,从接收开始,到100ms会把之前接收的数据发送出去,或者接收10个字符之后也会发送出去。这些都是测试用的。程序有bug,一次发送数据在10个字节以下,会正常收发;如果超过10个字节,串口就死掉了,估计是缓冲区多余的字符没有清空,而我只使用发送函数,所以也没有特地处理这个。
串口初始化及发送函数见下:
- void uart_init()
- {
- TXSTAbits.BRGH = 0; /* select low speed baud rate */
- TXSTAbits.TX9 = 0; /* select 8 data bits */
- TXSTAbits.TXEN = 1; /* enable transmit */
- RCSTAbits.SPEN = 1; /* serial port is enabled */
- RCSTAbits.RX9 = 0; /* select 8 data bits */
- RCSTAbits.CREN = 1; /* receive enabled */
- /* (Asynchronous) Baud Rate = FOSC/(64 (X + 1)) */
- SPBRG = 12; /* (16M)19200 */
- PIR1bits.RCIF = 0; /* make sure receive interrupt flag is clear */
- /*
- * PIE1bits.RCIE = 1; // enable UART receive interrupt
- * INTCONbits.PEIE = 1;// enable peripheral interrupt
- * INTCONbits.GIE = 1; // enable global interrupt
- */
- TRISCbits.TRISC7 = 1; /* RC7 = RX in */
- TRISCbits.TRISC6 = 0; /* RC6 = TX out */
- }
- void sendstring( uchar *data, uchar length )
- {
- uchar i;
- for ( i = 0; i < length; i++ )
- {
- TXREG = *data;
- data++;
- while ( !TXSTAbits.TRMT ) /* make sure buffer full bit is high bfore transmitting */
- ;
- }
- }
这里,串口方面的中断都被我关掉了,因为我有一个10ms的定时器中断,并且串口接收没有使用中断。TXREG = *data这句话要放在while判断之前,放后面的时候数据发送不出来,我看官方的示例程序是while在前,我没那个芯片,没测试过,不确定是不是芯片寄存器原理不同造成的。