今天调试PIC24FJ64GA306单片机的串口,遇到了一些问题,具体描述如下:
1. 开始只调试了UART2,引脚映射到了RX2=>RP17,TX2=>RP10,程序中开机后会发送一次欢迎信息给电脑端,之后单片机会将接收到的数字全部返回电脑端(测试通过没有问题)
2. 然后按照初始化UART2相同的方法再初始化了UART1,引脚映射到了RX1=>RP14,TX1=>RP29,程序开始时改成用串口1来发送相同的欢迎信息,然后将接收到电脑传来的信息通过UART2发送给485芯片通过485总线发给另外一个dsPIC33FJ64MC202芯片(发送欢迎信息时只能发送两个字节便不能再发送,也就是每次发送只能连续发两个字节,不知道具体是什么原因)
相关代码如下:
1.重映射端口代码:
///////////////////////////////////////////////
// 重新映射相关的引脚
// UART1 的RXD引脚映射到RP14而TXD引脚映射到RP29
// 注意在不同硬件下修改RP映射
////////////////////////////////////////////////
void reMapPinOfUART1(void)
{
// Unlock Registers
__builtin_write_OSCCONL(OSCCON & ~(1<<6));
// Config input function
RPINR18bits.U1RXR = 14; // U1's RXD to RP14
// Config ouput function
RPOR14bits.RP29R = 3; // U1's TXD to RP29
// ReLock Registers
__builtin_write_OSCCONL(OSCCON | (1<<6));
}
///////////////////////////////////////////////
// 重新映射相关的引脚
// UART2 的RXD引脚映射到RP13而TXD引脚映射到RP15
// 注意在不同硬件下修改RP映射
////////////////////////////////////////////////
void reMapPinOfUART2(void)
{
// Unlock Registers
__builtin_write_OSCCONL(OSCCON & ~(1<<6));
// Config input function
RPINR19bits.U2RXR = 17; // U2's RXD to RP17(对应的引脚编号为32,RF5)
// Config ouput function
RPOR5bits.RP10R = 5; // U2's TXD to RP10(对应引脚编号是31,RF4)
// ReLock Registers
__builtin_write_OSCCONL(OSCCON | (1<<6));
}
2.串口初始化代码
/////////////////////////////////////////////////////////////////////
// 串口2初始化函数
// 注意在不同时钟情况下修改波特率设置
////////////////////////////////////////////////////////////////////
void InitUART1(void)
{
reMapPinOfUART1(); // 重新配置UART2的端口,在些应用中使用到了RXD和TXD两个引脚,其他引脚未使用
// 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
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U1MODEbits.notimplemented; // Bit14
U1MODEbits.USIDL = 0; // Bit13 Continue in Idle
U1MODEbits.IREN = 0; // Bit12 No IR translation
U1MODEbits.RTSMD = 0; // Bit11 Simplex Mode
//U1MODEbits.notimplemented; // Bit10
U1MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U1MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U1MODEbits.LPBACK = 0; // Bit6 No Loop Back
U1MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U1MODEbits.RXINV = 0; // Bit4 IdleState = 1 (for dsPIC)
U1MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
// Load a value into Baud Rate Generator. Example is for 9600.
// See section 19.3.1 of datasheet.
// U1BRG = (Fcy/(16*BaudRate))-1
// U1BRG = (32M/(16*9600))-1
// U1BRG = 240
U1BRG = 103; // 40Mhz osc, 9600 Baud
// Load all values in for U1STA SFR
U1STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U1STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U1STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
//U1STAbits.notimplemented = 0; //Bit12
U1STAbits.UTXBRK = 0; //Bit11 Disabled
U1STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U1STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U1STAbits.TRMT = 0; //Bit8 *Read Only bit*
U1STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U1STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U1STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U1STAbits.PERR = 0; //Bit3 *Read Only Bit*
U1STAbits.FERR = 0; //Bit2 *Read Only Bit*
U1STAbits.OERR = 0; //Bit1 *Read Only Bit*
U1STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC2bits.U1RXIP = 5; // Mid Range Interrupt Priority level, no urgent reason
IPC3bits.U1TXIP = 5;
IFS0bits.U1TXIF = 0; // 清除发送中断标志
IEC0bits.U1TXIE = 1; // 使能发送中断
IFS0bits.U1RXIF = 0; // 清除接收中断标志
IEC0bits.U1RXIE = 1; // 使能接收中断
U1MODEbits.UARTEN = 1; // 使能串口模块
U1STAbits.UTXEN = 1;
// I think I have the thing working now.
}
/////////////////////////////////////////////////////////////////////
// 串口2初始化函数
// 注意在不同时钟情况下修改波特率设置
////////////////////////////////////////////////////////////////////
void InitUART2(void)
{
reMapPinOfUART2(); // 重新配置UART2的端口,在些应用中使用到了RXD和TXD两个引脚,其他引脚未使用
#ifdef RS485
Init_Pin_485();
#endif
// 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.RXINV = 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 = (32M/(16*9600))-1
// U2BRG = 240
U2BRG = 103; // 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; // 清除发送中断标志
IEC1bits.U2TXIE = 1; // 使能发送中断
IFS1bits.U2RXIF = 0; // 清除接收中断标志
IEC1bits.U2RXIE = 1; // 使能接收中断
U2MODEbits.UARTEN = 1; // 使能串口模块
U2STAbits.UTXEN = 1;
// I think I have the thing working now.
}
3.主程序代码
/////////////////////////////////////////////////////////////
// 主函数
/////////////////////////////////////////////////////////////
int main(void)
{
InitClock(); // 重新配置系统时钟
InitUART1(); // 初始化串口1
//InitUART2(); // 初始化串口2
UART1_SendString("Hellow World!\r\n");
while(1)
{
DelayTest();
}
return (1);
}
////////////////////////////////////////////////////////////
// 时钟配置函数
////////////////////////////////////////////////////////////
void InitClock(void)
{
CLKDIVbits.RCDIV = 0; // 不分频
RCONbits.SWDTEN = 0; // 关看门狗
// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to
// XT with PLL *4 (NOSC=0b011) 8 * 4MHz
__builtin_write_OSCCONL(0x01); // Start clock switching
while (OSCCONbits.COSC != 0b011); // Wait for Clock switch to occur
while(OSCCONbits.LOCK != 1) {}; // 等待PLL稳定
}
相信用以上代码应该足够了,请用过的大侠指点一下,十分感谢!