STM32F207下的实验(3)

目录:

1. DMA

2.Icapture

3. pwm

4. Time

1. DMA

led.h

#include"stm32f2xx.h"
#ifndef __LED_H

#define __LED_H

void LED_Init(void);

void Delay(vu32 nCount);

void CTL_LED(u8 LED_NUM, u8 OFF_ON);

	
#endif

led.c

#include"led.h"
#include"stm32f2xx.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
    //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
		
	//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	//GPIO_Init(GPIOF, &GPIO_InitStructure);
	//GPIO_SetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	GPIO_SetBits(GPIOD,GPIO_Pin_11|GPIO_Pin_12);
}

void Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}

void CTL_LED(u8 LED_NUM, u8 OFF_ON)
{
  switch(LED_NUM)
	{
	    case 0:
			if(OFF_ON == 1)
			{

				GPIO_ResetBits(GPIOD, GPIO_Pin_11);
			}
			else
			{
				GPIO_SetBits(GPIOD, GPIO_Pin_11);
			}
		    break;
		    
		case 1:
			if(OFF_ON == 1)
			{

				GPIO_ResetBits(GPIOD, GPIO_Pin_12);
			}
			else
			{
				GPIO_SetBits(GPIOD, GPIO_Pin_12);
			}
		    break;
		    
		//case 2:
			//GPIO_ResetBits(GPIOF, GPIO_Pin_9);
		   // break;
		//case 3:
			//GPIO_ResetBits(GPIOF, GPIO_Pin_10);
		    //break;
		default:
			//GPIO_ResetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
			GPIO_ResetBits(GPIOD,GPIO_Pin_11|GPIO_Pin_12);
		    break;
	}
}

usart_2.h

#include"stm32f2xx.h"
#include "stdio.h"	
#include "stm32f2xx_conf.h"
#include"led.h"

#ifndef __USART_2_H

#define __USART_2_H

void uart_init(u32 bound);
//void USART1_IRQHandler(void);
//void USART3_IRQHandler(void);


#define USART_REC_LEN  			200  	//最大接收字节数 200
//#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
#define EN_USART3_RX 			1		//使能(1)/禁止(0)串口3接收

	  	
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	

void uart_init(u32 bound);

#endif

usart_2.c

#include"stm32f2xx.h"
#include"usart_2.h"
#include"led.h"


//初始化IO 串口3
//bound:波特率

void uart_init(u32 bound)
{
	GPIO_InitTypeDef  GPIO_InitStructure;//首先定义一个GPIO初始化结构体
	USART_InitTypeDef USART_InitStructure;//定义一个串口初始化结构体
//	NVIC_InitTypeDef NVIC_InitStructure; //定义中断初始化结构
		
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//串口3是在APB1总线之下的,使能串口3的时钟,在rcc.h中
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //GPIO时钟使能
	
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //引脚复用映射,在gpio.h文件,第三个参数表示映射到什么功能
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);//表示将pinA9映射到串口3
	
	//GPIO端口初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//端口初始化
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;   //收发使能
	USART_InitStructure.USART_Parity = USART_Parity_No;  
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位字长
	
	USART_Init(USART3, &USART_InitStructure);//串口初始化
	USART_Cmd(USART3, ENABLE); //串口使能函数
	
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //中断使能,第二个参数表示使能哪一种中断,USART_IT_RXNE表示接收非空,即接收到数据,就要产生中断

}

dma.h

#include"stm32f2xx.h"
#ifndef __DAM_H_
#define __DAM_H_

void DMA_Config(DMA_Stream_TypeDef* DMA_Streamx);

void DMA_Enable(DMA_Stream_TypeDef* DMA_Streamx);

#endif

dma.c

#include"dma.h"

extern u8 SendBuff[8200];  //发送数据缓冲区

void DMA_Config(DMA_Stream_TypeDef* DMA_Streamx)
{
	DMA_InitTypeDef DMA_InitStructure;
	if((u32)DMA_Streamx > (u32)DMA2)
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);  //使能dma2时钟
	}
	else
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);  //使能dma1时钟
	}
	
	DMA_DeInit(DMA_Streamx);   //取消初始设置的DMA Streamx注册为默认复位值

	DMA_InitStructure.DMA_Channel = DMA_Channel_4;   //通道
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR;  //外设基地址
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SendBuff;  //存储器基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;        //方向
	DMA_InitStructure.DMA_BufferSize = 8200;   //传输量
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       //inc结尾,表示增量
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    //数据长度
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;        //模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;     //优先级
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;       //fifo
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //突发单次传输
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;        
	DMA_Init(DMA_Streamx, &DMA_InitStructure);        //初始化dma通道参数
}

