定时器是我们在嵌入式单片机里应用最广泛的外设。使用定时器的水平高低也决定着整个项目实施的水平高低。本次版主给大家带了使用TIM3定时器产生PWM示例。例程主要使用TIM3来产生40K频率的方波,占空比通过按键可调,按键按下时,占空比增加。
实例还是比较简单的,版主就不再多多叙述,大家直接看源代码吧!
源代码:
/** * @brief tim3 pwm 40KHz * @param * @retval * @date 2015-03-31 * @note */ void TIM3PWM(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); /* GPIOA Configuration: TIM3 CH4 (PB1) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_1); /* Enable the TIM3 gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; /*!< 分频为48MHz */ TIM_TimeBaseStructure.TIM_Period = 1199; /*!< 40KHz频率 */ TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = gCCR4_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); TIM_Cmd(TIM3, ENABLE); } /** * @brief key check * @param * @retval * @date 2015-03-28 * @note */ void KeyCheck(void) { bool KeyStatus; KeyStatus = KeyScan(0); switch(gKeyStatus) { case 0: /*!< 空闲状态 */ { if(KeyStatus == true) { gKeyStatus = 1; } else { gKeyStatus = 0; LedOff(0); gSendCmdStatus = 0; } break; } case 1: /*!< 消抖状态 */ { if(KeyStatus == true) { gKeyCnt = 5; gKeyStatus = 2; } else { gKeyCnt = 0; gKeyStatus = 0; } break; } case 2: /*!< 按下状态 */ { if(KeyStatus == true) { if(gKeyCnt == 0) { //按键按下执行内容 LedOn(0); gSendCmdStatus |= 0x0F; } else { gKeyStatus = 2; } } else { gKeyCnt = 0; gKeyStatus = 0; } break; } case 3: /*!< 确认按下 */ { LedOn(0); break; } default: gKeyStatus = 0; } } /** * @brief uart_int * @param * @retval * @date 2015-03-29 * @note 发送使用DMA方式,接收使用中断 */ void UartConfig(uint32_t band) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Connect pin to Periph */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); /* Configure pins as AF pushpull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = band; USART_InitStructure.USART_WordLength = USART_WordLength_8b; 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); /* NVIC configuration */ /* Enable the USARTx Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_DeInit(DMA1_Channel2); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_TDR_ADDRESS; DMA_InitStructure.DMA_BufferSize = (uint16_t)256; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&gSendBuf[0]); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_Init(DMA1_Channel2, &DMA_InitStructure); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); USART_Cmd(USART1, ENABLE); } void main(void) { uint16_t i; int8_t Str[] = "hello EEPW\r\n"; gKeyStatus = 0; bspInit(); gCntLed[0] = 500; gCntLed[1] = 500; TxIndex = 0; gSendCnt = 12; gRcvBuf[0] = 100; gCCR4_Val = 99; for(i = 0; i < gSendCnt; i++) { gSendBuf[i] = Str[i]; } UartConfig(115200); if (SysTick_Config(48000)) //参数为系统时钟的向上溢出值,此配置为48000,即1ms中断一次 { /* Capture error */ while (1); } TIM3PWM(); while(1) { if(gCntLed[1] == 0) { LedToggle(1); gCntLed[1] = gRcvBuf[0] * 4; } KeyCheck(); if(gSendCmdStatus > 0) { if(gSendCmdStatus < 0x10) { gCCR4_Val = gCCR4_Val + 100; if(gCCR4_Val > 1000) { gCCR4_Val = 0; } TIM_SetCompare4(TIM3, gCCR4_Val); DMA_Cmd(DMA1_Channel2, DISABLE); DMA_SetCurrDataCounter(DMA1_Channel2, gSendCnt); DMA_Cmd(DMA1_Channel2, ENABLE); gSendCmdStatus |= 0xF0; } } } } /** * @brief SysTick_Handler的中断入口函数 * @param * @retval * @date 2014-11-23 * @note */ void SysTick_Handler(void) { if(gCntLed[0] > 0) { gCntLed[0]--; } else { gCntLed[0] = 0; } if(gCntLed[1] > 0) { gCntLed[1]--; } else { gCntLed[1] = 0; } if(gKeyCnt > 0) { gKeyCnt--; } else { gKeyCnt = 0; } } /** * @brief USART1_Handler的中断入口函数 * @param * @retval * @date 2015-03-29 * @note */ void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { gRcvBuf[0] = USART_ReceiveData(USART1); } }
工程文件: