引子
其实楼主蓝桥杯报名之前接触32也有段时间,串口和上文的E2PROM了解或接触过,应用也不少但是因为做小项目不像蓝桥杯需要自己写收发函数等,这方面例程也很多都是拿来直接用。所以准备的过程中也是发现这两块有点陌生也有点怵,不过依然没有花很多时间准备因为感觉不会考很深。(结果就翻车了),十二届省赛就考了串口。不过还好前一天晚上问了问班里大佬,突击了下考场上还是基本实现了。
CT117E用的是串口2
串口驱动快速编写
引脚 TXD->PA2 RXD->PA3
全双工工作模式发送引脚推挽复用,接收引脚浮空/上拉输入
**参考STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Interrupt **
main.c选择一组串口复制代码
中断服务函数
补充
中断号位置stm32f10x.h
中断服务函数名位置startup_stm32f10x_md.s
数据收发
发送其实可以有多种方法,好像开启发送中断也是可以的(没试过)。后来发现重定义fput然后用printf更简单。
接收就在中断服务函数中操作,在标准库的基础上修改。下面介绍下发送
参考STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Printf main.c
使用:
1.keil配置
2.引用stdio.h不然你函数会报找不到
代码
#ifndef _USART_H_
#define _USART_H_
#include "stm32f10x.h"
#include "stdio.h"
void Usart2_Init(void);
int fputc(int ch, FILE *f);
void sendString(uint8_t *data);
#endif
#include "usart.h"
extern uint8_t RxBuffer[];
extern __IO uint8_t RxCounter;
extern __IO uint8_t RxFlag;
void Usart2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
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(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
int fputc(int ch, FILE *f)
{
USART_ClearFlag(USART2, USART_FLAG_TC);
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART2, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{}
return ch;
}
void sendString(uint8_t *data)
{
while(*data)
{
USART_SendData(USART2, *data++);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{}
}
}
void USART2_IRQHandler(void)
{
u16 temp;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
/* Read one byte from the receive data register */
temp = USART_ReceiveData(USART2);
if(temp == '\n') return ;
if(temp == '\r')
{
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
RxCounter=0;
RxFlag=1;
return;
}
RxBuffer[RxCounter++] = temp;
if(RxCounter >= 30)
{
RxCounter = 0;
}
}
}
问题
1.收发数据乱码或不显示
不显示可能是串口选择错误,会出现两个串口号,一般选择数值大那个。
数据乱码可能是代码的波特率和串口助手的配置不一致。
2.程序卡死在中断
标准库函数是开启了发送中断的,注意初始化不要添加这一句。不然你中断服务函数会一直进发送中断,同时你没有写相应内容就会卡死。
3.打印接收或发送数据丢第一字节
解决方法:函数开头添加清除标志位函数