实训day5_1|pwm、串口通信

PWM

呼吸灯显示
在这里插入图片描述

pwm的配置步骤:

  1. 使能相关时钟:RCC_AHB1PeriphClockCmd()RCC_AHB2PeriphClockCmd()
  2. 配置相关的引脚模式、速度、以及复用功能:使用GPIO_InitTypeDef结构体
  3. 使能TIM时钟:GPIO_PinAFConfig()
  4. 设置分频、周期:使用TIM_TimeBaseInitTypeDef结构体
  5. 产生一次更新事件,更新影子寄存器的值。
  6. 在CCMR中设置PWM模式:使用TIM_OCInitTypeDef结构体
  7. 设置各通道占空比。占空比= CCRx / ARR
  8. 使能比较输出
  9. 使能预装载寄存器,使能自动重装载的预装载寄存器允许位
  10. 使能定时器:TIM_Cmd()
    led.h、sys.h、delay.h、led.c、delay.c和之前文章里的一样就不复制过来了,可以查阅往期

main.c

#include "led.h"
#include "sys.h"
#include "delay.h"
#include "pwm.h"

int main(void)
{
	unsigned int arr;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//滴答时钟  168/8=21MHz
	LED_init();
	led_off();
	
	Pwm_Init();
	
	while(1)
	{
		
//		for(arr=0;arr<100;arr++)
//		{
//		
//			TIM_SetCompare1(TIM13, arr);
//			delay_ms(10);
//		}
//		
//		for(arr=100;arr>0;arr--)
//		{
//			TIM_SetCompare1(TIM13, arr);
//			delay_ms(10);
//		}
		
		
		for(arr=0;arr<100;arr++)
		{
		
			TIM_SetCompare1(TIM14, arr);
			delay_ms(10);
		}
		
		for(arr=100;arr>0;arr--)
		{
			TIM_SetCompare1(TIM14, arr);
			delay_ms(10);
		}
		
		
		
		
		for(arr=0;arr<100;arr++)
		{
		
			TIM_SetCompare3(TIM1, arr);
			delay_ms(10);
		}
		
		for(arr=100;arr>0;arr--)
		{
			TIM_SetCompare3(TIM1, arr);
			delay_ms(10);
		}
		
		
		for(arr=0;arr<100;arr++)
		{
		
			TIM_SetCompare4(TIM1, arr);
			delay_ms(10);
		}
		
		for(arr=100;arr>0;arr--)
		{
			TIM_SetCompare4(TIM1, arr);
			delay_ms(10);
		}
		
		
		

	}

	//return 0;
	

}


pwm.h

#ifndef __PWM_H__
#define __PWM_H__

#include "stm32f4xx.h"

void Pwm_Init(void);

#endif

pwm.c

#include "pwm.h"

void Pwm_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_OCInitTypeDef       TIM_OCInitStruct;
//	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13 | RCC_APB1Periph_TIM14, ENABLE);//42MHz
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	
	
	
	GPIO_InitStruct.GPIO_Pin =    GPIO_Pin_8 | GPIO_Pin_9 ;//PF8   PF9
	GPIO_InitStruct.GPIO_Mode =    GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType =   GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_PuPd =    GPIO_PuPd_UP;//上拉
	GPIO_InitStruct.GPIO_Speed =   GPIO_Fast_Speed;//高速   50MHz
	GPIO_Init(GPIOF,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin =    GPIO_Pin_13 | GPIO_Pin_14;//PE13   PE14
	GPIO_InitStruct.GPIO_Mode =    GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType =   GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_PuPd =    GPIO_PuPd_UP;//上拉
	GPIO_InitStruct.GPIO_Speed =   GPIO_Fast_Speed;//高速   50MHz
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	
	
	
	//此时不做GPIO,做什么事情给指定好
	//GPIO_PinAFConfig(GPIOF,GPIO_PinSource8,GPIO_AF_TIM13);
	GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1); 
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1);
	
	TIM_TimeBaseInitStruct.TIM_Period =  100-1;//重装载值  65535   我给5000就是500ms  
	TIM_TimeBaseInitStruct.TIM_Prescaler = 8400-1;//预分频器 1-65535  84MHz/8400=10000Hz--->1s
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//不分频了
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	
	//TIM_TimeBaseInit(TIM13, &TIM_TimeBaseInitStruct);
	TIM_TimeBaseInit(TIM14, &TIM_TimeBaseInitStruct);
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);
	
	TIM_OCInitStruct.TIM_OCMode      = TIM_OCMode_PWM1;//模式1
	TIM_OCInitStruct.TIM_OCPolarity  = TIM_OCPolarity_Low;//低电平有效
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//使能
	//TIM_OC1Init(TIM13, &TIM_OCInitStruct);
	TIM_OC1Init(TIM14, &TIM_OCInitStruct);
	TIM_OC3Init(TIM1, &TIM_OCInitStruct);
	TIM_OC4Init(TIM1, &TIM_OCInitStruct);
	//使能预装载寄存器
	//TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable);
	TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);
	TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
    //使能自动重装载的预装载寄存器允许位
	//TIM_ARRPreloadConfig(TIM13,ENABLE);	
	TIM_ARRPreloadConfig(TIM14,ENABLE);
	TIM_ARRPreloadConfig(TIM1,ENABLE);
	TIM_CtrlPWMOutputs(TIM1,ENABLE);
	//TIM_Cmd(TIM13,ENABLE);//使能定时器
	TIM_Cmd(TIM14,ENABLE);
	TIM_Cmd(TIM1,ENABLE);
}


