当前位置: 首页 > news >正文

网站添加favicon黄页网站推广服务

网站添加favicon,黄页网站推广服务,银川网站建设怎么样,网站设计论文分类号包含:WIFI模块、GPS模块、语言模块、调试信息接口。 一、硬件连接 huart4( PA0、 PA1 )与GPS模块连接。 huart3(PB10、PB11)与ESP8266模块连接。 huart2( PA2、 PA3 )与语音模块连接。 hu…

包含:WIFI模块、GPS模块、语言模块、调试信息接口。 

一、硬件连接

 huart4( PA0、  PA1 )与GPS模块连接。
 huart3(PB10、PB11)与ESP8266模块连接。
 huart2( PA2、  PA3 )与语音模块连接。
 huart1(PB14、PB15)与PC端连接,用于打印调试信息。

二、串口配置代码

2.1 开启中断:

        开启串口的接收中断 or 空闲中断。

	/* 该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 */HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, 1);// __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);// HAL_UART_Receive_DMA(&huart3,(uint8_t*)ATCmdRxBuffer,ATCmdRxBuffe_MAX_SIZE); //重新启动DMA接收__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);	//使能IDLE中断	HAL_UART_Receive_DMA(&huart2, voiceBuf, voiceBuf_MAX_SIZE);
//HAL_UART_Receive_DMA(&huart3, (uint8_t *)g_rx_buffer, 1);__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);                          /* 使能UART接收中断 */__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);                          /* 使能UART总线空闲中断 */
2.2 中断函数:
/* USER CODE BEGIN 1 */void HAL_UART_MyIdleCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART2){Voice_Length = voiceBuf_MAX_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);flag_voice = 1; // 设置接收完成标志}
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // 串口接收完成中断回调函数
{if (huart->Instance == USART1)                      /* 如果是串口1 */{if ((myHexapodRx.recv_end_flag & 0x8000) == 0)    /* 接收未完成    1000 0000 0000 0000 */ {if (myHexapodRx.recv_end_flag & 0x4000)         /* 接收到了0x0D /r  0100 0000 0000 0000 */{if (g_rx_buffer[0] != 0x0a)      /* \n 0x0A*/{myHexapodRx.recv_end_flag = 0;              /*  接收错误,重新开始 */}else{myHexapodRx.recv_end_flag |= 0x8000;        /* 接收完成了 */}}else                                            /* 还没收到0X0D */{if (g_rx_buffer[0] == 0x0d){myHexapodRx.recv_end_flag |= 0x4000;} else{                                          //0011 1111 1111 1111myHexapodRx.HexapodRxBuf[myHexapodRx.recv_end_flag & 0X3FFF] = g_rx_buffer[0];myHexapodRx.recv_end_flag++;if (myHexapodRx.recv_end_flag > (HexapodRxBuf_MAX_SIZE - 1)){myHexapodRx.recv_end_flag = 0;            /* 接收数据错误,重新开始接收 */}}}}HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, 1);}if (huart->Instance == USART2){HAL_UART_Receive_DMA(&huart2, (uint8_t *)voiceBuf, voiceBuf_MAX_SIZE);}

三、功能模块 

3.1 ESP8266模块

        3.1.1 atk_ESP8266D
        atk_mw8266d_usart.c
#include "atk_mw8266d_usart.h"
#include "usart.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>g_uart_rx_frame myATCmdRx = {0};static uint8_t g_uart_tx_buf[ATK_MW8266D_UART_TX_BUF_SIZE]; /* ATK-MW8266D UART发送缓冲 *//*** @brief       ATK-MW8266D UART printf* @param       fmt: 待发送的数据* @retval      无*/
void atk_mw8266d_uart_printf(char *fmt, ...)
{va_list ap;uint16_t len;va_start(ap, fmt);vsprintf((char *)g_uart_tx_buf, fmt, ap);va_end(ap);len = strlen((const char *)g_uart_tx_buf);HAL_UART_Transmit(&g_uart_handle, g_uart_tx_buf, len, HAL_MAX_DELAY);//HAL_UART_Transmit_IT(&g_uart_handle, g_uart_tx_buf, sizeof(g_uart_tx_buf));
}/*** @brief       ATK-MW8266D UART重新开始接收数据* @param       无* @retval      无*/
void atk_mw8266d_uart_rx_restart(void)
{myATCmdRx.sta.len     = 0;myATCmdRx.sta.finsh   = 0;
}/*** @brief       获取ATK-MW8266D UART接收到的一帧数据* @param       无* @retval      NULL: 未接收到一帧数据*              其他: 接收到的一帧数据*/
uint8_t *atk_mw8266d_uart_rx_get_frame(void)
{if (myATCmdRx.sta.finsh == 1){myATCmdRx.buf[myATCmdRx.sta.len] = '\0';//printf("接收到的数据: %s\r\n", myATCmdRx.buf);return myATCmdRx.buf;        }else{return NULL;}
}/*** @brief       获取ATK-MW8266D UART接收到的一帧数据的长度* @param       无* @retval      0   : 未接收到一帧数据*              其他: 接收到的一帧数据的长度*/
uint16_t atk_mw8266d_uart_rx_get_frame_len(void)
{if (myATCmdRx.sta.finsh == 1){return myATCmdRx.sta.len;}else{return 0;}
}/*** @brief       ATK-MW8266D UART初始化* @param       baudrate: UART通讯波特率* @retval      无*/
void atk_mw8266d_uart_init(uint32_t baudrate)
{g_uart_handle.Instance          = ATK_MW8266D_UART_INTERFACE;   /* ATK-MW8266D UART */g_uart_handle.Init.BaudRate     = baudrate;                     /* 波特率 */g_uart_handle.Init.WordLength   = UART_WORDLENGTH_8B;           /* 数据位 */g_uart_handle.Init.StopBits     = UART_STOPBITS_1;              /* 停止位 */g_uart_handle.Init.Parity       = UART_PARITY_NONE;             /* 校验位 */g_uart_handle.Init.Mode         = UART_MODE_TX_RX;              /* 收发模式 */g_uart_handle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;          /* 无硬件流控 */g_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16;         /* 过采样 */HAL_UART_Init(&g_uart_handle);                                  /* 使能ATK-MW8266D UART* HAL_UART_Init()会调用函数HAL_UART_MspInit()* 该函数定义在文件usart.c中*/
}/*** @brief       ATK-MW8266D UART中断回调函数* @param       无* @retval      无*/
void ATK_MW8266D_UART_IRQHandler(void)
{uint8_t tmp;if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_ORE) != RESET)        /* UART接收过载错误中断 */{__HAL_UART_CLEAR_OREFLAG(&g_uart_handle);                           /* 清除接收过载错误中断标志 */(void)g_uart_handle.Instance->ISR;                                  /* I先读SR寄存器,再读RDR寄存器 */(void)g_uart_handle.Instance->RDR;}if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_RXNE) != RESET)       /* UART接收中断 */{HAL_UART_Receive(&g_uart_handle, &tmp, 1, 1000);          /* UART接收数据 */if (myATCmdRx.sta.len < (ATK_MW8266D_UART_RX_BUF_SIZE - 1))   /* 判断UART接收缓冲是否溢出* 留出一位给结束符'\0'*/{myATCmdRx.buf[myATCmdRx.sta.len] = tmp;             /* 将接收到的数据写入缓冲 */myATCmdRx.sta.len++;                                      /* 更新接收到的数据长度 */}else                                                                /* UART接收缓冲溢出 */{myATCmdRx.sta.len = 0;                                    /* 覆盖之前收到的数据 */myATCmdRx.buf[myATCmdRx.sta.len] = tmp;             /* 将接收到的数据写入缓冲 */myATCmdRx.sta.len++;                                      /* 更新接收到的数据长度 */}}if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_IDLE) != RESET)       /* UART总线空闲中断 */{myATCmdRx.sta.finsh = 1;                                      /* 标记帧接收完成 */__HAL_UART_CLEAR_IDLEFLAG(&g_uart_handle);                          /* 清除UART总线空闲中断 */}
}
        atk_mw8266d_usart.h
