RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
GPIO_InitTypeDef GPIO_InitStructure;
//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);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
NVIC_InitTypeDef NVIC_InitStructure;
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器
//如果需要接收串口数据,则开启串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
typedef struct {
uint32_t USART_BaudRate; // 波特率
uint16_t USART_WordLength; // 字长
uint16_t USART_StopBits; // 停止位
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; // USART 模式
uint16_t USART_HardwareFlowControl; // 硬件流控制
} USART_InitTypeDef;
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = bound;//串口波特率
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 USART1_Send_Byte(u8 Data)
{
USART_GetFlagStatus(USART1, USART_FLAG_TC);
USART_SendData(USART1,Data);
while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );
}
//发送字符串,遇到字符串结尾标志'\0'结束
void USART1_Send_String(u8 *Data)
{
while(*Data)
USART1_Send_Byte(*Data++);
}
//按长度发送字符串,这种方法可以发送含0x00的字符串
void USART1_Send_String_By_Lens(u8 *Data, int Len)
{
int i;
for(i=0; i<Len; i++)
{
USART_SendData(USART1, Data[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //串口1发送数据
}
}
//重定向printf函数发送字符串,一般使用此函数直接输出打印调试信息,使用方法跟C语言中的使用方法一致。
int fputc(int ch, FILE *f)
{
USART_SendData( DEBUG_USARTx, (uint8_t) ch);
/* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return ch;
}
//串口1中断服务程序,此接收的数据是以0x0D、0x0A结尾为标志的数据帧。
void USART1_IRQHandler(void)
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
USART_ClearFlag(USART1, USART_IT_RXNE); //清除标志位
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res==0x0D)
USART_RX_STA|=0x4000;
else if(Res!=0x0a)
USART_RX_STA=0;//接收错误,重新开始
else
USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)
USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))
USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
//接收完数据之后,在main函数中对接收到的数据进行处理。
if(USART_RX_STA&0x8000)
{
//得到此次接收到的数据长度,即USART_RX_BUF数组中的有效数据长度
uart1Len=USART_RX_STA&0x3f;
//对接收到的数据进行数据处理,接收的数据暂存在USART_RX_BUF数组中
//... ...
USART_RX_STA=0;
memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //清空数组
}
喜欢请关注微信公众号:程序员小哈
公众号内容面向在校大学生、电子爱好者、嵌入式工程师;
涉及电子制作、模块使用、单片机技术、物联网相关知识分享;
软硬件全栈工程师,玩模块,学硬件,带你从0走到1
若觉得本次分享的文章对您有帮助,随手关注并转发分享,也是对我的支持。