void DMA_Enable(DMA_Stream_TypeDef* DMA_Streamx)
{
	DMA_Cmd(DMA_Streamx, DISABLE);		   //使能dma1通道,启动传输

	while(DMA_GetCmdStatus(DMA_Streamx) != DISABLE)   //查询dma的en位,确保数据流动续,可以配置
	{}

	DMA_SetCurrDataCounter(DMA_Streamx, 8200);    //设置通道当前剩余数据量

    DMA_Cmd(DMA_Streamx, ENABLE);		   //使能dma1通道,启动传输
}

main.c

#include"stm32f2xx.h"
#include"led.h"
#include"dma.h"
#include"usart_2.h"
#if 1
#define SEND_BUF_SIZE 8200

u8 SendBuff[SEND_BUF_SIZE];  //发送数据缓冲区
const u8 TEXT_TO_SEND[];

int main(void)
{ 
	//float pro = 0;    //进度
	u16 i;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	Delay(168);		    //延时初始化 
	uart_init(115200);	//串口初始化波特率为115200
	LED_Init();		  	//初始化与LED连接的硬件接口

	DMA_Config(DMA1_Stream3);

	for(i = 0; i < SEND_BUF_SIZE; i++)
	{
		SendBuff[i] = 1;
	}
	
	USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);    //使能串口dma发送
	//DMA_Enable(DMA1_Stream3);
	DMA_Cmd(DMA1_Stream3, ENABLE);	
	
	while(1)
	{
		//TCIFx表示数据流x传输完成中断标志,中文参考p221
		if(DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF3) != RESET)    //查询dma传输状态,TCIF后的系数与stream后的系数保持一致
		{
			DMA_ClearFlag(DMA1_Stream3, DMA_FLAG_TCIF3);
			break;
		}
		//pro = DMA_GetCurrDataCounter(DMA1_Stream3);    //获取、设置通道当前剩余数据量
		//pro = 1-pro/SEND_BUF_SIZE;//	  
		//pro*=100;      			    //得到百分比
		//while(pro == 100)
		//{
		//	CTL_LED(0, 1);
		//}
		
		CTL_LED(1, 1);	
		Delay(10000000);
		//CTL_LED(0, 1);
	}	
	
}
#endif

2. Icapture

usart_2.h

#include"stm32f2xx.h"
#include "stdio.h"	
#include "stm32f2xx_conf.h"
#include"led.h"

#ifndef __USART_2_H

#define __USART_2_H

void uart_init(u32 bound);
//void USART1_IRQHandler(void);
//void USART3_IRQHandler(void);


#define USART_REC_LEN  			200  	//最大接收字节数 200
//#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
#define EN_USART3_RX 			1		//使能(1)/禁止(0)串口3接收

	  	
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	

void uart_init(u32 bound);

#endif

usart_2.c

#include"stm32f2xx.h"
#include"usart_2.h"
#include"led.h"


//初始化IO 串口3
//bound:波特率

#if 1
#pragma import(__use_no_semihosting)             
//±ê×??aDèòaμ??§3?oˉêy                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//   
_sys_exit(int x) 
{ 
	x = x; 
} 

int fputc(int ch, FILE *f)
{ 	
	while((USART3->SR&0X40)==0);
	USART3->DR = (u8) ch;      
	return ch;
}
#endif

void uart_init(u32 bound)
{
	GPIO_InitTypeDef  GPIO_InitStructure;//首先定义一个GPIO初始化结构体
	USART_InitTypeDef USART_InitStructure;//定义一个串口初始化结构体
		
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//串口3是在APB1总线之下的,使能串口3的时钟,在rcc.h中
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //GPIO时钟使能
	
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //引脚复用映射,在gpio.h文件,第三个参数表示映射到什么功能
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);//表示将pinA9映射到串口3
	
	//GPIO端口初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//端口初始化
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;   //收发使能
	USART_InitStructure.USART_Parity = USART_Parity_No;  
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位字长
	
	USART_Init(USART3, &USART_InitStructure);//串口初始化
	USART_Cmd(USART3, ENABLE); //串口使能函数
	
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //中断使能,第二个参数表示使能哪一种中断,USART_IT_RXNE表示接收非空,即接收到数据,就要产生中断

}