#ifndef __ATK_MW8266D_UART_H
#define __ATK_MW8266D_UART_H#include "main.h"/* 引脚定义 */
#define ATK_MW8266D_UART_TX_GPIO_PORT           GPIOB
#define ATK_MW8266D_UART_TX_GPIO_PIN            GPIO_PIN_10
#define ATK_MW8266D_UART_TX_GPIO_AF             GPIO_AF7_USART2
#define ATK_MW8266D_UART_TX_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)     /* PA口时钟使能 */#define ATK_MW8266D_UART_RX_GPIO_PORT           GPIOB
#define ATK_MW8266D_UART_RX_GPIO_PIN            GPIO_PIN_11
#define ATK_MW8266D_UART_RX_GPIO_AF             GPIO_AF7_USART2
#define ATK_MW8266D_UART_RX_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)     /* PA口时钟使能 */#define ATK_MW8266D_UART_INTERFACE              USART3
#define ATK_MW8266D_UART_IRQn                   USART3_IRQn
//#define ATK_MW8266D_UART_IRQHandler             USART3_IRQHandler
#define ATK_MW8266D_UART_CLK_ENABLE()           do{ __HAL_RCC_USART3_CLK_ENABLE(); }while(0)    /* USART3 时钟使能 *//* UART收发缓冲大小 */
#define ATK_MW8266D_UART_RX_BUF_SIZE            128
#define ATK_MW8266D_UART_TX_BUF_SIZE            64
#define g_uart_handle   huart3typedef struct
{uint8_t buf[ATK_MW8266D_UART_RX_BUF_SIZE];              /* 帧接收缓冲 */struct{uint16_t len    : 15;                               /* 帧接收长度,sta[14:0] */uint16_t finsh  : 1;                                /* 帧接收完成标志,sta[15] */} sta;                                                  /* 帧状态信息 */
} g_uart_rx_frame;                                    /* ATK-MW8266D UART接收帧缓冲信息结构体 */extern g_uart_rx_frame myATCmdRx;/* 操作函数 */
void atk_mw8266d_uart_printf(char *fmt, ...);       /* ATK-MW8266D UART printf */
void atk_mw8266d_uart_rx_restart(void);             /* ATK-MW8266D UART重新开始接收数据 */
uint8_t *atk_mw8266d_uart_rx_get_frame(void);       /* 获取ATK-MW8266D UART接收到的一帧数据 */
uint16_t atk_mw8266d_uart_rx_get_frame_len(void);   /* 获取ATK-MW8266D UART接收到的一帧数据的长度 */
void atk_mw8266d_uart_init(uint32_t baudrate);      /* ATK-MW8266D UART初始化 */
void ATK_MW8266D_UART_IRQHandler(void);
#endif

        3.1.2 myTask_atk8266D
        myTask_atk8266D.c
