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。