Icapture.h

#include"stm32f2xx.h"
#ifndef __PWM_H_
#define __PWM_H_

void TIM9_CH1_Cap_Init(u32 arr, u32 psc);

void TIM1_BRK_TIM9_IRQHandler(void);


#endif

Icapture.c

#include"stm32f2xx.h"
#include"Icapture.h"

u8  TIM9CH1_CAPTURE_STA = 0;	//输入捕获状态,0表示还没有捕获到上升沿中断
u32	TIM9CH1_CAPTURE_VAL;	   //输入捕获值(TIM9是32位还是16位)

void TIM9_CH1_Cap_Init(u32 arr, u32 psc)  
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);   
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

	//初始化io口
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_TIM9);  //设置引脚复用映射,将GPIOE5复用为TIM9

	//初始化TIM9
	TIM_TimeBaseInitStructure.TIM_Period = arr;    //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;	//预分频系数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //分频器系数
	TIM_TimeBaseInit(TIM9, &TIM_TimeBaseInitStructure);

 	//输入捕获通道初始化函数
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;     //捕获通道
	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;    //捕获极性
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;    //映射关系
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;    //分频系数
	TIM_ICInitStructure.TIM_ICFilter = 0x00;    //滤波器
	TIM_ICInit(TIM9, &TIM_ICInitStructure);

	TIM_ITConfig(TIM9, TIM_IT_Update|TIM_IT_CC1, ENABLE);   //开启捕获中断和更新中断
	
	TIM_Cmd(TIM9, ENABLE);  //使能定时器TIM9
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn; //XTI9_5_IRQn;  8和14共用TIM8_TRG_COM_TIM14_IRQn
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	
	
	//TIM_OC1PreloadConfig(TIM9, TIM_OCPreload_Enable);	//使能输出比较预装载,使能tim14在ccr1上的预装载寄存器
	//TIM_ARRPreloadConfig(TIM9, ENABLE);	// 使能自动重装载的预装载寄存器的允许位, ARPE使能
}

void TIM1_BRK_TIM9_IRQHandler(void)     //中断服务函数,在启动文件中
{ 
	if((TIM9CH1_CAPTURE_STA&0x80) == 0)    //TIM9CH1_CAPTURE_STA的第八位为0,还未成功捕获
	{
		if(TIM_GetITStatus(TIM9, TIM_IT_Update) != RESET)    //溢出,检查TIM9的更新中断是否产生,RESET=0
		{
			if(TIM9CH1_CAPTURE_STA&0x40)      //已经捕获到高电平
			{
				if((TIM9CH1_CAPTURE_STA&0X3F) == 0X3F)  //高电平较长
				{
					TIM9CH1_CAPTURE_STA|=0X80;		// 标记成功地捕获了一次
					TIM9CH1_CAPTURE_VAL = 0XFFFFFFFF;    //32个1
				}
				else 
					TIM9CH1_CAPTURE_STA++;
			}
		}

		if(TIM_GetITStatus(TIM9, TIM_IT_CC1) != RESET)//检查TIM9的捕获中断是否发生
		{	
			if(TIM9CH1_CAPTURE_STA&0X40)		//	已经捕获到下降沿	
			{	  			
				TIM9CH1_CAPTURE_STA|=0X80;		//标记成功地捕获了一次高电平脉宽
			    TIM9CH1_CAPTURE_VAL = TIM_GetCapture1(TIM9);//获取当前的捕获值
	 			TIM_OC1PolarityConfig(TIM9, TIM_ICPolarity_Rising); //cc1p = 0, 设置为上升沿捕获
			}
			else  								//TIM9CH1_CAPTURE_STA的第6位为0,则还没有捕获到新的上升沿,先将下面几个值清0
			{
				TIM9CH1_CAPTURE_STA = 0;			//清空
				TIM9CH1_CAPTURE_VAL = 0;
				TIM9CH1_CAPTURE_STA|=0X40;		//设置TIM9CH1_CAPTURE_STA的第6位为1,标记捕获到了上升沿
				//TIM_Cmd(TIM9, DISABLE ); 	//关闭定时器9
	 			TIM_SetCounter(TIM9, 0);     //定时器计数值清0
	 			TIM_OC1PolarityConfig(TIM9, TIM_ICPolarity_Falling);  //通道极性设置独立函数,cc1p = 1, 设置为下降沿捕获,等待下降沿到来,low = falling
				TIM_Cmd(TIM9, ENABLE ); 	//使能定时器9
			}		    
	    }
	}
	TIM_ClearITPendingBit(TIM9, TIM_IT_CC1|TIM_IT_Update);    //清空中断和捕获标志位
}