#include "myTask_ATK8266D.h"
#include "atk_mw8266d.h"
#include "usart.h"
#include "main.h"
#include "stdio.h"
#include "string.h"
#include "led.h"#define DEMO_WIFI_SSID "guilin88"
#define DEMO_WIFI_PWD "12345678"
#define DEMO_TCP_SERVER_IP "192.168.96.95"
#define DEMO_TCP_SERVER_PORT "6688"void myTask_ATK8266D(void)
{uint8_t ret;//char ip_buf[16];/* 初始化ATK-MW8266D */printf("开始连接AP.......\r\n");ret = atk_mw8266d_init(115200);if (ret != 0){printf("ATK-MW8266D init failed!\r\n");while (1){LED_R_Toggle;delay_ms(200);}}
//	printf("正在恢复出厂设置...\r\n");
//	while (atk_mw8266d_restore())
//	{
//		color_debug();
//	}printf("正在进行AT测试...\r\n");while (atk_mw8266d_at_test()){color_debug();}
//	printf("正在设置波特率...\r\n");
//	ret = atk_mw8266d_send_at_cmd("AT+UART=115200,8,1,0,0", "OK", 500);
//	while (ret != 0)
//	{
//		color_debug();
//	}printf("正在设置Station模式...\r\n");while (atk_mw8266d_set_mode(1)){color_debug();}
//	printf("正在进行软件复位...\r\n");
//	while (atk_mw8266d_sw_reset())
//	{
//		color_debug();
//	}
//	printf("关闭回显功能...\r\n");
//	while (atk_mw8266d_ate_config(0))
//	{
//		color_debug();
//	}printf("正在连接WIFI...\r\n");while (atk_mw8266d_join_ap(DEMO_WIFI_SSID, DEMO_WIFI_PWD)){printf("Error to connect tcp server! 2秒后重新连接!\r\n");color_debug();}
//	printf("获取IP地址中...\r\n");
//	while (atk_mw8266d_get_ip(ip_buf))
//	{
//		color_debug();
//	}//	printf("IP: %s\r\n", ip_buf);/* 连接TCP服务器 */printf("正在连接TCP服务器...\r\n");while (atk_mw8266d_connect_tcp_server(DEMO_TCP_SERVER_IP, DEMO_TCP_SERVER_PORT)){printf("Error to connect tcp server! 2秒后重新连接!\r\n");color_debug();}/* 进入透传 */printf("进入透传...\r\n");while (atk_mw8266d_enter_unvarnished()){color_debug();}printf("成功进入透传\r\n");atk_mw8266d_uart_rx_restart(); // 重新开始接收数据
}
        myTask_atk8266D.h
