Mình viết đoạn code này để xuất một chuỗi kí tự và số lên trên máy tính, quá trình truyền là ok. Tuy nhiên, khi dùng hàm delay_us hay delay_ms qua trình truyền lại không xảy ra.
Đây là code :
#include<p33fj256gp710.h>
#include<stdio.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 Crystal
//unsigned int a,b,c,d;
#define ms_count 125 ;
unsigned int time_out,m,x,y;
unsigned char sbuf[200],c='C',t='T';
void __attribute__ ((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
LATA = U1RXREG;
IFS0bits.U1RXIF = 0; //interrupt request has not occurred
}
void __attribute__ ((interrupt, no_auto_psv)) _U1TXInterrupt(void) {
IFS0bits.U1TXIF = 0;
}
void InitClock() {
PLLFBD = 38; // M = 40
CLKDIVbits.PLLPOST = 0; // N1 = 2
CLKDIVbits.PLLPRE = 0; // N2 = 2
OSCTUN = 0;//khong su dung oscillator tuning register
RCONbits.SWDTEN = 0; // disabe watch dog timer
// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x01); // Initiate Clock Switch to FRC with PLL (NOSC=0b001)
// luu y : doc thanh ghi OSCCON de thay
__builtin_write_OSCCONL(0x01); // Start clock switching
//ghi lan luot vao 8 bit cao va thap cua OSCCON
while (OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur
while(OSCCONbits.LOCK != 1) {}; //pll lock status bit
}
void InitUART1() {
// configure U2MODE
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U2MODEbits.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.URXINV = 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
// Baud Rate Generator is for 9600.
// See section 19.3.1 of datasheet.
// U1BRG = (Fcy/(16*BaudRate))-1
// U1BRG = (37M/(16*9600))-1
// U1BRG = 240
U1BRG = 239; // 40Mhz osc, 9600 Baud, baud rate = Fcy/[16x(UxBRG+1)]
// 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
//U2STAbits.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*
IPC7 = 0x4400; // Mid Range Interrupt Priority level, no urgent reason
IFS0bits.U1TXIF = 0; // Clear the Transmit Interrupt Flag
IEC0bits.U1TXIE = 1; // Enable Transmit Interrupts
IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag
IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts
U1MODEbits.UARTEN = 1; // And turn the peripheral on
U1STAbits.UTXEN = 1;
}
int main(void) {
InitClock(); // This is the PLL settings
InitUART1(); // Initialize UART2 for 9600,8,N,1 TX/RX
while(1){ // The ever versatile Infinite Loop!
sprintf(sbuf,"%c%c %i %i %i %i %i %i \n",'T','C',20,40,40,60,30,10);
putsUART1(sbuf);
}
}
/************************************************** *************************
* Function Name : putsUART1 *
* Description : This function puts the data string to be transmitted *
* into the transmit buffer (till NULL character) *
* Parameters : unsigned int * address of the string buffer to be *
* transmitted *
* Return Value : None *
************************************************** *************************/
void putsUART1(unsigned int *buffer)
{
char * temp_ptr = (char *) buffer;
/* transmit till NULL character is encountered */
if(U1MODEbits.PDSEL == 3) /* check if TX is 8bits or 9bits */
{
while(*buffer != '\0')
{
while(U1STAbits.UTXBF); /* wait if the buffer is full */
U1TXREG = *buffer++; /* transfer data word to TX reg */
delay_us(100);
}
}
else
{
while(*temp_ptr != '\0')
{
while(U1STAbits.UTXBF); /* wait if the buffer is full */
U1TXREG = *temp_ptr++; /* transfer data byte to TX reg */
delay_us(100);
}
}
}
/************************************************** *****************************************
//Function: void Init_TMR1(void)
//Input: None
//Output: Setup Parameter to Timer1 Operate
// TMR1 use for delay
************************************************** *****************************************/
void Init_TMR1(void)
{
T1CONbits.TON=0; //Stop Timer1
T1CONbits.TGATE=0; //Disable Gated Timer mode
T1CONbits.TCKPS=2; //Select Prescale 1:1
T1CONbits.TCS=0; //Internal clock
PR1=ms_count;
_T1IF=0;
_T1IE=1;
TMR1=0;
}
/************************************************** *****************************************
//Function: void delay_us(unsigned int n)
//Input: n: n us to delay
//Output: Delay n us
************************************************** *****************************************/
void delay_us(unsigned int n)
{
PR1=n*ms_count;
time_out=0;
T1CONbits.TON=1;
while(time_out==0);
T1CONbits.TON = 0;
TMR1=0;
}
/************************************************** *****************************************
//Function: void delay_ms(unsigned int n)
//Input: n: n ms to delay
//Output: Delay n ms
************************************************** *****************************************/
void delay_ms(unsigned int n)
{
unsigned int i;
i=0;
while(i<=n)
{
delay_us(1000);
i++;
}
}
void _ISR _T1Interrupt(void)
{
_T1IF = 0; //Clear Timer1 flag
time_out = 1;
}
|