main.c

#include"stm32f2xx.h"
#include"usart_2.h"
//#include"led.h"
#include"Icapture.h"

extern u8  TIM9CH1_CAPTURE_STA;	
extern u32	TIM9CH1_CAPTURE_VAL;	

int main(void)
{ 
	long long temp = 0;  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Delay(168);		    
	//LED_Init();		  	
	uart_init(115200);
	
	TIM9_CH1_Cap_Init(0XFFFFFFFF, 84-1);  //arr的值是32个1,足够大
	
	while(1)
	{
 		Delay(10);			 
 		if(TIM9CH1_CAPTURE_STA&0X80)        //最高位为1,表示捕获完成
		{
			temp = TIM9CH1_CAPTURE_STA&0X3F;   //temp表示捕获高电平定时器溢出的次数
			temp*=0XFFFFFFFF;		 		         //溢出次数与arr的乘积
			temp+=TIM9CH1_CAPTURE_VAL;		   //时间长度内,cnt计数的次数
			printf("HIGH:%lld us\r\n", temp); //
			TIM9CH1_CAPTURE_STA = 0;			     //TIM9CH1_CAPTURE_STA置0,就可以开启第二次捕获
		}
	}
}


3. pwm

led.h

#include"stm32f2xx.h"
#ifndef __LED_H

#define __LED_H


void LED_Init(void);

void Delay(vu32 nCount);

void CTL_LED(u8 LED_NUM, u8 OFF_ON);

	
#endif

led.c

#include"led.h"
#include"stm32f2xx.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOD, &GPIO_InitStructure);
	GPIO_SetBits(GPIOD, GPIO_Pin_12);
}


void Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}

#if 0
void CTL_LED(u8 LED_NUM, u8 OFF_ON)
{
  switch(LED_NUM)
	{
	    case 0:
			if(OFF_ON == 1)
			{

				GPIO_ResetBits(GPIOD, GPIO_Pin_11);
			}
			else
			{
				GPIO_SetBits(GPIOD, GPIO_Pin_11);
			}
		    break;
		    
		case 1:
			if(OFF_ON == 1)
			{

				GPIO_ResetBits(GPIOD, GPIO_Pin_12);
			}
			else
			{
				GPIO_SetBits(GPIOD, GPIO_Pin_12);
			}
		    break;
		default:
			//GPIO_ResetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
			GPIO_ResetBits(GPIOD,GPIO_Pin_11|GPIO_Pin_12);
		    break;
	}
}
#endif

pwm.h

#include"stm32f2xx.h"
#ifndef __PWM_H_
#define __PWM_H_

void TIM4_PWM_Init(u32 arr, u32 psc);


#endif

pwm.c

#include"stm32f2xx.h"
#include"pwm.h"

void TIM4_PWM_Init(u32 arr, u32 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   //使能定时器4时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);   //使能gpio时钟

	GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);  //将GPIOD12复用为TIM4
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	

	//初始化TIM4  输出通道  初始化输出比较参数
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;    //模式1决定,当cnt<ccr1时,通道1为有效电平
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //极性,有效电平是高电平还是低电平
	TIM_OC1Init(TIM4, &TIM_OCInitStructure);

	//初始化TIM4初始化 pwm模式
	TIM_TimeBaseInitStructure.TIM_Period = arr;    //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;  //预分频系数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //分频器系数
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);
	
    TIM_Cmd(TIM4, ENABLE);  //使能TIM14

	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能输出比较预装载,使能tim14在ccr1上的预装载寄存器
	TIM_ARRPreloadConfig(TIM4, ENABLE);    // 使能自动重装载的预装载寄存器的允许位, ARPE使能
	
}