#ifndef _MYTASK_ATK8266D_H
#define _MYTASK_ATK8266D_Hvoid myTask_ATK8266D(void);#endif

3.2 GPS模块

        3.2.1 ATGM336H
        ATGM336H.c
#include "ATGM336H.h"
#include "main.h"
#include "usart.h"
#include "string.h"
#include "stdio.h"char rxdatabufer;
u16 point1 = 0;_SaveData Save_Data;
LatitudeAndLongitude_s g_LatAndLongData =
{.E_W = 0,.N_S = 0,.latitude = 0.0,.longitude = 0.0
};// 串口1中断服务程序
// 注意,读取USARTx->SR能避免莫名其妙的错误
char USART_RX_BUF[USART_REC_LEN];	// 接收缓冲,最大USART_REC_LEN个字节.
uint8_t uart_A_RX_Buff;// 接收状态
// bit15,	接收完成标志
// bit14,	接收到0x0d
// bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;	// 接收状态标记void atgm336h_init(void)
{clrStruct();HAL_UART_Receive_IT(&huart4, &uart_A_RX_Buff, 1);
}//GPS中断回调函数,需要放入串口接收中断中
void atgm336h_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == UART4){
//		printf("%c", uart_A_RX_Buff);if(uart_A_RX_Buff == '$'){point1 = 0;}USART_RX_BUF[point1++] = uart_A_RX_Buff;if(USART_RX_BUF[0] == '$' && USART_RX_BUF[4] == 'M' && USART_RX_BUF[5] == 'C')	//确定是否收到"GPRMC/GNRMC"这一帧数据{if(uart_A_RX_Buff == '\n'){memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);      //清空memcpy(Save_Data.GPS_Buffer, USART_RX_BUF, point1); 	//保存数据Save_Data.isGetData = true;point1 = 0;memset(USART_RX_BUF, 0, USART_REC_LEN);      //清空}}if(point1 >= USART_REC_LEN){point1 = USART_REC_LEN;}HAL_UART_Receive_IT(&huart4, &uart_A_RX_Buff, 1);}
}u8 Hand(char *a)	// 串口命令识别函数
{if(strstr(USART_RX_BUF, a)!=NULL)return 1;elsereturn 0;
}void CLR_Buf(void)	// 串口缓存清理
{memset(USART_RX_BUF, 0, USART_REC_LEN);	//清空point1 = 0;
}void clrStruct(void)
{Save_Data.isGetData = false;Save_Data.isParseData = false;Save_Data.isUsefull = false;memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);	//清空memset(Save_Data.UTCTime, 0, UTCTime_Length);memset(Save_Data.latitude, 0, latitude_Length);memset(Save_Data.N_S, 0, N_S_Length);memset(Save_Data.longitude, 0, longitude_Length);memset(Save_Data.E_W, 0, E_W_Length);
}void errorLog(int num)
{while (1){printf("ERROR%d\r\n",num);}
}void parseGpsBuffer(void)
{char *subString;char *subStringNext;char i = 0;uint16_t Number=0, Integer=0, Decimal=0;if (Save_Data.isGetData){Save_Data.isGetData = false;printf("**************\r\n");printf("%s\r\n", Save_Data.GPS_Buffer);for (i = 0 ; i <= 6 ; i++){if (i == 0){if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)errorLog(1);	//解析错误}else{subString++;if ((subStringNext = strstr(subString, ",")) != NULL){char usefullBuffer[2];switch(i){case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break;	//获取UTC时间case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;	//获取UTC时间case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break;	//获取纬度信息case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;	//获取N/Scase 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;	//获取经度信息case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;	//获取E/Wdefault:break;}subString = subStringNext;Save_Data.isParseData = true;if(usefullBuffer[0] == 'A')Save_Data.isUsefull = true;else if(usefullBuffer[0] == 'V')Save_Data.isUsefull = false;}else{errorLog(2);	//解析错误}}}if (Save_Data.isParseData){if(Save_Data.isUsefull){// 获取 N/S 和 E/Wg_LatAndLongData.N_S = Save_Data.N_S[0];g_LatAndLongData.E_W = Save_Data.E_W[0];// 获取纬度for(uint8_t i=0; i<9; i++){if(i<2){Number *= 10;Number += Save_Data.latitude[i]-'0';}else if(i<4){Integer *= 10;Integer += Save_Data.latitude[i]-'0';}else if(i==4);else if(i<9){Decimal *= 10;Decimal += Save_Data.latitude[i]-'0';}}g_LatAndLongData.latitude = 1.0*Number + (1.0*Integer+1.0*Decimal/10000)/60;Number = 0;Integer = 0;Decimal = 0;// 获取经度for(uint8_t i=0; i<10; i++){if(i<3){Number *= 10;Number += Save_Data.longitude[i]-'0';}else if(i<5){Integer *= 10;Integer += Save_Data.longitude[i]-'0';}else if(i==5);else if(i<10){Decimal *= 10;Decimal += Save_Data.longitude[i]-'0';}}g_LatAndLongData.longitude = 1.0*Number + (1.0*Integer+1.0*Decimal/10000)/60;}}}
}void printGpsBuffer(void)
{if (Save_Data.isParseData){Save_Data.isParseData = false;printf("Save_Data.UTCTime = %s\r\n", Save_Data.UTCTime);if(Save_Data.isUsefull){Save_Data.isUsefull = false;printf("Save_Data.latitude = %s\r\n", Save_Data.latitude);printf("Save_Data.N_S = %s", Save_Data.N_S);printf("Save_Data.longitude = %s", Save_Data.longitude);printf("Save_Data.E_W = %s\r\n", Save_Data.E_W);printf("latitude: %c,%.4f\r\n", g_LatAndLongData.N_S, g_LatAndLongData.latitude);printf("longitude: %c,%.4f\r\n", g_LatAndLongData.E_W, g_LatAndLongData.longitude);}else{printf("GPS DATA is not usefull!\r\n");}}
}
        ATGM336H.h
#ifndef __ATGM336H_H
#define __ATGM336H_H#include "usart.h"
#include "sys.h"
// #include "stdbool.h"#define USART_REC_LEN 200 // 定义最大接收字节数 200
#define EN_USART1_RX 1	  // 使能(1)/禁止(0)串口1接收#define false 0
#define true 1// 定义数组长度
#define GPS_Buffer_Length 80
#define UTCTime_Length 11
#define latitude_Length 11
#define N_S_Length 2
#define longitude_Length 12
#define E_W_Length 2typedef struct SaveData
{char GPS_Buffer[GPS_Buffer_Length];char isGetData;					  // 是否获取到GPS数据char isParseData;				  // 是否解析完成char UTCTime[UTCTime_Length];	  // UTC时间char latitude[latitude_Length];	  // 纬度char N_S[N_S_Length];			  // N/Schar longitude[longitude_Length]; // 经度char E_W[E_W_Length];			  // E/Wchar isUsefull;					  // 定位信息是否有效
} _SaveData;// 经纬度数据
typedef struct _LatitudeAndLongitude_s
{float latitude;	 // 纬度float longitude; // 经度char N_S; // 北南char E_W; // 东西
} LatitudeAndLongitude_s;extern char rxdatabufer;
extern u16 point1;
extern _SaveData Save_Data;
extern LatitudeAndLongitude_s g_LatAndLongData;void atgm336h_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void atgm336h_init(void); // 初始化
void clrStruct(void); // 清除结构体数据
void parseGpsBuffer(void); // 解包函数
void printGpsBuffer(void); // 打印函数#endif // __ATGM336H_H
        3.2.2 myTask_GPS
        myTask_GPS.c
#include "myTask_GPS.h"
#include "stdio.h"
#include "ATGM336H.h"void myTask_GPS(void){atgm336h_init();while (1){if (Save_Data.isParseData){Save_Data.isParseData = false;if(Save_Data.isUsefull){Save_Data.isUsefull = false;printf("latitude: %c,%.4f\r\n", g_LatAndLongData.N_S, g_LatAndLongData.latitude);printf("longitude: %c,%.4f\r\n", g_LatAndLongData.E_W, g_LatAndLongData.longitude);}else{printf("GPS DATA is not usefull!\r\n");}}HAL_Delay(30);}
}

3.3 语音模块

        直接使用串口2接收指令信息。

3.4 串口重定义

        支持printf函数,便于打印调试信息到PC端,适配STM32H7系列。其他系列需要查看不同的芯片手册。

/******************************************************************************************/
/* 加入以下代码, 支持printf函数, 而不需要选择use MicroLIB */#if 1
#if (__ARMCC_VERSION >= 6010050)           /* 使用AC6编译器时 */
__asm(".global __use_no_semihosting\n\t"); /* 声明不使用半主机模式 */
__asm(".global __ARM_use_no_argv \n\t");   /* AC6下需要声明main函数为无参数格式,否则部分例程可能出现半主机模式 */#else
/* 使用AC5编译器时, 要在这里定义__FILE 和 不使用半主机模式 */
#pragma import(__use_no_semihosting)struct __FILE
{int handle;/* Whatever you require here. If the only file you are using is *//* standard output using printf() for debugging, no file handling *//* is required. */
};#endif/* 不使用半主机模式,至少需要重定义_ttywrch\_sys_exit\_sys_command_string函数,以同时兼容AC6和AC5模式 */
int _ttywrch(int ch)
{ch = ch;return ch;
}/* 定义_sys_exit()以避免使用半主机模式 */
void _sys_exit(int x)
{x = x;
}char *_sys_command_string(char *cmd, int len)
{return NULL;
}/* FILE 在 stdio.h里面定义. */
FILE __stdout;/* 重定义fputc函数, printf函数最终会通过调用fputc输出字符串到串口 */
int fputc(int ch, FILE *f)
{while ((USART1->ISR & 0X40) == 0); /* 等待上一个字符发送完成 */USART1->TDR = (uint8_t)ch; /* 将要发送的字符 ch 写入到DR寄存器 */return ch;
}
#endif
/***********************************************END*******************************************/

http://www.rdtb.cn/news/18331.html

相关文章:

  • 做导航网站用什么源码佛山seo网站排名
  • 贵阳网站推广有几家代运营电商公司排行榜
  • 衡水住房和城乡建设局网站站内推广有哪些方式
  • 种植园网站模板搜索引擎免费登录入口
  • 52麻将官方网站做代理seo项目完整流程
  • 网站内容建设培训通知成都网站seo公司
  • 苏州做网站优化公司哪家好通过百度指数不能判断出
  • 给我免费播放片高清在线观看授他以柄电视剧短视频矩阵seo系统源码
  • 郴州北京网站建设模板建站网页
  • 泰安网约车平台有哪些seo sem论坛
  • 长沙品牌网站建设嘉兴seo网络推广
  • 网站做营利性广告需要什么备案域名是什么
  • 1g做网站空间百度代运营
  • 校园环境设计规划及实施方案云seo关键词排名优化软件
  • 在哪个网站做兼职靠谱app优化推广
  • 晋城网站制作公司怎么选广告投放网
  • 企业网站建设上海自己开平台怎么弄啊
  • 网站移动端推广新闻头条今日要闻军事
  • gbk utf8网站速度怎样把产品放到网上销售
  • 电商网站建设与运营方向seo快速软件
  • wordpress删主题seo搜索引擎优化工作内容
  • app开发大约多少钱广州百度首页优化
  • 前端用什么框架做网站百度搜索的优势
  • 做网站前端难吗软文推广多少钱
  • 东莞网站建设方案网络营销软件哪个好用
  • 求一个全部用div做的网站企业seo职位
  • 阿里巴巴武汉网站建设百度seo报价方法
  • 自己做网站不推广宁波网络推广公司有哪些
  • 手机网站建设制作教程视频教程怎么找需要推广的商家
  • 网站关键词优化公司成都今天重大新闻事件