工具/软件:Code Composer Studio
我曾在一段时间前提出过一个与这个非常相似的问题、此后我进行了几次调整。 我正在处理的项目涉及温度传感器风扇控制器和 MSP430G2553。 ADC 值通过传感器进行测量、预设所需温度和当前温度之间的误差差异都通过 UART TX 打印到 PC。 风扇通过 PWM 增加速度、这取决于检查 ADC10MEM 值的三个 if 语句(我删除了许多其他用于清洁的 if 语句)。 顺便说一下、我使用了 CoolTerm 来查看打印的值。
我要做的最后一件事是通过 UART RX 发送多字符命令、以设置任何所需的温度值。 现在、诸如 if (UCA0RXBUF ='A')的单字符命令可以设置 SetDesiredTemp = 100。 此外、我可以通过 UART RX 键入任何随机字符串、完全相同的字符串将通过 UART RX 回传到 PC。 这意味着我可以确认我的 MSP430能够读取一整串字符并将其发回 PC。
这是我的问题出现的地方。 我知道 UART RX 正在执行我想要的操作、但使用下面的代码、如何检查发送到 RX 的字符串(或检查通过 TX 回显的字符串)以查看是否输入了字符串命令、例如"Set Desired Temperature ="? 更重要的是、如何将最后三个字符"100"转换为可插入 SetDesiredTemp = 100行的整数?
我将在这里发布完整代码、供大家查看。 它会进行编译。 我主要希望在代码中可以执行上述操作的地方、数小时的调试让我无处可去。
#include #include #include //闭环:温度传感器风扇控制器 /***初始化 UART 相关代码***/ volatile unsigned int current = 0;//将当前读取的 ADC10MEM 存储在循环的开头。 volatile unsigned int timer_count = 0; static char data; char buffer[32]; char buffer2[32]; void init_UART (); void init_timer(); void start_conversion (); void UARTSendArray (unsigned char * TxArray、unsigned char ArrayLength); /***初始化温度变量***/ int error = 0;//从电流中减去电流以确定风扇速度。 int SETtemperror = 370;//生成错误温度值的默认室温。 void (* UART_Rx_ISR_PTR)(unsigned char c); void UART_SET_Rx_ISR_PTR (void (* ISR_PTR)(unsigned char c) ){ UART_Rx_ISR_PTR = ISR_PTR; } void UART_putc (unsigned char c) //通过 TX 一次打印一个字符到 PC。 { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX 缓冲器就绪? UCA0TXBUF = c;// TX } void UART_PUs (const char * str) //使用此功能将任何字符串消息打印到 PC。 { while (* str) UART_putc (* str++); } void UART_Rx_ISR (unsigned char c){// UART RX 命令转到此处? UART_putc (c); P1OUT ^= BIT0;//切换 P1.0 (红色 LED) 开关(c){ 案例"A":{ SETtemperror = 460; UART_PUs ((char *)"\n\rDesirred 温度现在为:460\n"); } } void init_UART () { P1SEL = BIT1 + BIT2;// P1.1 = RXD、P1.2 = TXD P1SEL2 = BIT1 + BIT2;// P1.1 = RXD、P1.2 = TXD UCA0CTL1 |= UCSSEL_2;// SMCLK UCA0BR0 = UCA0;参阅上面的波特率分频器0 = UCA0BR0 ;/ UCB0BR0 = UCA0 = UCA104; //调制 UCBRSx = 1 UCA0CTL1 &=~UCSWRST;//**初始化 USCI 状态机** IE2 |= UCA0RXIE;//启用 USCI_A0 TX 中断 } 空 UARTSendArray (unsigned char * TxArray、unsigned char ArrayLength) { while (ArrayLength --){//循环、直至 StringLength = 0且 POST 递减 while (!(IFG2 & UCA0TXIFG));//等待 TX 缓冲区为新数据做好准备 UCA0TXBUF =* TxArray;//在指定的指针的位置写入字符 TxArray++;//使 TxString 指针指向下一个字符 } } void init_timer () { TA1CTL |= TACLR;//重置计时器 TA1CTL = tassel_2// SMCLK + ID_0//输入分频器= 1 + MC_2;//连续模式,中断禁用 TA1CCTL0 = OUTMOD_2//比较模式 + CCIE//中断启用 + CCIFG ;*** Timer0设置 DCOCTL = 0;//选择最低 DCO 设置 BCSCTL1 = CALBC1_1MHz;//将 DCO 设置为1MHz DCOCTL = CALDCO_1MHz; TA0CTL |= TASSEL_2 | MC_1 | ID_3; TA0CCR0 |= 800; TA0CCTL1 |= OUTMOD_7; TA0CCR1 |=0; } void start_conversion () { if ((ADC10CTL1 & ADC10BUSY)=0){// if not already converting //P1OUT ^= 0x40;// green led ADC10CTL0 |= ADC10SC; ADC10SA =(unsigned)¤t;//将最新的 ADC 值存储到 主地址 中}void (int) WDTCTL = WDTPW + WDTHOLD; //停止 WDT init_uart(); init_timer(); /*** GPIO 设置***/ P1DIR |= BIT6;// PWM 输出 P1SEL |= BIT6; P2DIR |= BIT0 + BIT1 + BIT3 + BIT4; /*** ADC10设置***/ ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE + REFON + ENC;// ADC10ON、中断被启用。 启用(但尚未启动)转换 ADC10DTC1 = 1;//每次传输一个块 ADC10CTL1 = INCH_3 + SHS_0 + ADC10DIV_3 + ADC10SSEL_3 + CONSEQ_0;//时钟源= SMCLK //ADC10AE0 |= BIT0; // pa.1 ADC 选项选择 //在接收到数据时调用寄存器 ISR UART_SET_Rx_ISR_PTR (UART_Rx_ISR); //启用中断并将 CPU 置于 SLEEP _Bis_SR_register (GIE+LPM0_Bits); unsigned char c = UCA0RXBUF; UART_putc (c); //初始化字符检索,初始化字符打印。 UART_PUT ((char *)"\n\n\r 温度控制器:打开并准备好\n");//发出主块已初始化的信号 unsigned int a = 0、delay = 50000、sec = 0; 对于(;) { 电流= ADC10MEM; Error = Current - SETtemperror;//计算与预设温度的误差差异。 ab()已删除。 //a = 0;sec = 0; //延迟以消除 LED 闪烁 //while (A < delay){A++;} //while ((a >= delay)&&(sec < 10)){A = 0;sec++;} 如果(误差< 10){ P2OUT &=~BIT4;P2OUT &=~BIT3;P2OUT &=~BIT1;P2OUT &=~BIT0;// 0000 TA0CCR1 = 0;// TA0CCR1 = ADC10MEM } 如果((error >= 10)&&(error < 100)){ P2OUT &=~BIT4;P2OUT |= BIT3;P2OUT |= BIT1;P2OUT &=~BIT0;// 0000 TA0CCR1 = 400;// TA0CCR1 = ADC10MEM } if (error >= 100){ P2OUT |= BIT4;P2OUT |= BIT3;P2OUT |= BIT1;P2OUT |= BIT0;// 1111 TA0CCR1 = 800;// TA0CCR1 = ADC10MEM } } #pragma vector=ADC10_vector // ADC10中断服务例程 __interrupt void ADC10_ISR (void) { _BIC_SR_REGISTER_ON_EXIT (CPUOFF); //从0 (SR)清除 CPUOFF 位 } //中断处理程序 #pragma vector = Timer1_A0_vector __interrupt void Timer1_A0 (void) { timer_count++; if (timer_count > 16){// 1秒刷新率的默认值为16。 对于较慢的数据传输 、设置为16 timer_count = 0; start_conversion (); IE2 |= UCA0TXIE;//激活 TX 中断 IE2 |= UCA0RXIE;//启用 USCI_A0 RX 中断 } #pragma vector = USCIAB0TX_vector __interrupt void USCI0TX_ISR (void) { //P1DIR = 0x01; //P1OUT ^= 0x01;//红色 LED 无符号整型 I = 0;//迭代器指针 sprintf (buffer、"temp measured:%d \n\r"、(int)(current));//将文本输出到 PC //uart_posed (((char *)"MSP430 Harduart\n"while (int)、(int))、(int)(int)))(while '/uift2 )/u0u./uart!/uart (uif) buffer 0)/u./uart (uift2)/u0u.u. UCA0TXBUF = buffer[i++]; } unsigned int j = 0;//迭代器指针 sprintf (buffer2、"Error diff:%d \n\r"、(int)(error)));//将文本输出到 PC while (buffer2[j]!='\0'){ while (!(IFG2 & TXIFG缓冲区)/ UCA0A0准备就绪 UCA0TXBUF = buffer2[j+]; } IE2 &&~UCA0TXIFG;//复位中断标志 } #pragma vector=USCIAB0RX_Vector __interrupt void USCI0RX_ISR (void) { if (UART_Rx_ISR_PTR!= 0L){ //如果有更多字符要发送到 RX 缓冲区,请继续发送字符。 (UART_Rx_ISR_PTR)(UCA0RXBUF); } switch (UCA0RXBUF){//不确定命令的确切位置 案例"d":{ SETtemperror = 460; UART_PUs ((char *)"\n\rDesirred 温度现在为:460\n"); } }
