野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 17205|回复: 2

KeilMDK配置项中Use MicroLIB,是否需要勾选的深入讨论

[复制链接]
发表于 2021-1-29 11:26:19 | 显示全部楼层 |阅读模式
采用原子哥工程的编程方式,移植了之后,仿真环境下,单步运行,全速运行,程序没问题,打印也没问题,
但是开发板(野火开发板)上电单独运行,程序卡死,
但是勾选了Use MicroLIB,程序运行合适了,
后面采用了支持printf函数,而不需要选择use MicroLIB处理方式出现.\Objects\LEDApp.axf: Error: L6200E: Symbol __stdout multiply defined (by stdio_streams.o and usart.o).
在这个报错下,勾选了Use MicroLIB,程序正常了。。。。。。。

下面直接上代码请大神们帮忙分析一下:
#include "myusart.h"


void  usart_init(void)
{   
  //GPIO设置
    GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef  USART_InitStructure;
  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);  //使能USART1,GPIOA时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能USART1,GPIOA时钟

  //USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA.9

  //USART1_RX GPIOA.10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化PA.10

  
//USART 初始化设置
USART_InitStructure.USART_BaudRate = 115200;  //串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
  USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

USART_Init(USART1,&USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE);   //使能串口1

}



/********************发送一个字符***********************/

void Usart_SendByte(USART_TypeDef * pUSARTx, uint8_t ch)
{
USART_SendData(pUSARTx, ch);    //发送一个字节数据到USART

while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); //等待发送数据寄存器为空
}

/********************发送字符串**************************/

void Usart_SendString(USART_TypeDef * pUSARTx, char *str)
{
   unsigned int k=0;
do{
     Usart_SendByte(pUSARTx, *(str +k));
   k++;
  }while(*(str + k)!='\0');
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET)  //等待发送完成
{

}
}

/*****************发送一个16位数***********************/

void Usart_SendHalfWord(USART_TypeDef * pUSARTx, uint16_t ch)
{
   uint8_t  temp_h, temp_l;
temp_h = (ch&0XFF00)>>8;  //取出高八位
temp_l = ch&0XFF;  //取出低八位

USART_SendData(pUSARTx,temp_h);  //发送高八位
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);

USART_SendData(pUSARTx,temp_l);  //发送低八位
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}

/************重定向C库函数printf到串口,重定向后可使用printf函数***/
int fputc(int ch, FILE *F)
{
  USART_SendData(USART1, (uint8_t) ch);  //发送一个字节数据到串口
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);  //等待发送完成
return (ch);
}


/****重定向c库函数scanf到串口,重写向后可使用scanf,getchar等函数******/

int fgetc(FILE *f)
{
  while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);  //等待串口输入数据
return (int)USART_ReceiveData(USART1);
}



#ifndef __MYUSART_H
#define __MYUSART_H  

#include "stm32f10x.h"
#include <stdio.h>


void usart_init(void);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart_SendString( USART_TypeDef * pUSARTx, char *str);
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch);
      
#endif







#include "sys.h"
#include "usart.h"   
//////////////////////////////////////////////////////////////////////////////////   
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用   
#endif

//加入以下代码,支持printf函数,而不需要选择use MicroLIB   
#if 1
#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
int handle;

};

FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
x = x;
}

/***************************增加下面这个函数*****************************/
//__use_no_semihosting was requested, but _ttywrch was
_ttywrch(int ch)
{
    ch = ch;
}
/***************************增加上面这个函数*****************************/


#endif



#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"


#endif






#include "led.h"
#include "myusart.h"
#include "stm32f10x.h"
#include "usart.h"

static void Show_Message(void);


int main(void)
{
char ch;
  
  /* 初始化RGB彩灯 */
  LED_Init();
  
  /* 初始化USART 配置模式为 115200 8-N-1 */
  usart_init();

  /* 打印指令输入提示信息 */
  Show_Message();
  while(1)
{
    /* 获取字符指令 */
    ch=getchar();
    printf ("接收到字符:%c\n",ch);
   
    /* 根据字符指令控制RGB彩灯颜色 */
    switch(ch)
    {
      case '1':
        LED_RED;
      break;
      case '2':
        LED_GREEN;
      break;
      case '3':
        LED_BLUE;
      break;
      case '4':
        LED_YELLOW;
      break;
      case '5':
        LED_PURPLE;
      break;
      case '6':
        LED_CYAN;
      break;
      case '7':
        LED_WHITE;
      break;
      case '8':
        LED_RGBOFF;
      break;
      default:
        /* 如果不是指定指令字符,打印提示信息 */
        Show_Message();
        break;      
    }   
}
}
static void Show_Message(void)
{
  printf("\r\n   这是一个通过串口通信指令控制RGB彩灯实验 \n");
  printf("使用  USART  参数为:%d 8-N-1 \n",115200);
  printf("开发板接到指令后控制RGB彩灯颜色,指令对应如下:\n");
  printf("   指令   ------ 彩灯颜色 \n");
  printf("     1    ------    红 \n");
  printf("     2    ------    绿 \n");
  printf("     3    ------    蓝 \n");
  printf("     4    ------    黄 \n");
  printf("     5    ------    紫 \n");
  printf("     6    ------    青 \n");
  printf("     7    ------    白 \n");
  printf("     8    ------    灭 \n");  
}

回复

使用道具 举报

 楼主| 发表于 2021-1-29 13:52:20 | 显示全部楼层
在不使用半主机操作的时候,只有在仿真环境下,才会正常运行,打印,如图:

,只有勾选了,Use MicroLIB,才会正常运行。

但是使用了半主机操作,.\Objects\LEDApp.axf: Error: L6200E: Symbol __stdout multiply defined (by stdio_streams.o and usart.o).报这个错误,同样勾选了,Use MicroLIB,错误解决,程序,正常运行,打印,
这种操作,如何能正确执行哦,这样仍然链接了使用半主机的函数,链接器继续报错误,不等于没解决吗,大佬们如何看

#pragma import(__use_no_semihosting)  // 确保没有从 C 库链接使用半主机的函数
_sys_exit(int  x) //定义 _sys_exit() 以避免使用半主机模式
{
x = x;
}
struct __FILE  // 标准库需要的支持函数
{
int handle;
};
/* FILE is typedef ’ d in stdio.h. */
FILE __stdout;
野火论坛202101291345056180..png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-29 13:54:47 | 显示全部楼层
还有野火此实验例程,既没有勾选Use MicroLIB,也没有使用这种操作#pragma import(__use_no_semihosting)  // 确保没有从 C 库链接使用半主机的函数
_sys_exit(int  x) //定义 _sys_exit() 以避免使用半主机模式
{
x = x;
}
struct __FILE  // 标准库需要的支持函数
{
int handle;
};
/* FILE is typedef ’ d in stdio.h. */
FILE __stdout;


但就是正常的,奇怪不
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-4 03:47 , Processed in 0.051089 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表