TI中文支持网
TI专业的中文技术问题搜集分享网站

MSP430G2553: 在CCS上重定义printf函数,串口端显示有误

Part Number:MSP430G2553Other Parts Discussed in Thread:MSP-EXP430G2ET

各位好,

我首先在包含了stdio.h和string.h头文件的main函数中对fputc和fputs进行重定义,代码如下:

int fputc(int ch,FILE *f)
{while(UCA0STAT & UCBUSY);
//UCA0TXBUF = ch;UCA0TXBUF = ch&0xff;while(!(IFG2 & UCA0TXIFG));//等待发送完成return ch;
}

int fputs(const char *_ptr, register FILE *_fp)
{unsigned int i, len;len = strlen(_ptr);for(i=0 ; i<len ; i++){while(UCA0STAT & UCBUSY);
//UCA0TXBUF = _ptr[i];UCA0TXBUF = _ptr[i]&0xff;while(!(IFG2 & UCA0TXIFG));//等待发送完成}return len;
}

printf能够输出hello world这样的字符串,但是用到如"%d"等格式符号时就出现了问题。

具体代码如下:

int main(void)
{int i=0;uint8_t buff1[4] = {0x00,0x01,0x02,0x03};uint32_t buff2;float buff3;WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timerInitSystemClock();InitUART();buff2 = (((uint32_t)buff1[0])<<24)|(((uint32_t)buff1[1])<<16)|(((uint32_t)buff1[2])<<8)|buff1[3]; //将4个8位数据组合成一个uint32_t的数据,符合原始数据长度buff3 = (float)buff2;
//UARTSendString(buff1,4);
//for(i=0;i<4;i++)
//{
//UARTSendString(buff1[i],)
//}

//printf("hello world!!");for(i=0;i<4;i++){printf("buff1[%d] = %x\n",i,buff1[i]);}printf("buff2[1] = %u\n",buff2);printf("buff3[1] = %f\n",buff3);
//printf("i = %d \n",i);
	return 0;
}

一开始我对现project的properties中的“level of printf support required”中的设置为'minimal',这个时候通过串口只能够打印出int格式的数,也只会打印一次;

当我把设置改为'full'来满足我需要打印16进制数的要求时,串口不仅一直在打印%前的语句,而且需要打印的16进制数也打印不出来;对于在‘minimal’时能够按要求打印的int格式的数也是一直打印,串口助手打印出来的是这样的:

它好像一直卡在buff1[1]的printf中没有跳到下一步。但如果设置是‘minimal’的时候,串口助手显示的是:

请帮我看看应该怎么修改我的代码或者配置,谢谢各位!

Ben Qin:

你好,我查看下代码,稍后回复您。

,

Ben Qin:

可以分别单独打印buff1,buff2,buff3看看吗?

,

?? ?:

你好,代码和串口助手输出结果如下:

int main(void)
{int i=0;uint8_t buff1[4] = {0x00,0x01,0x02,0x03};uint32_t buff2;float buff3;WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timerInitSystemClock();InitUART();buff2 = (((uint32_t)buff1[0])<<24)|(((uint32_t)buff1[1])<<16)|(((uint32_t)buff1[2])<<8)|buff1[3]; //将4个8位数据组合成一个uint32_t的数据,符合原始数据长度UARTSend4B(buff2);buff3 = (float)buff2;for(i=0;i<4;i++){printf("buff1[%d] = %x\n",i,buff1[i]);}printf("buff2 = %u\n",buff2);printf("buff3 = %f\n",buff3);return 0;
}

在properties里面设置printf是'minimal',因为设置成full的时候会一直不断输出‘buff[1]=0‘。’

,

Ben Qin:

?? ? 说:我首先在包含了stdio.h和string.h头文件的main函数中对fputc和fputs进行重定义,

这个跟你的代码有什么关系?

?? ? 说:对于在‘minimal’时能够按要求打印的int格式的数也是一直打印,串口助手打印出来的是这样的:

这也太奇怪了。不用for循环可以正常打印吗?

,

?? ?:

1.我看网上别的帖子说需要在include了<stdio.h>和<string.h>头文件的函数中对fpuc和fputs进行重定义才能在串口使用printf函数;

2.设置是'full'的情况下,我刚刚试了不用for循环,只打印buff1[1],也是一直打印。

,

Ben Qin:

方便的话,可以将你的工程上传上来吗?

你可以参考下面这几篇帖子:

https://e2echina.ti.com/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/67066/printf

e2echina.ti.com/…/msp430f5529-printf

,

?? ?:

#include <msp430.h>#include "stdint.h"
#include <stdio.h>
#include <string.h>#define BufferSize 3
uint8_t tx_buffer[BufferSize] = {0,1,2};/** @fn:void InitSystemClock(void)* @brief:	初始化系统时钟* @para:	none* @return:	none* @comment:初始化系统时钟*/
void InitSystemClock(void)
{/*配置DCO为1MHz*/DCOCTL = CALDCO_1MHZ;BCSCTL1 = CALBC1_1MHZ;/*配置SMCLK的时钟源为DCO*/BCSCTL2 &= ~SELS;/*SMCLK的分频系数置为1*/BCSCTL2 &= ~(DIVS0 | DIVS1);
}
/** @fn:void InitUART(void)* @brief:	初始化串口,包括设置波特率,数据位,校验位等* @para:	none* @return:	none* @comment:初始化串口*/
void InitUART(void)
{/*复位USCI_Ax*/UCA0CTL1 |= UCSWRST;/*选择USCI_Ax为UART模式*/UCA0CTL0 &= ~UCSYNC;/*配置UART时钟源为SMCLK*/UCA0CTL1 |= UCSSEL1;/*配置波特率为9600@1MHz*/UCA0BR0 = 0x68;UCA0BR1 = 0x00;UCA0MCTL = 1 << 1;/*使能端口复用*/P1SEL |= BIT1 + BIT2;P1SEL2 |= BIT1 + BIT2;/*清除复位位,使能UART*/UCA0CTL1 &= ~UCSWRST;
}
/** @fn:void UARTSendString(uint8_t *pbuff,uint8_t num)* @brief:	通过串口发送字符串* @para:	pbuff:指向要发送字符串的指针*num:要发送的字符个数* @return:	none* @comment:通过串口发送字符串*/
void UARTSendString(uint8_t *pbuff,uint8_t num)
{uint8_t cnt = 0;for(cnt = 0;cnt < num;cnt ++){while(UCA0STAT & UCBUSY);//只要UCBUSY位(UCA0STAT的最低位)是1,就无法跳出这个while循环,不会执行到下一句//__delay_cycles(5000);UCA0TXBUF = *(pbuff + cnt);}
}
/** @fn:void PrintNumber(uint16_t num)* @brief:	通过串口发送数字* @para:	num:变量* @return:	none* @comment:通过串口发送数字*/
void PrintNumber(uint16_t num)
{uint8_t buff[6] = {0,0,0,0,0,'\n'};uint8_t cnt = 0;for(cnt = 0;cnt < 5;cnt ++){buff[4 - cnt] = (uint8_t)(num % 10 + '0');num /= 10;}UARTSendString(buff,6);
}
/** @fn:void UARTSendByte(uint8_t buff)* @brief:通过串口发送一个字节* @para:pbuff:指向要发送字节的指针* @return: none* @comment:通过串口发送字符串*/
void UARTSendByte(uint8_t buff)
{while(UCA0STAT & UCBUSY);UCA0TXBUF = buff;
}/** @fn:void UARTSend4B(uint32_t buff)* @brief:通过串口发送四个字节* @para:buff:要发送的字节* @return: none* @comment:拆成4个字节,一个一个分别发送*/
void UARTSend4B(uint32_t buff)
{uint8_t SendBuffer[4];int i;SendBuffer[0] = (buff>>24)&0xff;SendBuffer[1] = (buff>>16)&0xff;SendBuffer[2] = (buff>> 8)&0xff;SendBuffer[3] = (buff)&0xff;/*将32位数据拆成4个8位数据,一个一个向串口发送*/for(i=0;i<4;i++){UARTSendByte(SendBuffer[i]);}
}int fputc(int ch,FILE *f)
{while(UCA0STAT & UCBUSY);
//UCA0TXBUF = ch;UCA0TXBUF = ch&0xff;while(!(IFG2 & UCA0TXIFG));//等待发送完成return ch;
}int fputs(const char *_ptr, register FILE *_fp)
{unsigned int i, len;len = strlen(_ptr);for(i=0 ; i<len ; i++){while(UCA0STAT & UCBUSY);
//UCA0TXBUF = _ptr[i];UCA0TXBUF = _ptr[i]&0xff;while(!(IFG2 & UCA0TXIFG));//等待发送完成}return len;
}//int putchar(int c)
//{
//if(c == '\n')
//{
//while(UCA0STAT & UCBUSY);
//UCA0TXBUF = '\r';
//}
//while(UCA0STAT & UCBUSY);
//UCA0TXBUF = c;
//return c;
//}//int fputc(int c,FILE *f)
//{
//
//UCA0TXBUF = c;
//while(UCA0STAT & UCBUSY);
//return c;
//}/** main.c*/
int main(void)
{int i=0;uint8_t buff1[4] = {0x00,0x01,0x02,0x03};uint32_t buff2;float buff3;WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timerInitSystemClock();InitUART();buff2 = (((uint32_t)buff1[0])<<24)|(((uint32_t)buff1[1])<<16)|(((uint32_t)buff1[2])<<8)|buff1[3]; //将4个8位数据组合成一个uint32_t的数据,符合原始数据长度UARTSend4B(buff2);buff3 = (float)buff2;printf("buff1[1] = %x\n",buff1[1]);//for(i=0;i<4;i++)
//{
//printf("buff1[%d] = %x\n",i,buff1[i]);
//}//printf("buff2 = %u\n",buff2);
//
//printf("buff3 = %f\n",buff3);//UARTSendString(buff1,4);
//for(i=0;i<4;i++)
//{
//UARTSendString(buff1[i],)
//}//printf("hello world!!");//printf("buff2[1] = %u\n",buff2);
//printf("buff3[1] = %f\n",buff3);
//printf("i = %d \n",i);return 0;
}

这是我整个工程的代码,我用的开发板是msp-exp430g2et。

您给的第一个链接参考的是一个百度文档,它针对的是液晶屏的printf和scanf的使用;

第二个链接参考的github网站代码我好像也参考过,但是编译无法通过;另一个html显示好像不太全,没有看到贴上来的代码。

,

Ben Qin:

好的,我在我的板子上跑下看看。

,

Ben Qin:

你好,在下面这个函数中:

void UARTSend4B(uint32_t buff)
{uint8_t SendBuffer[4];int i;SendBuffer[0] = (buff>>24)&0xff;SendBuffer[1] = (buff>>16)&0xff;SendBuffer[2] = (buff>> 8)&0xff;SendBuffer[3] = (buff)&0xff;/*将32位数据拆成4个8位数据,一个一个向串口发送*/for(i=0;i<4;i++){UARTSendByte(SendBuffer[i]);}
}

buff 的类型还是32位并没有改变,而SendBuffer是8位。这是一个问题。

将buff2的这段代码中buff1[3]也加上强制转换:

buff2 = (((uint32_t)buff1[0])<<24)| (((uint32_t)buff1[1])<<16)| (((uint32_t)buff1[2])<<8)| ((uint32_t)buff1[3]);

以及buff1是8位,所以应该用%o.

  printf("buff1[1] = %o\n", buff1[1]);

,

?? ?:

您好,非常谢谢您的答复!

1. UARTSend4B这个函数不经过更改是可以正常直接向pc端发送32位数据的,将串口助手的接收设置改成“HEX”即可;

2. 您提到buff1是8位数据,但是“%o”这个输出格式指的是八进制,虽然对于buff1中的0,1,2,3输出没有影响,但是八进制输出并不是我想要的输出格式;

3. 在buff2这段代码加上了您的提议后,在“%x”的输出格式下仍是buff2=203,而理论上应该是buff2=10203。

,

Ben Qin:

?? ? 说:在buff2这段代码加上了您的提议后,在“%x”的输出格式下仍是buff2=203,而理论上应该是buff2=10203

这是由于%x对于数据位数有限制,从结果来看,其最高位数应该是16位,但buff2有32位。所以应该用%lx。

赞(0)
未经允许不得转载:TI中文支持网 » MSP430G2553: 在CCS上重定义printf函数,串口端显示有误
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1