我试图让我的系统使用UART通过XBee发出信号,并且我有一个很好的链接,并且正在交流。
每当我按下板上的按钮时,我使用的代码应该输出一些内容。
下面的代码应该输出
- 'h'按下1时
- '你好,当2被按2时
- '3'按下3时
- '4'按下4时
1,3,而4个工作完美地工作,但是当我按2时,我得到的就是'o H e'。为什么那是?
#include <p33FJ256GP710A.h>
#include "string.h"
_FOSCSEL(FNOSC_FRC); // Internal FRC oscillator
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_NONE);
// Clock Switching is enabled and Fail Safe
Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystanl
#define TRUE 1
#define FALSE 0
unsigned char S3Flag, S4Flag, S5Flag, S6Flag;
const char A[] = {'hello', ' ', 'how', ' ', 'are'};
int i;
void __attribute__ ((interrupt, no_auto_psv)) _U2RXInterrupt(void) {
LATA = U2RXREG;
IFS1bits.U2RXIF = 0;
}
void __attribute__ ((interrupt, no_auto_psv)) _U2TXInterrupt(void) {
IFS1bits.U2TXIF = 0;
}
void InitClock() {
PLLFBD = 38; // M = 40
CLKDIVbits.PLLPOST = 0; // N1 = 2
CLKDIVbits.PLLPRE = 0; // N2 = 2
OSCTUN = 0;
RCONbits.SWDTEN = 0;
// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x01); // Initiate Clock Switch to
// FRC with PLL (NOSC=0b001)
__builtin_write_OSCCONL(0x01); // Start clock switching
while (OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur
while(OSCCONbits.LOCK != 1) {};
}
void InitUART2() {
// This is an EXAMPLE, so brutal typing goes into explaining all bit sets
// The HPC16 board has a DB9 connector wired to UART2, so we will
// be configuring this port only
// configure U2MODE
U2MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U2MODEbits.notimplemented; // Bit14
U2MODEbits.USIDL = 0; // Bit13 Continue in Idle
U2MODEbits.IREN = 0; // Bit12 No IR translation
U2MODEbits.RTSMD = 0; // Bit11 Simplex Mode
//U2MODEbits.notimplemented; // Bit10
U2MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U2MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U2MODEbits.LPBACK = 0; // Bit6 No Loop Back
U2MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U2MODEbits.URXINV = 0; // Bit4 IdleState = 1 (for dsPIC)
U2MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U2MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U2MODEbits.STSEL = 0; // Bit0 One Stop Bit
// Load a value into Baud Rate Generator. Example is for 9600.
// See section 19.3.1 of datasheet.
// U2BRG = (Fcy/(16*BaudRate))-1
// U2BRG = (37M/(16*9600))-1
// U2BRG = 240
U2BRG = 240; // 40Mhz osc, 9600 Baud
// Load all values in for U1STA SFR
U2STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U2STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U2STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
//U2STAbits.notimplemented = 0; //Bit12
U2STAbits.UTXBRK = 0; //Bit11 Disabled
U2STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U2STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U2STAbits.TRMT = 0; //Bit8 *Read Only bit*
U2STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U2STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U2STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U2STAbits.PERR = 0; //Bit3 *Read Only Bit*
U2STAbits.FERR = 0; //Bit2 *Read Only Bit*
U2STAbits.OERR = 0; //Bit1 *Read Only Bit*
U2STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC7 = 0x4400; // Mid Range Interrupt Priority level, no urgent reason
IFS1bits.U2TXIF = 0; // Clear the Transmit Interrupt Flag
IEC1bits.U2TXIE = 1; // Enable Transmit Interrupts
IFS1bits.U2RXIF = 0; // Clear the Recieve Interrupt Flag
IEC1bits.U2RXIE = 1; // Enable Recieve Interrupts
U2MODEbits.UARTEN = 1; // And turn the peripheral on
U2STAbits.UTXEN = 1;
// I think I have the thing working now.
}
void InitPorts() {
// S3 (portD Pin 6, chosen as trigger for sending 'M' to UART)
// S6 (portD Pin 7, chosen as trigger for sending 'C' to UART)
// S5 (portA Pin 7, chosen as trigger for sending 'H' to UART)
// S4 (portD Pin 13, chosen as trigger for sending 'P' to UART)
TRISD = 0x20C0; // D6,7,13 inputs
AD1PCFGHbits.PCFG23 = 1; // This is important. RA7 is muxxed with AN23,
// So we need to config the pin as DIGITAL
TRISA = 0x0080; // only 0th bit needs be output. A7 is input
S3Flag = S4Flag = S5Flag = S6Flag = 0; // Some Debounce Flags
}
void SoftwareDebounce() {
if(PORTDbits.RD6 == FALSE) {
if( S3Flag == FALSE ) {
S3Flag = TRUE;
U2TXREG = 'h';
}
}
else {
S3Flag = FALSE;
}
if(PORTDbits.RD7 == FALSE) {
if( S6Flag == FALSE ) {
S6Flag = TRUE;
for(i=0; i<=4;i++){
U2TXREG = ("%s", A[i]);
}
}
}
else {
S6Flag = FALSE;
}
if(PORTAbits.RA7 == FALSE) {
if( S5Flag == FALSE ) {
S5Flag = TRUE;
U2TXREG = '3';
}
}
else {
S5Flag = FALSE;
}
if(PORTDbits.RD13 == FALSE) {
if( S4Flag == FALSE ) {
S4Flag = TRUE;
U2TXREG = '4';
}
}
else {
S4Flag = FALSE;
}
}
int main(void) {
InitClock(); // This is the PLL settings
InitUART2(); // Initialize UART2 for 9600,8,N,1 TX/RX
InitPorts(); // LEDs outputs, Switches Inputs
while(1) { // The ever versatile Infinite Loop!
SoftwareDebounce();
}
}
好吧,这些更改应该是一个不错的开始,但是我想在将下一个字符加载到 U2TXREG
之前,您需要阻止另一个寄存器。您应该尝试找到要使用的串行库,以便您只需传递要打印的字符串,然后让它们进入一个圆形缓冲区,当硬件准备好用于下一个字节时。/p>
const char *A = "hello how are";
if(PORTDbits.RD7 == FALSE) {
if( S6Flag == FALSE ) {
S6Flag = TRUE;
int len = strlen(A);
for(i=0; i<len; i++){
U2TXREG = A[i];
}
}
}
else {
S6Flag = FALSE;
}
您只应该写入tx-buffer,当至少一个位置空的位置时,否则您将丢失数据:
const char *A = "hello how are";
if(PORTDbits.RD7 == FALSE) {
if( S6Flag == FALSE ) {
S6Flag = TRUE;
int len = strlen(A);
for(i=0; i<len; i++){
while (U2STAbits.UTXBF == 1); //wait for an empty position in the buffer
U2TXREG = A[i];
}
}
}
else {
S6Flag = FALSE;
}