main.c

#include"stm32f2xx.h"
#include"led.h"
#include"pwm.h"

int main(void)
{ 
	u16 ledpwmval = 0;   //ledpwmval是TIM_pulse
	u8 dir = 1;         //dir值控制方向
	LED_Init();		  	//初始化与LED连接的硬件接口

	TIM4_PWM_Init(499, 29);    //29是预分频系数,则定时器计数频率是30/29+1=1um,周期由arr决定,重转载值是500,则由1和500,可知整个周期是500
	TIM_SetCompare1(TIM4, 50);   //程序中频率可变的led灯实验不明显,这里设置为占空比为50%的,可通过示波器查看效果
	
	
	while(1)
	{	
#if 0

		Delay(20);
		if(dir)
		{
			ledpwmval++;
		}
		else
		{
			ledpwmval--;
		}

		if(ledpwmval > 300)    //dir值控制方向
		{ 
			dir = 0;
		}
		else if(ledpwmval == 0)
		{
			dir = 1;
		}
		
		TIM_SetCompare1(TIM4, ledpwmval);   //设置比较值函数,ledpwmval是变量,则不断改变占空比,从而led灯亮度变化
#endif
	}

}

4. Time

led.h

#include"stm32f2xx.h"
#ifndef __LED_H

#define __LED_H


void LED_Init(void);

void Delay(vu32 nCount);

void CTL_LED(u8 LED_NUM, u8 OFF_ON);

	
#endif

led.c

#include"led.h"
#include"stm32f2xx.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOD, &GPIO_InitStructure);
	GPIO_SetBits(GPIOD,GPIO_Pin_11|GPIO_Pin_12);
}

void Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}

void CTL_LED(u8 LED_NUM, u8 OFF_ON)
{
  switch(LED_NUM)
	{
	    case 0:
			if(OFF_ON == 1)
			{

				GPIO_ResetBits(GPIOD, GPIO_Pin_11);
			}
			else
			{
				GPIO_SetBits(GPIOD, GPIO_Pin_11);
			}
		    break;
		    
		case 1:
			if(OFF_ON == 1)
			{

				GPIO_ResetBits(GPIOD, GPIO_Pin_12);
			}
			else
			{
				GPIO_SetBits(GPIOD, GPIO_Pin_12);
			}
		    break;
		default:
			//GPIO_ResetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
			GPIO_ResetBits(GPIOD,GPIO_Pin_11|GPIO_Pin_12);
		    break;
	}
}

time.h

#include"stm32f2xx.h"
#ifndef __TIME_H_
#define __TIME_H_

void TIM3_Int_Init(u32 arr, u32 psc);

void TIM3_IRQHandler(void);


#endif

time.c

#include"stm32f2xx.h"
#include"time.h"
#include"led.h"

void TIM3_Int_Init(u32 arr, u32 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  //使能定时器时钟

	TIM_TimeBaseInitStructure.TIM_Period = arr;    //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;  //预分频系数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //分频器系数
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);

	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	TIM_Cmd(TIM3, ENABLE);

	//初始化中断函数
	NVIC_InitStructure.NVIC_IRQChannel= TIM3_IRQn;  //xx.h
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;  
	NVIC_Init(&NVIC_InitStructure);   	
}

void TIM3_IRQHandler(void)  //中断服务函数,在启动文件中
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)   //确定中断为更新中断
	{
		CTL_LED(0, 1);
	}
	TIM_ClearITPendingBit(TIM3, TIM_IT_Update);	
}

main.c

#include"stm32f2xx.h"
#include"led.h"
#include"time.h"

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	Delay(168);		    //延时初始化 
	LED_Init();		  	//初始化与LED连接的硬件接口

	TIM3_Int_Init(49999, 8399);

	while(1)
	{
		CTL_LED(1, 1);	
		Delay(200);
	}
}


猜你喜欢

转载自blog.csdn.net/juliarjuliar/article/details/79785663
今日推荐