1、目录结构
2、重现问题
这里出现的问题是在构建printf函数重定向的时候遇到的,报错信息如图所示:
linking...
.\Objects\usart.axf: Error: L6915E: Library reports error: __use_no_semihosting was requested, but _ttywrch was referenced
Not enough information to list load addresses in the image map.
Finished: 1 information, 0 warning and 1 error messages.
".\Objects\usart.axf" - 1 Error(s), 11 Warning(s).
Target not created.
Build Time Elapsed: 00:00:04
3、解决方案
在对应重定向源文件中,我这里是MyUsart.c文件,添加如下函数解决问题
_ttywrch(int ch)
{
ch = ch;
}
完整代码
#include "MyUsart.h"
#include "MyLed.h"
#include "cJSON.h"
/********** 禁用半主机模式 **********/
#pragma import(__use_no_semihosting)
struct __FILE
{
int a;
};
FILE __stdout;
void _sys_exit(int x)
{
}
_ttywrch(int ch)
{
ch = ch;
}
u16 temp;
/*******************************************************************************
* 函 数 名 : init__uart1
* 函数功能 : 配置串口1
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void init__uart1()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
// 串口IO配置,PA9,PA10
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//IO时钟打开
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//IO方式具体看《中文手册》8.1.11章节
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9; //TX
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//IO方式具体看《中文手册》8.1.11章节
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10; //RX
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//配置串口1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//打开串口时钟
USART_DeInit(USART1);//在配置串口前复位下是个好习惯
USART_InitStruct.USART_BaudRate=9600; //波特率9600
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //无硬件流
USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //接收和发送都使能
USART_InitStruct.USART_Parity=USART_Parity_No; //无奇偶校验
USART_InitStruct.USART_StopBits=USART_StopBits_1; //停止位1位
USART_InitStruct.USART_WordLength=USART_WordLength_8b; //数据长度8位
USART_Init(USART1,&USART_InitStruct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE); //配置完成后一定要记得使能串口
}
/*******************************************************************************
* 函 数 名 : Send_String
* 函数功能 : 发送字符串
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
//void Send_String(USART_TypeDef* USARTx, char *s)
//{
// while(*s!='\0')
// {
// while(USART_GetFlagStatus(USARTx,USART_FLAG_TC )==RESET);
// USART_SendData(USARTx,*s++);
// }
//}
/*******************************************************************************
* 函 数 名 : NVIC_Config
* 函数功能 : 初始化中断向量控制器NVIC
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* 函 数 名 : TIM2_IRQHandler
* 函数功能 : 中断函数中自己编写
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void USART1_IRQHandler(void)
{
//判断TIM3更新中断是否发生
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
{
//接收数据
temp=USART_ReceiveData(USART1); //接收数据
}
USART_SendData(USART1,temp);
}
/*******************************************************************************
* 函 数 名 : get_Status
* 函数功能 : 返回串口数据
* 输 入 : 无
* 输 出 : 返回数据
*******************************************************************************/
char get_Status(void){
return temp;
}
/*****************************************************
*function: 写字符文件函数
*param1: 输出的字符
*param2: 文件指针
*return: 输出字符的ASCII码
******************************************************/
int fputc(int ch, FILE *f)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); //等待上次发送结束
USART_SendData(USART1, (unsigned char)ch); //发送数据到串口
return ch;
}
/*******************************************************************************
* 函 数 名 : get_Status
* 函数功能 : 返回串口数据
* 输 入 : 无
* 输 出 : 返回数据
*******************************************************************************/
void sendjson() {
//创建指针
char * jsonptr;
cJSON * root; //json对象
char * jsontemp; //tempjson
char * CMD1 = "1"; //开关1,开控制命令
char * CMD2 = "0"; //开关1,关控制命令
//指向输入的字符串
jsonptr = temp;
//解析JSON格式字符串并点亮相应的LED灯
root = cJSON_Parse(jsonptr);
//u1_printf("MQTT111:%s\r\n", root->valuestring);
if (root) { //判断json不为空
//Delay_Ms(10);
//u1_printf("MQTT111:%s\r\n", cJSON_GetObjectItem(root,"led1")->valuestring);
jsontemp = cJSON_GetObjectItem(root, "led1")->valuestring;
printf("MQTT111:%s\r\n", jsontemp);
if (!strcmp(jsontemp, CMD1)) { //如果现在IO是高电平,表示开关1是关闭状态
printf("MQTT222:%s\r\n", cJSON_GetObjectItem(root, "led1") ->valuestring);
}
} else if (root) { //判断指令,如果是CMD2,关开关1
if (!strcmp(jsontemp, CMD2)) { //如果现在IO是低电平,表示开关1是打开状态
printf("MQTT333:%s\r\n", cJSON_GetObjectItem(root, "led1") ->valuestring);
}
}
}