练习题过程

文章详细介绍了如何在STM32平台上使用TIM14PWM进行脉冲宽度调制,同时配置TIM3定时器产生中断并利用SPI1进行数据通信,展示了嵌入式系统的定时器控制和串行通信应用。
摘要由CSDN通过智能技术生成

//pwm.c
#include"pwm.h"
#include"uart.h"
void TIM14_PWM_Init(u32 arr,u32 psc)      //PWM定时器14
{
  GPIO_InitTypeDef GPIO_InitStruct;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
  TIM_OCInitTypeDef TIM_OCInitStruct;
  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
  GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
  GPIO_Init(GPIOF,&GPIO_InitStruct);

  TIM_TimeBaseStruct.TIM_Prescaler=psc;  //定时器分频
  TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseStruct.TIM_Period=arr;   //自动重装载值
  TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1;
  TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStruct);   //初始化定时器14

  //初始化TIM14 Channel1 PWM模式
  TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
  TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
  TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_Low;
  TIM_OCInitStruct.TIM_Pulse=300;  //占空比300/500=60%
  TIM_OC1Init(TIM14,&TIM_OCInitStruct);  //
  
  TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM14,ENABLE);
  
  TIM_Cmd(TIM14,ENABLE);   //使能
}

 //pwm.h
#ifndef __PWM_H
#define __PWM_H	
#include "sys.h" 

void TIM14_PWM_Init(u32 arr,u32 psc);

#endif 

//timer.c
#include "time.h"
#include "led.h"
#include "adc.h"

u16 flag;
void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  NVIC_InitTypeDef NVIC_InitStruct;
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  
  
  TIM_TimeBaseInitStruct.TIM_Period=arr;
  TIM_TimeBaseInitStruct.TIM_Prescaler=psc;
  TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
  
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
  TIM_Cmd(TIM3,ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  NVIC_Init(&NVIC_InitStructure);        //初始化
}

extern u16 adcx;

//定时器中断服务函数
void TIM3_IRQHandler(void)
{
 if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
  {
    adcx=Get_Adc(ADC_Channel_10);    
    flag=1;
  }
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

 //timer.h
#ifndef __TIME_H
#define __TIME_H	
#include "sys.h" 

void TIM3_Int_Init(u16 arr,u16 psc);

extern u16 flag;


#endif 

//spi.c
#include "spi.h"

//SPI口初始化
//这里针是对SPI1的初始化
void SPI1_Init(void)
{	 
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟
 
  //GPIOFB 3,4,5初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//PB3~5复用功能输出	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1); //PB3复用为 SPI1 MISO
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); //PB4复用为 SPI1 MOSI
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1); //PB5复用为 SPI1 Slok
 
	//这里只针对SPI口初始化
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);  //复位SPI1
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE); //停止复位SPI1

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPI  主机
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//串行同步时钟的空闲状态为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI1, ENABLE); //使能SPI外设

	SPI1_ReadWriteByte(0xff);//启动传输		 
}   
//SPI1速度设置函数
//SPI速度=fAPB2/分频系数
//@ref SPI_BaudRate_Prescaler:SPI_BaudRatePrescaler_2~SPI_BaudRatePrescaler_256  
//fAPB2时钟一般为84Mhz:
void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
{
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
	SPI1->CR1&=0XFFC7;//位3-5清零,用来设置波特率
	SPI1->CR1|=SPI_BaudRatePrescaler;	//设置SPI1速度 
	SPI_Cmd(SPI1,ENABLE); //使能SPI1
} 
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{		 			 
 
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空  
	
	SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte  数据
		
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte  
 
	return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据	
 		    
}

  //spi.h
#ifndef __SPI_H
#define __SPI_H	
#include "sys.h" 


void SPI1_Init(void);			 //初始化SPI1口
void SPI1_SetSpeed(u8 SpeedSet); //设置SPI1速度   
u8 SPI1_ReadWriteByte(u8 TxData);//SPI1总线读写一个字节


#endif 

//main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
#include "time.h"
#include "pwm.h"
#include "spi.h"
u16 adcx;          //全局变量   

int main(void)
{ 
	float temp;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);    //初始化延时函数
	uart_init(115200);	//初始化串口波特率为115200
	Adc_Init();         //初始化ADC
	SPI1_Init();         //初始化SPI
  TIM3_Int_Init(5000-1,8400-1);      //定时器3
	TIM14_PWM_Init(500-1,84-1);       //PWM定时器14
   //TIM_SetCompare1(TIM14,300);	 //占空比60%输出     

	while(1)
	{ 
		if(flag == 1)        //标志位
		{
			flag = 0;
		  temp=(float)adcx*(3.3f/256);          //获取计算后的带小数的实际电压值,比如3.1
		printf("temp=%0.2f\r\n",temp);
		if(temp>1.5f)       //浮点型加(f)
		{
		  // TIM_Cmd(TIM14, ENABLE);
			TIM_SetCompare1(TIM14,0);
			 printf("pwm开启\r\n");
		}
		else                //接地
		{
			TIM_Cmd(TIM14, DISABLE);     //关闭TIM14
			printf("pwm关闭\r\n");
		}
		 SPI1_ReadWriteByte(adcx);
		printf("adcx=%d\r\n",adcx);
		
	}
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值