工具/软件:TI C/C++编译器
我创建了一个程序、在该程序中使用 MSP432设置 UART、但无法使 UART 正常工作、能否有人帮助我配置 UART。 或者向我展示一个示例、其中它使用中断、而不使用中断
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.
工具/软件:TI C/C++编译器
我创建了一个程序、在该程序中使用 MSP432设置 UART、但无法使 UART 正常工作、能否有人帮助我配置 UART。 或者向我展示一个示例、其中它使用中断、而不使用中断
UART.c
/*UART 配置*/ void UART_init (void){ /*配置 UART*/ EUSCI_A2->CTLW0 |= EUSCI_A_CTLW0_SWRST; /*将 EUSCI 置于复位状态*/ EUSCI_A2->CTLW0 = EUSCI_A_CTLW0_SWRST | /*在复位时保持 EUSCI */ EUSCI_B_CTLW0_ssel_SMCLK; /*配置 EUSCI 时钟 SMCLK*/ /*波特率计算 *12000000/(16*9600)=78.125 *分数部分= 0.125 *用户指南表21-4:UCBRSx = 0x10 *UCBRFx=int (78.125-78)*16)=2. * EUSCI_A2->BRW = 78; /*12000000/16/9600*/ EUSCI_A2->MCTLW =(2 << EUSCI_A_MCTLW_BRF_OFS)| EUSCI_A_MCTLW_OS16; EUSCI_A2->CTLW0 &=~(EUSCI_A_CTLW0_SWRST); /*初始化 EUSCI*/ EUSCI_A2->IFG &=~(EUSCI_A_IFG_RXIFG); EUSCI_A2->IE |= EUSCI_A_IE_RXIE; /*启用 UART RX 中断*/ /*启用全局中断*/ __ENABLE_IRQ(); /*在 EUSCI_A2中断中启用 NVIC */ NVIC->ISER[0]= 1 <<((EUSCIA2_IRQn)& 31); } /* UART 端口*/ void confg_UART_wired (void){ P3->SEL0 |= UART_TX | UART_RX; /*将2个 UART 引脚设置为第二功能*/ }/*UART 时钟系统*/ void UART_cs (void){ CS->KEY = CS_KEY_VAL; /*解锁 CS 模块寄存器访问*/ CS->CTL0 = 0; /*重置调整参数*/ CS->CTL0 = CS_CTL0_DCORSEL_3; /*将 DCO 设置为12MHz (标称值,8-16MHz 范围的中心)*/ CS->CTL1 = CS_CTL1_SERA_2 | /*选择 ACLK = REFO*/ CS_CTL1_SELS _3 | /*SMCLK = DCO*/ CS_CTL1_SELM_3; /*MCLK = DCO*/ CS->KEY = 0; } 空 EUSCIA2_IRQHandler (空){ if (EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG){ LED_PyOUT (G_LED); } if (EUSCI_A2->IFG & EUSCI_A_IFG_TXIFG){ LED_PyOUT (R_LED); /*点亮 RX*/ }上的 P2.x LED }
main.c
void main (void){
/*清除所有 LED RGB/
LED_PxCLR (R_LED_G_LED_B_LED);
LED_PyDIR (R_LED|G_LED|B_LED);
看门狗狗犬;
UART_CS();
confg_UART_wired();
UART_INIT();
while (1){
}
}
void WatchDogHold (void){WDTCTL
= WDTPW | WDTHOLD;/*停止看门狗计时器*/
}
Bruce McKenney 首先 感谢您的帮助。
我正在尝试安装一个程序、该程序通过 UART 向蓝牙模块发送数据(文本)。 R_LED 和 G_LED 分配给 MSP432卡、仅用于调试。 验证这个发送或接收、但是我不理解 RXIFG 和 TXIFG 的操作、如果我已经很清楚中断的部分可以按如下方式完成:
void EUSCIA2_IRQHandler (void){ if (EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG){ LED_PyOUT (G_LED); /*点亮 RX*/上的 P2.1 LED EUSCI_A2->IFG &=~(EUSCI_A_IFG_RXIFG); } if (EUSCI_A2->IFG & EUSCI_A_IFG_TXIFG){ LED_PyOUT (R_LED); /*在 TX*/上点亮 P2.0 LED while (!(EUSCI_A2->IFG 和 EUSCI_A_IFG_TXIFG)); } }
这可能是许多其他用户的疑问、在解决此问题后、我将提供资源、以便能够帮助遇到相同问题的每个人。
好的、我根据您告诉我的内容进行了一些修改和实施
UART.c
char RX_Buffer[]; int buffer_count = 0; /*UART 配置*/ void UART_init (void){ /*配置 UART*/ EUSCI_A2->CTLW0 |= EUSCI_A_CTLW0_SWRST; /*将 EUSCI 置于复位状态*/ EUSCI_A2->CTLW0 = EUSCI_A_CTLW0_SWRST | /*在复位时保持 EUSCI */ EUSCI_B_CTLW0_ssel_SMCLK; /*配置 EUSCI 时钟 SMCLK*/ /*波特率计算 *12000000/(16*9600)=78.125 *分数部分= 0.125 *用户指南表21-4:UCBRSx = 0x10 *UCBRFx=int (78.125-78)*16)=2. * EUSCI_A2->BRW = 78; /*12000000/16/9600*/ EUSCI_A2->MCTLW =(2 << EUSCI_A_MCTLW_BRF_OFS)| EUSCI_A_MCTLW_OS16; EUSCI_A2->CTLW0 &=~(EUSCI_A_CTLW0_SWRST); /*初始化 EUSCI*/ EUSCI_A2->IFG &=~(EUSCI_A_IFG_RXIFG); EUSCI_A2->IE |= EUSCI_A_IE_RXIE; /*启用 UART RX 中断*/ /*启用全局中断*/ __ENABLE_IRQ(); /*在 EUSCI_A2中断中启用 NVIC */ NVIC->ISER[0]= 1 <<((EUSCIA2_IRQn)& 31); } /* UART 端口*/ void confg_UART_wired (void){ P3->SEL0 |= UART_TX | UART_RX; /*将2个 UART 引脚设置为第二功能*/ }/*UART 时钟系统*/ void UART_cs (void){ CS->KEY = CS_KEY_VAL; /*解锁 CS 模块寄存器访问*/ CS->CTL0 = 0; /*重置调整参数*/ CS->CTL0 = CS_CTL0_DCORSEL_3; /*将 DCO 设置为12MHz (标称值,8-16MHz 范围的中心)*/ CS->CTL1 = CS_CTL1_SERA_2 | /*选择 ACLK = REFO*/ CS_CTL1_SELS _3 | /*SMCLK = DCO*/ CS_CTL1_SELM_3; /*MCLK = DCO*/ CS->KEY = 0; }/* 系统时钟为3MHz*/ void delayM(int n)时的延迟毫秒{ int i、j; for (j=0;j < n;j++); for (i= 750;i>0;i--); }/*UART 计数卡阻发送*/ void UART_c_String (char *c){ int i; for (i=0;c[i];i++){ Buffer_count++; } UART_SEND (c、buffer_count); } /*UART 发送多个字节*/ void UART_SEND (unsigned char * pucData、unsigned char ucLength){ while (ucLength){ /*等待 TX 缓冲区为新数据做好准备*/ while (!(EUSCI_A2->IFG 和 EUSCI_A_IFG_TXIFG)); /*检查是否未设置*/ /*如果置位,则 TX 中断正暂挂*/ EUSCI_A2->TXBUF =*数据; /*将数据推送到 TX 缓冲区*/ ucLength ----; /*剩余数据长度*/ pucData++; /*shift pointer */ } /*等待最后一个字节完全发送*/ while (EUSCI_A2->STATW 和 EUSCI_A_STATW_BUSY); /*这表示 EUSCI 是发送还是接收*/ }/*UART 获取多个字节*/ void UART_GET (void){ RX_Buffer[buffer_count]= EUSCI_A2->RXBUF; if (++buffer_count >= 2){ Buffer_count = 0; EUSCI_A2->IFG &=~(EUSCI_A_IFG_RXIFG); /*重置 RX 标志*/ } } 空 EUSCIA2_IRQHandler (空){ if (EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG){ UART_GET(); /*点亮 RX*/上的 P2.1 LED LED_PyOUT (G_LED); } if (EUSCI_A2->IFG & EUSCI_A_IFG_TXIFG){ EUSCI_A2->IFG &=~(EUSCI_A_IFG_TXIFG); LED_PyOUT (R_LED); /*点亮 RX*/ }上的 P2.0 LED }
main.c
void main (void){
/*清除所有 LED RGB/
LED_PxCLR (R_LED_G_LED_B_LED);
LED_PyDIR (R_LED|G_LED|B_LED);
看门狗狗犬;
UART_CS();
confg_UART_wired();
UART_INIT();
UART_c_String ("Hello World!");
while (1){
}
}
void WatchDogHold (void){WDTCTL
= WDTPW | WDTHOLD;/*停止看门狗计时器*/
}
好的、Bruce、
我已经完成了您告诉我的操作、但我已经声明 char RX_Buffer[]、因为在 main 中调用函数"uart_c_String()"、在这里我传递我想要发送的整个文本、因此该函数会对字符进行计数并将它们传递到"UART_SEND ()"函数、在这里动态地重新填充缓冲区。 这是否是一种不良做法?
UART.c
#include "MSP.h" #include "UART.h" #include "main.h" #include #include char RX_Buffer[2]; int buffer_count = 0; /*UART 配置*/ void UART_init (void){ /*配置 UART*/ EUSCI_A2->CTLW0 |= EUSCI_A_CTLW0_SWRST; /*将 EUSCI 置于复位状态*/ EUSCI_A2->CTLW0 = EUSCI_A_CTLW0_SWRST | /*在复位时保持 EUSCI */ EUSCI_B_CTLW0_ssel_SMCLK; /*配置 EUSCI 时钟 SMCLK*/ /*波特率计算 *12000000/(16*9600)=78.125 *分数部分= 0.125 *用户指南表21-4:UCBRSx = 0x10 *UCBRFx=int (78.125-78)*16)=2. * EUSCI_A2->BRW = 78; /*12000000/16/9600*/ EUSCI_A2->MCTLW =(2 << EUSCI_A_MCTLW_BRF_OFS)| EUSCI_A_MCTLW_OS16; EUSCI_A2->CTLW0 &=~(EUSCI_A_CTLW0_SWRST); /*初始化 EUSCI*/ EUSCI_A2->IFG &=~(EUSCI_A_IFG_RXIFG); EUSCI_A2->IE |= EUSCI_A_IE_RXIE; /*启用 UART RX 中断*/ /*启用全局中断*/ __ENABLE_IRQ(); /*在 EUSCI_A2中断中启用 NVIC */ NVIC->ISER[0]= 1 <<((EUSCIA2_IRQn)& 31); } /* UART 端口*/ void confg_UART_wired (void){ P3->SEL0 |= UART_TX | UART_RX; /*将2个 UART 引脚设置为第二功能*/ }/*UART 时钟系统*/ void UART_cs (void){ CS->KEY = CS_KEY_VAL; /*解锁 CS 模块寄存器访问*/ CS->CTL0 = 0; /*重置调整参数*/ CS->CTL0 = CS_CTL0_DCORSEL_3; /*将 DCO 设置为12MHz (标称值,8-16MHz 范围的中心)*/ CS->CTL1 = CS_CTL1_SERA_2 | /*选择 ACLK = REFO*/ CS_CTL1_SELS _3 | /*SMCLK = DCO*/ CS_CTL1_SELM_3; /*MCLK = DCO*/ CS->KEY = 0; }/* 系统时钟为3MHz*/ void delayM(int n)时的延迟毫秒{ int i、j; for (j=0;j < n;j++); for (i= 750;i>0;i--); }/*UART 计数卡阻发送*/ void UART_c_String (char *c){ int i; for (i=0;c[i];i++){ Buffer_count++; } UART_SEND (c、buffer_count); } /*UART 发送多个字节*/ void UART_SEND (unsigned char * pucData、unsigned char ucLength){ while (ucLength){ /*等待 TX 缓冲区为新数据做好准备*/ while (!(EUSCI_A2->IFG 和 EUSCI_A_IFG_TXIFG)); /*检查是否未设置*/ /*如果置位,则 TX 中断正暂挂*/ EUSCI_A2->TXBUF =*数据; /*将数据推送到 TX 缓冲区*/ ucLength ----; /*剩余数据长度*/ pucData++; /*shift pointer */ } /*等待最后一个字节完全发送*/ while (EUSCI_A2->STATW 和 EUSCI_A_STATW_BUSY); /*这表示 EUSCI 是发送还是接收*/ }/*UART 获取多个字节*/ void UART_GET (void){ RX_Buffer[buffer_count]= EUSCI_A2->RXBUF; if (++buffer_count >= 2){ Buffer_count = 0; } } 空 EUSCIA2_IRQHandler (空){ if (EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG){ LED_PyOUT (G_LED); UART_GET(); } }
Bruce、
我做了一些更改、 串行发送的字符与蓝牙终端中计数的字符相同
UART.c
char input[100];
unsigned int RXByteCtr = 0;
/*UART 配置*/
void UART_init (void){
/*配置 UART*/
EUSCI_A2->CTLW0 |= EUSCI_A_CTLW0_SWRST; /*将 EUSCI 置于复位状态*/
EUSCI_A2->CTLW0 = EUSCI_A_CTLW0_SWRST | /*在复位时保持 EUSCI */
EUSCI_A_CTLW0_MODE_0|
EUSCI_A_CTLW0_ssel_SMCLK; /*配置 EUSCI 时钟 SMCLK*/
/*波特率计算
*12000000/(16*115200)=78.125
*分数部分= 0.125
*用户指南表21-4:UCBRSx = 0x10
*UCBRFx=int (78.125-78)*16)=2.
*
EUSCI_A2->BRW = 6; /*12000000/16/9600*/
EUSCI_A2->MCTLW =(8 << EUSCI_A_MCTLW_BRF_OFS)|
EUSCI_A_MCTLW_OS16;
EUSCI_A2->CTLW0 &=~(EUSCI_A_CTLW0_SWRST); /*初始化 EUSCI*/
EUSCI_A2->IFG &=~(EUSCI_A_IFG_RXIFG);
EUSCI_A2->IE |= EUSCI_A_IE_RXIE; /*启用 UART RX 中断*/
/*启用全局中断*/
__ENABLE_IRQ();
/*在 EUSCI_A2中断中启用 NVIC */
NVIC->ISER[0]= 1 <<((EUSCIA2_IRQn)& 31);
}
/* UART 端口*/
void confg_UART_wired (void){
P3->SEL0 |= UART_TX | UART_RX; /*将2个 UART 引脚设置为第二功能*/
}/*UART
时钟系统*/
void UART_cs (void){
CS->KEY = CS_KEY_VAL; /*解锁 CS 模块寄存器访问*/
CS->CTL0 = 0; /*重置调整参数*/
CS->CTL0 = CS_CTL0_DCORSEL_3; /*将 DCO 设置为12MHz (标称值,8-16MHz 范围的中心)*/
CS->CTL1 = CS_CTL1_SERA_2 | /*选择 ACLK = REFO*/
CS_CTL1_SELS _3 | /*SMCLK = DCO*/
CS_CTL1_SELM_3; /*MCLK = DCO*/
CS->KEY = 0;
}/*
系统时钟为3MHz*/
void delayM(int n)时的延迟毫秒{
int i、j;
for (j=0;j < n;j++);
for (i= 750;i>0;i--);
}
void UART_transmit (const char *str){
而(*str !=0){//do this during current element is not
//等于空字符
while (!(EUSCI_A2->IFG 和 EUSCI_A_IFG_TXIFG));
//确保发送中断标志被置位
EUSCI_A2->TXBUF =* str++;
//使用当前字符串元素加载 UCA0TXBUF
printf ("%c"、EUSCI_A2->TXBUF);
}
}
空 EUSCIA2_IRQHandler (空){
if (EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG){
Input[RXByteCTR++]= EUSCI_A2->RXBUF;
LED_PyOUT (G_LED);
}
}
main.c
const char correct[]="您的密码正确\n";
void main (void){
/*清除所有 LED RGB/
LED_PxCLR (R_LED_G_LED_B_LED);
LED_PyDIR (R_LED|G_LED|B_LED);
看门狗狗犬;
UART_CS();
confg_UART_wired();
UART_INIT();
UART_Transmit (正确);
while (1){
}
}
void WatchDogHold (void){WDTCTL
= WDTPW | WDTHOLD;/*停止看门狗计时器*/
}
结果:
是的、定义正确...
uart.h
#ifndef UART_H_ #define UART_H_ /* define*/ #define UART_TX BIT3 #define UART_RX BIT2 void UART_INIT (void); void confg_UART_Wired (void); void UART_cs (void); #endif /* UART_H_*
Bruce 我和大家分享 main.h、函数在哪里...
main.h
#ifndef MAIN_H_ #define MAIN_H_ void WatchDogHold (void); /* LED 引脚配置*/ #define LED_PxOUT P2->OUT #define LED_PxDIR P2->DIR #define LED_PxCLR (x) LED_PxOUT &=~ ^(x & 0x00FF)#define LED_PxLED (x + PxLED)(x + PxLED)#define PxLED (x + PxLED)#define LED (x + PxLED)#define PxLED (x + PxLED)#define PxLED + PxLED (x + PxLED)#define PxLED + PxLED + PxLED)#define PxLED (0xPxLED /*红色 LED*/ #define G_LED BIT1 /*绿色 LED*/ #define B_LED BIT2 /*蓝色 LED*/ #endif /* MAIN_H_*/
Armando、
以下是一些建议:
希望这会有所帮助。
-Bob L.