串口usart1

串口usart1

#include "stm32f4xx.h"
#include<stdio.h>

GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;


void delay_us(uint32_t nus)
{
	SysTick->CTRL = 0; // 关闭滴答定时器
	SysTick->LOAD = (SystemCoreClock/8/1000000)*nus; // 计数值
	SysTick->VAL = 0; // 清空当前值和状态标志位
	SysTick->CTRL = 1; // 启动定时器工作
	// 检测CTRL的第16位是否为0,如果为0表示定时时间到达
	while ((SysTick->CTRL & 0x00010000)==0);
	
	SysTick->CTRL = 0; //失能(关闭)滴答定时器
}

void delay_ms(uint32_t nms)
{	
	while(nms--)
	{
		SysTick->CTRL = 0; // 关闭滴答定时器
		SysTick->LOAD = (SystemCoreClock/8/1000); // 计数值
		SysTick->VAL = 0; // 清空当前值和状态标志位
		// 选择时钟源(如果是5表示选择168M工作,如果是1选择21M工作)并启动定时器工作
		SysTick->CTRL = 1; 
		// 检测CTRL的第16位是否为0,如果为0表示定时时间到达
		while ((SysTick->CTRL & 0x00010000)==0);
		
		SysTick->CTRL = 0; //失能(关闭)滴答定时器
	}
	
}

void init_usart1(uint32_t baud)
{
	USART_InitTypeDef USART_InitStructure;	
	
	// 使能PA时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	// 使能串口1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	// 将PA9 PA10连接到串口1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	// 配置GPIO A9 A10为第二功能模式
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AF; // 复用模式
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // 推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
	// 初始化GPIOA
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	// 配置串口属性
	USART_InitStructure.USART_BaudRate = baud; // 波特率
	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优先级
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 触发串口1中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	// 使能串口1工作
	USART_Cmd(USART1,ENABLE);
	
	// 使能串口1接收中断,如果有数据达到,触发中断服务函数
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

}

// 发送字符
void usart_send_ch(unsigned char ch)
{
	// 发送数据
	USART_SendData(USART1,ch);
	// 等待发送完成
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) != SET);

}

// 发送字符串
void usart_send_str(const char  *pbuf)
{
	while(*pbuf != '\0')
	{
		// 发送数据
		USART_SendData(USART1,*pbuf++);
		// 等待发送完成
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) != SET);
		
	}
	
}

//实现fputc
int fputc(int ch,FILE *f)
{
	//将字符发送到串口调试助手
	USART_SendData(USART1,ch);
	// 等待发送完成
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) != SET);
	return ch;
}

int main(void)
{
	// 设置系统时钟源8分频,21M
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
	// 配置优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	// 串口初始化
	init_usart1(115200);
	
	//usart_send_ch('a');
	usart_send_str("hello jack\r\n");
	
	//当调用printf函数的时候会自动调用fputc
	printf("hello rose\r\n");
	
	while(1){}
}

// 串口中断服务函数用于接收数据
void USART1_IRQHandler(void)
{
	uint16_t data;
	// 检测是否有数据达到,状态发生改变
	if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
	{
		// 接收数据
		data = USART_ReceiveData(USART1);
		
		// 将数据打印输出
		usart_send_ch(data);
		
		// 接收完毕,清空中断标志位
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
		
	}

}	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值