This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具与软件:
我是一名学生、目前正在从事一个涉及 MSP430FR5994微控制器的项目。 我的任务是实现 UART 通信、以将数据从微控制器发送到我的 PC。 验证我的 C 代码。
发送字符时接收效果很好、但发送整数时遇到问题。 令人惊讶的是、我根本没有收到任何消息、甚至指示数据传输的 LED 也不会切换。
以下是我使用的 C 代码:
#包含
#包含
///详细说明
void initClock (void);
void initUART (void);
void initPort (void);
void sendBuffer (void);
int main (void){
//停止看门狗计时器
WDTCTL = WDTPW + WDTHOLD;
//初始化事件
initClock();
initPort();
inituart();
while (1){
//通过 UART 发送预定义的缓冲区
sendBuffer();
P1OUT ^= BIT0;//切换 LED 以指示正在发送数据
__delay_cycles (1000000);//添加延迟以避免循环过快
}
返回0;
}
//初始化
void initClock (void){
CSCTL0_H = CSKEY >> 8;// D é verrouillage du module CS
CSCTL1 = DCOFSEL_6;// S é lection de DCO à 8 MHz (selon la documentation MSP430)
CSCTL2 = SELM__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;//配置地址源
CSCTL3 = DIVA__1 | DIVS__1 | DIVM_1;//重组
CSCTL0_H = 0;//应对模块 CS
}
//初始化 UART
void initUART (void){
UCA0CTLW0 = UCSWRST;//将 à 重新初始化模块 UART
P2SEL0 &=~(BIT0 | BIT1);//配置加密产品 P2.0 et P2.1
P2SEL1 |=(BIT0 | BIT1);
UCA0CTLW0 |= UCSSEL_SMCLK;// SMCLK 通信源模块 UART
UCA0BRW = 52;//配置 du d é bit en bauds à 9600 bauds
UCA0MCTLW = UCOS16 | UCBRF_1 | 0x49;//配置 DES paramètres DE 调制
UCA0CTLW0 &=~UCSWRST;//错误地进行重新初始化
UCA0IE |= UCRXIE;//激活中断接收 UART
}
//初始化 DES 端口 GPIO
void initPort (void){
P1OUT = 0x00;
P1DIR = 0xFF;
P1OUT |= BIT0;
P2OUT = 0x00;
P2DIR = 0xFF;
P3OUT = 0x00;
P3DIR = 0xFF;
P4OUT = 0x00;
P4DIR = 0xFF;
P5OUT = 0x00;
P5DIR = 0xFF;
P6OUT = 0x00;
P6DIR = 0xFF;
P7OUT = 0x00;
P7DIR = 0xFF;
P8OUT = 0x04;
P8DIR = 0xFF;
P9OUT = 0x00;
P9DIR = 0xFF;
PAOUT = 0x00;
PADIR = 0xFF;
PBOUT = 0x00;
PBDIR = 0xFF;
PCOUT = 0x00;
PCDIR = 0xFF;
PDOUT = 0x00;
PDDIR = 0xFF;
PEOUT = 0x00;
PEDIR = 0xFF;
PJOUT = 0x00;
PJDIR = 0xFF;
P2SEL0 &=~(BIT0 | BIT1);
P2SEL1 |=(BIT0 | BIT1);
}
//通过 UART 发送预定义缓冲器的函数
void sendBuffer (void){
//要发送的数据缓冲区
uint8_t buffer[]={0x01、0x02、0x03、0x04、0x05};
//通过 UART 发送缓冲区
INT I;
对于(i = 0;i < sizeof (buffer);i++){
//等待传输寄存器准备就绪
while (! (UCA0IFG & UCTXIFG));
//发送缓冲元素
UCA0TXBUF =缓冲器[i];
//等待传输完成
while (UCA0STATW 和 UCBUSY);
}
}
如果深入了解可能导致此问题的原因以及如何解决此问题、我将不胜感激。 此外、如果您对我的 C 代码有任何建议或改进、我将非常感谢您提供宝贵意见。
感谢您的参与和协助!
您是说、如果您更改
uint8_t buffer[]={0x01、0x02、0x03、0x04、0x05};
至
uint8_t buffer []={'h'、'e'、'l'、'l'、'o'};
它的工作原理是什么?
您不需要同时进行忙时等待、第一个:while (! (UCA0IFG & UCTXIFG));应该足够了。
那么什么代码"当我发送字符完美工作"? 从这里开始。 此外、还可以查看基于中断的 UART 回显示例。
我使用了另一个代码用于发送字符。 它将整数转换为字符并逐个发送。
我想您的意思是使用 sprintf()之类的东西创建整数的 ASCII 字符串。 但现在您希望直接发送整数。
采用原始程序。 只需直接发送整数即可。 这样可以吗?
如果是、现在只需为数组中的每个字符生成循环。
对于此处粘贴的代码:
您是否删除了
while (UCA0STATW 和 UCBUSY);
忙等待?
您的原始代码可以很好地满足我的要求。 我必须对我可用的 MSP430FR2311的引脚和时钟进行一些更改。
#include <msp430.h> #include <stdint.h> void Software_Trim(); // Software Trim to get the best DCOFTRIM value #define MCLK_FREQ_MHZ 8 // MCLK = 8MHz // Déclarations des fonctions void initUART(void); void initPort(void); void sendBuffer(void); int main(void) { // Stop watchdog timer WDTCTL = WDTPW + WDTHOLD; // Initialisation des périphériques initPort(); PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode // to activate 1previously configured port settings __bis_SR_register(SCG0); // disable FLL CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3; // DCOFTRIM=3, DCO Range = 8MHz CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz __delay_cycles(3); __bic_SR_register(SCG0); // enable FLL Software_Trim(); // Software Trim to get the best DCOFTRIM value CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz // default DCODIV as MCLK and SMCLK source initUART(); while (1) { // Send a predefined buffer via UART sendBuffer(); P1OUT ^= BIT0; // Toggle LED to indicate sending data __delay_cycles(1000000); // Add a delay to avoid too fast a loop } } // Initialisation de l'horloge void Software_Trim() { unsigned int oldDcoTap = 0xffff; unsigned int newDcoTap = 0xffff; unsigned int newDcoDelta = 0xffff; unsigned int bestDcoDelta = 0xffff; unsigned int csCtl0Copy = 0; unsigned int csCtl1Copy = 0; unsigned int csCtl0Read = 0; unsigned int csCtl1Read = 0; unsigned int dcoFreqTrim = 3; unsigned char endLoop = 0; do { CSCTL0 = 0x100; // DCO Tap = 256 do { CSCTL7 &= ~DCOFFG; // Clear DCO fault flag } while (CSCTL7 & DCOFFG); // Test DCO fault flag __delay_cycles((unsigned int) 3000 * MCLK_FREQ_MHZ); // Wait FLL lock status (FLLUNLOCK) to be stable // Suggest to wait 24 cycles of divided FLL reference clock while ((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0)) ; csCtl0Read = CSCTL0; // Read CSCTL0 csCtl1Read = CSCTL1; // Read CSCTL1 oldDcoTap = newDcoTap; // Record DCOTAP value of last time newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time dcoFreqTrim = (csCtl1Read & 0x0070) >> 4; // Get DCOFTRIM value if (newDcoTap < 256) // DCOTAP < 256 { newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256 if ((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256 endLoop = 1; // Stop while loop else { dcoFreqTrim--; CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim << 4); } } else // DCOTAP >= 256 { newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256 if (oldDcoTap < 256) // DCOTAP cross 256 endLoop = 1; // Stop while loop else { dcoFreqTrim++; CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim << 4); } } if (newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256 { csCtl0Copy = csCtl0Read; csCtl1Copy = csCtl1Read; bestDcoDelta = newDcoDelta; } } while (endLoop == 0); // Poll until endLoop == 1 CSCTL0 = csCtl0Copy; // Reload locked DCOTAP CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM while (CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) ; // Poll until FLL is locked } // Initialisation de l'UART void initUART(void) { // Configure UART pins P1SEL0 |= BIT6 | BIT7; // set 2-UART pin as second function UCA0CTLW0 = UCSWRST; // Mise à la réinitialisation du module UART UCA0CTLW0 |= UCSSEL__SMCLK; // Sélection de SMCLK comme source d'horloge UART UCA0BRW = 52; // Configuration du débit en bauds à 9600 bauds UCA0MCTLW = UCOS16 | UCBRF_1 | 0x49; // Configuration des paramètres de modulation UCA0CTLW0 &= ~UCSWRST; // Sortie de la réinitialisation UCA0IE |= UCRXIE; // Activation des interruptions de réception UART } // Initialisation des ports GPIO void initPort(void) { P1OUT = 0x00; P1DIR = 0xFF; P1OUT |= BIT0; P2OUT = 0x00; P2DIR = 0xFF; PAOUT = 0x00; PADIR = 0xFF; PJOUT = 0x00; PJDIR = 0xFF; P2SEL0 &= ~(BIT0 | BIT1); P2SEL1 |= (BIT0 | BIT1); } // Function to send a predefined buffer via UART void sendBuffer(void) { // Data buffer to send uint8_t buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05 }; // Send buffer via UART int i; for (i = 0; i < (sizeof(buffer)); i++) { // Wait until transmission register is ready while (!(UCA0IFG & UCTXIFG)) ; // Send buffer element UCA0TXBUF = buffer[i]; // Wait until transmission is complete while (UCA0STATW & UCBUSY) ; } }
通常情况下发生这种情况时-特别是当 LED 停止切换时-这意味着你得到一个中断、在存根我看到你正在激活 UART 接收中断时、将你发送到无尽的中断。 如果接收到任何没有处理程序的字符、则可能会发生这种情况。
此外,注释掉你的 sendBuffer()函数,看看延迟环路+ LED 是否有效。 否则、您遇到时钟或其他问题。
我终于解决了它。 实际上,问题在于 UART 配置(应配置 MSB),并且函数 sizeof(Buffer)未向 IDE 返回精确值,因此未 处理 for Loop 。 感谢您的帮助
我看了看 sizeof ()的东西,但由于 sizeof (uint8_t )是1 ,它似乎是可以的。