主题中讨论的其他器件:MSP430F2274、 MSP-FET
您好!
我正在尝试对 LMX2694 PLL 进行编程。 我有用于它的 EVAL 板以及用于微控制器 MSP430F2274的 EVAL 板。 我使用 N5181信号发生器作为参考振荡器信号。 在使用 MSP-FET 和 TI Code Composer Studio 构建我的项目并将代码加载到微控制器时、PLL 似乎不会输出它应该输出的信号(在频谱分析仪上看不到任何信号); 但是、当我在代码中放置断点然后运行它时、PLL 似乎能够输出信号(在所选频率的频谱分析仪上可以看到锁定信号)。
我将介绍我用来使 PLL 不工作和工作的两个过程。 在这两种情况下、我都有一个为 PLL 的 EVAL 板供电的电源:
PLL 不能用于以下过程:
(1)打开 PLL 电源。
(2)将插入的代码加载到微控制器中。 然后微控制器打开并执行整个 int main()。
(3) PLL 不会在频谱分析仪上显示信号。
PLL 使用以下过程:
(1)在调试模式下将插入的代码加载到微控制器中。
(2)加载插入的代码后按"Resume"、int main()将运行到第261行的断点。
(3)此时、微控制器应该已经完成了 CPU 时钟、SPI 总线和 GPIO 端口的初始化。
(4)打开 PLL 电源。
(5)按"恢复"。
(6)代码一直运行到代码末尾第266行上的断点(返回0)。
(7) PLL 能够显示频谱分析仪检测到的信号。
我感觉 PLL 上电时的初始化例程在某种程度上阻止了 PLL 的正确编程。 是这样吗? 当我运行只针对 PLL 的代码时、PLL 看起来工作正常。 也许微控制器会将信号输出到 SPI 总线、以便在 PLL 上电时使其发生混淆? 我可以对此做些什么、还是有人可能提出任何建议? 我认为、微控制器在现场启动后、不会有用于切换 PLL 功率的选项。 谢谢!!
#include <msp430.h>
#include <stdint.h>
int i;
unsigned int j;
unsigned int t;
volatile char dummy = 0;
volatile char probe1 = 0;
volatile char probe2 = 0;
volatile char probe3 = 0;
volatile char probe4 = 0;
volatile char probe5 = 0;
volatile char probe6 = 0;
volatile char probe7 = 0;
volatile char probe8 = 0;
uint8_t reg_matrix[80][3] =
{
{0x00, 0x21, 0x14},
{0x01, 0x08, 0x0C},
{0x02, 0x05, 0x00},
{0x03, 0x06, 0x42},
{0x04, 0x0E, 0x43},
{0x05, 0x03, 0xE8},
{0x06, 0x78, 0x02},
{0x07, 0x00, 0xB2},
{0x08, 0x20, 0x00},
{0x09, 0x16, 0x04},
{0x0A, 0x10, 0xD8},
{0x0B, 0x00, 0x18},
{0x0C, 0x50, 0x01},
{0x0D, 0x40, 0x00},
{0x0E, 0x1E, 0x70},
{0x0F, 0x06, 0x4F},
{0x10, 0x00, 0x80},
{0x11, 0x01, 0x2C},
{0x12, 0x00, 0x64},
{0x13, 0x27, 0xB7},
{0x14, 0xF8, 0x48},
{0x15, 0x04, 0x01},
{0x16, 0x00, 0x01},
{0x17, 0x00, 0x7C},
{0x18, 0x07, 0x1A},
{0x19, 0x06, 0x24},
{0x1A, 0x0D, 0xB0},
{0x1B, 0x00, 0x02},
{0x1C, 0x04, 0x88},
{0x1D, 0x31, 0x8C},
{0x1E, 0x31, 0x8C},
{0x1F, 0x43, 0xEC},
{0x20, 0x03, 0x93},
{0x21, 0x1E, 0x21},
{0x22, 0x00, 0x00},
{0x23, 0x00, 0x04},
{0x24, 0x00, 0x36},
{0x25, 0x84, 0x04},
{0x26, 0xFD, 0x51},
{0x27, 0xDA, 0x80},
{0x28, 0x00, 0x00},
{0x29, 0x00, 0x00},
{0x2A, 0x00, 0x00},
{0x2B, 0x00, 0x00},
{0x2C, 0x1F, 0x63},
{0x2D, 0xC8, 0xDF},
{0x2E, 0x07, 0xFD},
{0x2F, 0x03, 0x00},
{0x30, 0x03, 0x00},
{0x31, 0x41, 0x80},
{0x32, 0x00, 0x00},
{0x33, 0x00, 0x80},
{0x34, 0x04, 0x20},
{0x35, 0x00, 0x00},
{0x36, 0x00, 0x00},
{0x37, 0x00, 0x00},
{0x38, 0x00, 0x00},
{0x39, 0x00, 0x20},
{0x3A, 0x80, 0x01},
{0x3B, 0x00, 0x01},
{0x3C, 0x09, 0xC4},
{0x3D, 0x00, 0xA8},
{0x3E, 0x03, 0x22},
{0x3F, 0x00, 0x00},
{0x40, 0x13, 0x88},
{0x41, 0x00, 0x00},
{0x42, 0x01, 0xF4},
{0x43, 0x00, 0x00},
{0x44, 0x03, 0xE8},
{0x45, 0x00, 0x00},
{0x46, 0xC3, 0x50},
{0x47, 0x00, 0x80},
{0x48, 0x00, 0x01},
{0x49, 0x00, 0x3F},
{0x4A, 0x00, 0x00},
{0x4B, 0x08, 0x00},
{0x4C, 0x00, 0x0C},
{0x4D, 0x00, 0x00},
{0x4E, 0x00, 0x64},
{0x4F, 0x00, 0x00}
};
void delay(unsigned int count)
{
//P3OUT = 0x00;
for (t = 0; t<count; ++t)
{
}
//P3OUT = 0x08;
}
void initClockTo16MHz()
{
if (CALBC1_16MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_16MHZ; // Set DCO
DCOCTL = CALDCO_16MHZ;
}
void initSPI()
{
UCA0CTL1 |= UCSWRST; //Performs a software reset on A0.
UCA0CTL1 |= UCSSEL_2; //Using SMCLK.
UCA0BR0 = 0x0A; //Divide by 10 (both UCA0BR0 and UCA0BR1 on the next line set this).
UCA0BR1 = 0;
UCA0MCTL = 0; //Modulation not used in SPI mode. Clearing UCA0MCTL register.
UCA0CTL0 = 0xAB; //UCCKPH + !UCCKPL + UCMSB + !UC7BIT + UCMST + 4-pin SPI w. ACTIVE Master (2 bits) + Synchronous.
//UCA0CTL1 = 0x00; //Releases the module from being in reset mode and initializes the USCI state machine.
}
void initGPIO()
{
//initialize GPIO
P3OUT = 0x00; //Reset all channels on port 3.
P3OUT = 0x0C;
P3DIR = 0x0C; //Configures P3.2 and P3.3 channels to be outputs.
P3SEL = 0x11; //Configures channel 0 to be in UC0CLK mode, channel 4 to be in UC0SIMO mode, and all other channels to be in I/O mode.
ADC10AE0 = 0;
//Configure all unused ports to be reset, and configured as outputs in I/O mode to reduce power consumption.
P1OUT = 0x00;
P2OUT = 0x00;
P4OUT = 0x00;
P1DIR = 0xFF;
P2DIR = 0xFF;
P4DIR = 0xFF;
P1SEL = 0x00;
P2SEL = 0x00;
P4SEL = 0x00;
UCA0CTL1 &= ~UCSWRST; //Releases the module from being in reset mode and initializes the USCI state machine.
}
//void writeSPI(char addr, char value)
//{
// TI_CC_CSn_PxOUT &= ~TI_CC_CSn_PIN; // /CS enable
// while (TI_CC_SPI_USCIB0_PxIN&TI_CC_SPI_USCIB0_SOMI);// Wait for CCxxxx ready
// IFG2 &= ~UCB0RXIFG; // Clear flag
// UCB0TXBUF = addr; // Send address
// while (!(IFG2&UCB0RXIFG)); // Wait for TX to finish
// IFG2 &= ~UCB0RXIFG; // Clear flag
// UCB0TXBUF = value; // Send data
// while (!(IFG2&UCB0RXIFG)); // Wait for TX to finish
// TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable
//}
void init_mainPLL()
{
//Resets the PLL
P3OUT = 0x00; //Select main PLL
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0b00000000;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00100001;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00010110;
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF; //Read back from RXBuffer.
while (!(IFG2 & UCA0TXIFG)); //Ensure buffer is empty before unselecting main PLL
delay(7); //Delay to allow bits to transfer to PLL
P3OUT = 0x08; //Unselect main PLL
//Removes reset on PLL
P3OUT = 0x00; //Select main PLL
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0b00000000;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00100001;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00010100;
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF; //Read back from RXBuffer
while (!(IFG2 & UCA0TXIFG)); //Ensure buffer is empty before unselecting main PLL
delay(7); //Delay to allow bits to transfer to PLL
P3OUT = 0x08; //Unselect main PLL
}
void program_mainPLL()
{
for (i = 79; i>-1; --i)
{
P3OUT = 0x00; //Select main PLL
for (j = 0; j<3; ++j)
{
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = reg_matrix[i][j]; //Send byte
}
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF; //Read back from RXBuffer
while (!(IFG2 & UCA0TXIFG));
delay(7);
P3OUT = 0x08; //Unselect main PLL
}
}
void ready_mainPLL()
{
P3OUT = 0x00; //Select main PLL
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0x00;
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0x21;
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0x1C;
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG));
delay(7);
P3OUT = 0x08; //Unselect main PLL
}
void testloop()
{
while(1)
{
while (!(IFG2 & UCA0TXIFG));
//IFG2 |= UCA0TXIFG;
probe1 = IFG2;
probe2 = !(IFG2 & UCA0TXIFG);
probe3 = UCA0TXBUF;
probe4 = UCA0RXBUF;
UCA0TXBUF = 0x4D;
//IFG2 |= UCA0TXIFG;
probe5 = IFG2;
probe6 = !(IFG2 & UCA0TXIFG);
probe7 = UCA0TXBUF;
probe8 = UCA0RXBUF;
}
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; //Stop watchdog timer
initClockTo16MHz();
initSPI();
initGPIO();
//testloop();
init_mainPLL();
program_mainPLL();
delay(1500);
ready_mainPLL();
return 0;
}