1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
#if 1 /// 重定向c库函数printf到USART1 int fputc(int ch, FILE *f) { /* 发送一个字节数据到USART1 */ USART_SendData(USART1, (uint8_t) ch); /* 等待发送完毿*/ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); } /// 重定向c库函数scanf到USART1 int fgetc(FILE *f) { /* 等待串口1输入数据 */ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1); } #endif /*********************************************END OF FILE**********************/ USART 只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留USART 接口来实现与其他模块或者控制器进行数据传输,比如 GSM 模块, WIFI 模块、蓝牙模块
配合原子的 usmart可以方便的进行调试,使用usmart可以通过串口调用函数,可以传参数非常方便。 void NVIC_Configuration_1(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 配置 NVIC 为优先级绿1 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置中断源:按键 1 */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; /* 配置抢占优先级: 1 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; /* 配置子优先级_1 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; /* 使能中断通道 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART1_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* config USART1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); /* USART1 GPIO config */ /* Configure USART1 Tx (PA.09) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Rx (PA.10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART1 mode config */ USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; 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); NVIC_Configuration_1(); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, DISABLE); (void)USART1->SR; (void)USART1->DR; USART_ClearFlag(USART1, USART_FLAG_TC); USART_ClearITPendingBit(USART1, USART_IT_RXNE); USART_Cmd(USART1, ENABLE); } void USART1_IRQHandler_FUN(void) { u8 data; (void)USART1->SR; //Error clear; data = (u8)(USART1->DR & (u16)0x01FF); USART_ClearITPendingBit(USART1, USART_IT_RXNE); resevice_buf(data);// get_buf_usart1[get_usart1_i] = data; USART_SendData(USART1, data); get_usart1_i++; if(get_buf_usart1[0] != 0xFF) { get_usart1_i=0; } if(get_usart1_i==4) { AnalizingBuf2(); get_usart1_i = 0; gRxHostBufferFlush(4,get_buf_usart1); } } /// 重定向c库函数printf到USART1 int fputc(int ch, FILE *f) { /* 发送一个字节数据到USART1 */ USART_SendData(USART1, (uint8_t) ch); /* 等待发送完毿*/ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); } /// 重定向c库函数scanf到USART1 int fgetc(FILE *f) { /* 等待串口1输入数据 */ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1); } 使用USART1进行串口调试,打印信息到电脑 程序是如何找到中断服务程序呢?在启动文件startup_stm32f10x_md.s中有这样一段代码,汇编DCD USART1_IRQHandler stm32串口调试是一个很好的方法 一般有4个上的串口,可以将printf函数重定向到一个UART。这样就可以用printf函数将单片机的数据打印到PC上的超级终端或串口调试助手。 可以通过串口发送一些参数方便调试,可以用一个协议易于操作 //定义一个协议,关于数据收发的 //第一位:判断数据是否正确 //第二位:判断数据是否正确 //第三位:存放参数多少 //第四位:参数[1] //第五位:参数[2] //第n位:参数[n] /* Buffur_Full接受完毕标志位,意思可以解析程序了 */ char get_From_PC[64]; bool Buffur_Full = FALSE;//定义成全局变量 char buf[64];//定义成全局变量 int buf_conut =0 void DEBUG_USART_IRQHandler(void) { uint8_t ucTemp; if (USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { buf[buf_conut++] = USART_ReceiveData( USART1 ); PacketCheck(); } } void BufferFlush(u32 BufferSize){ for(u32 counter=0; counter } void PacketCheck(void) { int para_length = 0; //Header Check if(buf[0]!=0xff){ BufferFlush(buf_conut); buf_conut=0; return; } else if(buf_conut==1) return; if(buf[1]!=0xff){ BufferFlush(buf_conut); buf_conut=0; return; } else if(buf_conut==2) return; if(buf_conut>2) { para_length = buf[2]; if(buf_conut - 2> para_length) { for(int i= 0;i { get_From_PC = buf[i+3]; } } if(buf_conut == para_length +2) { Buffur_Full = TURE; gRxHostBufferFlush(buf_conut); buf_conut = 0; } } } /* 嵌套向量中断控制器 NVIC 配置 中断控制器 NVIC 配置 */ static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置 USART 为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; /* 抢断优先级为 1 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 子优先级为 1 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置 NVIC */ NVIC_Init(&NVIC_InitStructure); } 工作模式配置 //USART 初始化配置 void Debug_USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* 使能 USART GPIO 时钟 */ RCC_AHB1PeriphClockCmd(DEBUG_USART_RX_GPIO_CLK | DEBUG_USART_TX_GPIO_CLK, ENABLE); /* 使能 USART 时钟 */ RCC_APB2PeriphClockCmd(DEBUG_USART_CLK, ENABLE); /* GPIO 初始化 */ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 配置 Tx 引脚为复用功能 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN ; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); /* 配置 Rx 引脚为复用功能 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); /* 连接 PXx 到 USARTx_Tx*/ GPIO_PinAFConfig(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_SOURCE, DEBUG_USART_RX_AF); /* 连接 PXx 到 USARTx__Rx*/ GPIO_PinAFConfig(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_SOURCE, DEBUG_USART_TX_AF); /* 配置串 DEBUG_USART 模式 */ /* 波特率设置: DEBUG_USART_BAUDRATE */ USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; /* 字长(数据位+校验位): 8 */ USART_InitStructure.USART_WordLength = USART_WordLength_8b; /* 停止位: 1 个停止位 */ USART_InitStructure.USART_StopBits = USART_StopBits_1; /* 校验位选择:不使用校验 */ USART_InitStructure.USART_Parity = USART_Parity_No; /* 硬件流控制:不使用硬件流 */ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; /* USART 模式控制:同时使能接收和发送 */ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* 完成 USART 初始化配置 */ USART_Init(DEBUG_USART, &USART_InitStructure); /* 嵌套向量中断控制器 NVIC 配置 */ NVIC_Configuration(); /* 使能串口接收中断 */ USART_ITConfig(DEBUG_USART, USART_IT_RXNE, ENABLE /* 使能串口 */ USART_Cmd(DEBUG_USART, ENABLE); } GPIO_PinAFConfig 函数接收三个参数,第一个参数为 GPIO 端口,比如 GPIOA;第二个参数是指定要复用的引脚号,比如 GPIO_PinSource10;第三个参数是选择复用外设,比如 GPIO_AF_USART1。该函数最终操作的是 GPIO 复用功能寄存器 GPIO_AFRH 和GPIO_AFRL,分高低两个。 字符发送 /***************** 发送一个字符 **********************/ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* 发送一个字节数据到 USART */ USART_SendData(pUSARTx,ch); /* 等待发送数据寄存器为空 */ 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)!=' |