串口通信

  1. 实现通过串口输入1打开蜂鸣器,输入0关闭蜂鸣器
  2. 实现通过蓝牙输入1打开蜂鸣器,输入0关闭蜂鸣器

要安装相关驱动和串口调试工具
在这里插入图片描述
在这里插入图片描述
前往GitHub下载调试工具

main.c

led.c和led.h和之前几篇文章里的一致

#include "led.h"
#include "uart.h"
int main(void)
{
	LED_init();		//gpio初始化

	Uart1_Init(9600);
	Uart3_Init(9600);
	return 0;
}


uart.h

#ifndef __UART_H__
#define __UART_H__

#include "stm32f4xx.h"

void Uart1_Init(unsigned int band);
void Uart3_Init(unsigned int band);

#endif

uart.c

#include "uart.h"
#include "sys.h"
void Uart1_Init(unsigned int band)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	//必须先初始化时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin =     GPIO_Pin_9 | GPIO_Pin_10;//PA9   PA10
	GPIO_InitStruct.GPIO_Mode =    GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType =   GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_PuPd =    GPIO_PuPd_UP;//上拉
	GPIO_InitStruct.GPIO_Speed =   GPIO_Fast_Speed;//高速   50MHz
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//此时是往串口1复用
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	USART_InitStruct.USART_BaudRate = band;//波特率
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流
	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//数据收发
	USART_InitStruct.USART_Parity = USART_Parity_No;//没有校验位
	USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位1位
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位8位
	USART_Init(USART1,&USART_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//UART1
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x1;//抢占优先级   0-3
	NVIC_InitStruct.NVIC_IRQChannelSubPriority =0x3;//响应优先级           0-3
	NVIC_Init(&NVIC_InitStruct); 	
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	USART_Cmd(USART1,ENABLE);
}


void Uart3_Init(unsigned int band)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	//必须先初始化时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin =     GPIO_Pin_10 | GPIO_Pin_11;//PB10   PB11
	GPIO_InitStruct.GPIO_Mode =    GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType =   GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_PuPd =    GPIO_PuPd_UP;//上拉
	GPIO_InitStruct.GPIO_Speed =   GPIO_Fast_Speed;//高速   50MHz
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3);
	
	USART_InitStruct.USART_BaudRate = band;//波特率
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流
	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//数据收发
	USART_InitStruct.USART_Parity = USART_Parity_No;//没有校验位
	USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位1位
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位8位
	USART_Init(USART3,&USART_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;//UART3
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x1;//抢占优先级   0-3
	NVIC_InitStruct.NVIC_IRQChannelSubPriority =0x3;//响应优先级           0-3
	NVIC_Init(&NVIC_InitStruct); 	
	
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	
	USART_Cmd(USART3,ENABLE);
}





//中断服务函数     在startup_stm32f40_41xxx.s 里面找
void USART1_IRQHandler(void)
{
	char a;
	//判断确实进中断
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
	//if((USART1->SR &(0x1<<5))!=0)
	{
		//立马清楚中断线
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
		//USART1->SR &= ~(0x1<<5);
		a=USART_ReceiveData(USART1);
		if(a == '1')
		{
			PFout(8)=1;
		}
		if(a == '0')
		{
			PFout(8)=0;
		}
	
	}
}


void USART3_IRQHandler(void)
{
	char b;
	//判断确实进中断
	if(USART_GetITStatus(USART3,USART_IT_RXNE)==SET)
	//if((USART3->SR &(0x1<<5))!=0)
	{
		//立马清楚中断线
		USART_ClearITPendingBit(USART3,USART_IT_RXNE);
		//USART3->SR &= ~(0x1<<5);
		b=USART_ReceiveData(USART3);
		if(b == '1')
		{
			PFout(8)=1;
		}
		if(b == '0')
		{
			PFout(8)=0;
		}
	
	}
}

**有个地方要注意:**输入频率要一致,比如说8000000(8M),如果在.h文件不是8M就要改成一致的8M,一般情况下文件会设为只读所以直接修改不了,要文件夹找到对应文件,取消设置的只读才能修改,改完后建议重新设回只读,起保护作用。
在这里插入图片描述
在这里插入图片描述
右击后选择Open Containing Folder就可以前往该文件位置了,然后右击设置属性勾选是否只读
在这里插入图片描述
打开PortHelper.exe,发送1和0即可
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值