STM32F103官方初始化模板
2018-08-12 来源:eefocus
#include 'stm32f10x_lib.h'
系统时钟初始化函数==========================================================================================
void RCC_Configuration(void)
{
/* 定义枚举类型变量 HSEStartUpStatus */
ErrorStatus HSEStartUpStatus;
/* 复位系统时钟设置*/
RCC_DeInit();
/* 开启HSE*/
RCC_HSEConfig(RCC_HSE_ON);
/* 等待HSE起振并稳定*/
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/* 判断HSE起是否振成功,是则进入if()内部 */
if(HSEStartUpStatus == SUCCESS)
{
/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* 设置FLASH延时周期数为2 */
FLASH_SetLatency(FLASH_Latency_2);
/* 使能FLASH预取缓存 */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* 使能PLL */
RCC_PLLCmd(ENABLE);
/* 等待PLL输出稳定 */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
/* 选择SYSCLK时钟源为PLL */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* 等待PLL成为SYSCLK时钟源 */
while(RCC_GetSYSCLKSource() != 0x08);
}
/* 打开APB2总线上的GPIOA时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
}
GPIO口初始化函数====================================================================================================
void GPIO_Configuration(void)
{
/* 定义GPIO初始化结构体 GPIO_InitStructure */
GPIO_InitTypeDef GPIO_InitStructure;
/* 设置 GPIOA.4 为推挽输出,最大翻转频率为50MHz*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
常用GPIO函数:
GPIO_WriteBit(GPIOA,GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_4)));//翻转GPIOA.4电平
GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_11); //读取电平,返回1或0;
系统节拍定时器初始化====================================================================================================
void Systick_Configuration(void)
{
SysTick_CounterCmd(SysTick_Counter_Disable); /* 失能Systick定时器 */
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); /* 选择HCLK为Systick时钟源 */
SysTick_CounterCmd(SysTick_Counter_Clear); /* 清除Systick计数器 */
SysTick_SetReload(900); /* 主频为72/8MHz,配置计数值为900 可以得到0.1ms定时间隔*/
}
利用系统节拍定时器延时0.1ms函数(带参)================================================================================
void Delay_01ms(int c)
{
int cc;
for(cc=0;cc SysTick_CounterCmd(SysTick_Counter_Enable);/* 启动Systick计数 */ while(SysTick_GetFlagStatus(SysTick_FLAG_COUNT) == 0); /* 等待Systick计数至0 */ SysTick_CounterCmd(SysTick_Counter_Disable); /* 失能Systick定时器 */ SysTick_CounterCmd(SysTick_Counter_Clear); /* 清除Systick计数器 */ } } //SysTick_ITconfig(ENABLE);//使能SysTick中断 利用USART1进行串口通信初始化============================================================================================== void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; //波特率为9600bps USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 8位数据长度 USART_InitStructure.USART_StopBits = USART_StopBits_1;// 1个停止位,无校验 USART_InitStructure.USART_Parity = USART_Parity_No ; // 禁用硬件流控制 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 禁止USART时钟 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //在第2个边沿捕获数据,最后一位数据的时钟脉冲不从 SCLK 输出 USART_Init(USART1 , &USART_InitStructure); USART_Cmd(USART1 , ENABLE); // /* 使能USART1 */ } /* 设置USART1的Tx脚(PA.9)为第二功能推挽输出模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA , &GPIO_InitStructure); /* 设置USART1的Rx脚(PA.10)为浮空输入脚 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA , &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB , ENABLE); 串口通信模板=========================================================================================================== /* 等待USART1接收数据完毕 */ if(USART_GetFlagStatus(USART1 , USART_IT_RXNE) == SET) { /* 向串口发送接收到的数据 */ USART_SendData(USART1 , USART_ReceiveData(USART1)); /* 短延时,保证收发稳定性 */ for(i = 0; i < 500; i ++); } 翻转电平=============================================================================================================== GPIO_WriteBit(GPIOA,GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_4)));//翻转GPIOA.4电平 判断串口接收数据======================================================================================================== if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET) 位带操作================================================================================================================ #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //Êä³ö #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //ÊäÈë #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //Êä³ö #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //ÊäÈë #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //Êä³ö #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //ÊäÈë #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //Êä³ö #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //ÊäÈë #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //Êä³ö #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //ÊäÈë #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //Êä³ö #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //ÊäÈë #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //Êä³ö #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //ÊäÈë #define LED PAout(8)// 定义PA8 NVIC中断优先级配置====================================================================================================== void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_RAM , 0x0); /* 中断向量表起始地址从 0x20000000 开始 */ #else NVIC_SetVectorTable(NVIC_VectTab_FLASH , 0x0); /* 中断向量表起始地址从 0x80000000 开始 */ #endif NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 选择NVIC优先级分组2 */ NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQChannel; /* 使能EXIT 2通道 ,1级先占优先级 ,0级次占优先级 (0级优先级最高)*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 外部中断设置============================================================================================================ void EXIT_Configuration(void) { EXTI_InitTypeDef EXTI_InitStructure; /* 设置外部中断0通道(EXIT Line0)在下降沿时触发中断 */ EXTI_InitStructure.EXTI_Line = EXTI_Line2 ; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // EXTI_GenerateSWInterrupt(EXTI_Line2);//这个函数可以软件进入中断 } //注意:在void GPIO_Configuration(void)函数中需要添加如下:(或者在当前函数下添加) //GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource2);//此处选定PA2引脚,所占用中断必为EXIT2 //注意:使用外部中断必须打开复用口时钟,在void RCC_Configuration(void)中需要添加如下: //RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);后面的AFIO //中断服务函数在stm32f10x_it.c中,中断结束需要清除,如:EXTI_ClearFlag(EXTI_Line2); 窗口看门狗设置=========================================================================================================== 在RCC配置中加入:RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); void WWDG_Configuration(void) { WWDG_SetPrescaler(WWDG_Prescaler_8); /* 设置WWDG预分频值为8,WWDG时钟频率 = (PCLK1/4096)/8 = 244 Hz(~4ms)*/ WWDG_Enable(0x7F);/* 设置WWDG初始计数值为0x7F并启动WWDG,此时WWDG 超时时间为4ms * (0x7F - 0x3F) = 264ms */ WWDG_ClearFlag(); /* 清除 WWDG 早期唤醒中断(EWI)标志 */ WWDG_EnableIT(); /* 使能 WWDG 早期唤醒中断(EWI) */ } 在NVIC配置中加入: NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//先占优先级1(用户值可选) NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStructure); 在中断服务文件中的void WWDG_IRQHandler(void)函数中加入: WWDG_SetCounter(0x7F);/* 更新 WWDG 计数器 */ WWDG_ClearFlag(); /* 清除 WWDG 早期唤醒中断(EWI)标志 */ 在main中的初始化区域里加入以检查是否发生过窗口看门狗复位: if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { printf('\r\n The STM32 has been reset by WWDG \r\n'); RCC_ClearFlag(); /* 清除看门狗复位标志 */ } else { WWDG_Configuration();/* 设置 WWDG */ printf('\r\n The STM32 has't been reset by WWDG before \r\n'); } ADC采集PB0口电压模拟值==================================================================================================== void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; RCC_ADCCLKConfig(RCC_PCLK2_Div4);/* 配置ADC时钟分频 */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立工作模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //多通道扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续模数转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换触发方式:转换由软件触发启动 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //进行规则转换的 ADC 通道的数目为1 ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);//设置ADC1使用8转换通道转换顺序1采样时间为55.5周期 ADC_Cmd(ADC1, ENABLE);/* 使能 ADC1 */ ADC_ResetCalibration(ADC1);/* 复位 ADC1 的校准寄存器 */ while(ADC_GetResetCalibrationStatus(ADC1)); /* 等待 ADC1 校准寄存器复位完成 */ ADC_StartCalibration(ADC1);/* 开始 ADC1 校准 */ while(ADC_GetCalibrationStatus(ADC1)); /* 等待 ADC1 校准完成 */ ADC_SoftwareStartConvCmd(ADC1, ENABLE);/* 启动 ADC1 转换 */ } 定义输出模拟量 float VolValue RCC配置: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 |RCC_APB2Periph_GPIOB, ENABLE); GPIO配置,将 PB.0 设置为模拟输入脚: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOB , &GPIO_InitStructure); 采集函数: VolValue = 2.56 * ADC_GetConversionValue(ADC1) / 0X0FFF; //2.56为参考电压,0X0FFF为转换结果最大值 通用定时器之基本定时===================================================================================================== void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_DeInit(TIM2); //复位TIM2定时器 TIM_InternalClockConfig(TIM2); //采用内部时钟给TIM2提供时钟源 TIM_TimeBaseStructure.TIM_Period = 2000; // 1s (2000*500us) TIM_TimeBaseStructure.TIM_Prescaler = 36000-1; // 分频36000 (500us) TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方向向上计数 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除TIM2溢出中断标志 TIM_ARRPreloadConfig(TIM2,DISABLE); //禁止ARR预装载缓冲器(如果允许就能够更改TIM_period:2000这个值) TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //TIM2溢出中断允许 TIM_Cmd(TIM2, ENABLE); //开启tim2计数 } RCC配置中加入:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); NVIC配置中加入: NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 中断服务函数: if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET){ //GPIO_WriteBit(GPIOB,GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_8))); TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);//清除TIM2的中断待处理位 } 常用函数: TIM2->CNT=0; //清零计数器 TIM=TIM_GetCounter(TIM2); //将TIM2里计数器的值返回给变量TIM 通用计时器--时间基准====================================================================================================== (此段代码并不充分,其基本功能是用一个定时器来定时4个不同时间段来改变4个IO口电平,通道不需要与IO口相匹配) vu16 CCR1_Val = 40000; /* 初始化输出比较通道1计数周期变量*/ vu16 CCR2_Val = 20000; /* 初始化输出比较通道2计数周期变量*/ vu16 CCR3_Val = 10000; /* 初始化输出比较通道3计数周期变量*/ vu16 CCR4_Val = 5000; /* 初始化输出比较通道4计数周期变量*/ void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/* 定义 TIM_TimeBase 初始化结构体 TIM_TimeBaseStructure */ TIM_OCInitTypeDef TIM_OCInitStructure;/* 定义 TIM_OCInit 初始化结构体 TIM_OCInitStructure */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2 , &TIM_TimeBaseStructure); TIM_PrescalerConfig(TIM2 , 7199 , TIM_PSCReloadMode_Immediate);/* 设置预分频值,且立即装入 */ /* * 设置 OC1,OC2,OC3,OC4 通道 * 工作模式为计数器模式 * 使能比较匹配输出极性 * 时钟分割0 * 向上计数模式 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); /* 禁止预装载寄存器 */ TIM_OC1PreloadConfig(TIM2 , TIM_OCPreload_Disable); TIM_OC2PreloadConfig(TIM2 , TIM_OCPreload_Disable); TIM_OC3PreloadConfig(TIM2 , TIM_OCPreload_Disable); TIM_OC4PreloadConfig(TIM2 , TIM_OCPreload_Disable); TIM_ITConfig(TIM2 , TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 , ENABLE); /* 使能 TIM 中断 */ TIM_Cmd(TIM2 , ENABLE);/* 启动 TIM 计数 */ } 中断服务程序: extern vu16 CCR1_Val; /* 外部声明输出比较通道1计数周期变量*/ extern vu16 CCR2_Val; /* 外部声明输出比较通道2计数周期变量*/ extern vu16 CCR3_Val; /* 外部声明输出比较通道3计数周期变量*/ extern vu16 CCR4_Val; /* 外部声明输出比较通道4计数周期变量*/ vu16 capture = 0; /* 当前捕获计数值局部变量 */ if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { // GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_4))) capture = TIM_GetCapture1(TIM2);/* 读出当前计数值 */ TIM_SetCompare1(TIM2, capture + CCR1_Val);/* 根据当前计数值更新输出捕获寄存器 */ TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);//清除中断标志 } else if...... 通用定时器之PWM输出======================================================================================================== (此段代码并不充分,其基本功能是用一个定时器在4个口输出PWM信号,注意!通道必须与IO口相匹配) vu16 CCR1_Val = 60000; /* 初始化输出比较通道1计数周期变量 */ vu16 CCR2_Val = 30000; /* 初始化输出比较通道2计数周期变量 */ vu16 CCR3_Val = 15000; /* 初始化输出比较通道3计数周期变量 */ vu16 CCR4_Val = 7500; /* 初始化输出比较通道4计数周期变量 */ RCC配置: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /* 打开 TIM2 时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /* 打开 APB 总线上的 GPIOA,USART1 时钟 */ GPIO配置: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //与通道对应 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //第二功能推挽输出 void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseStructure.TIM_Period = 60000; // 计数重载值为6000 TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频值为(0+ 1 = 1) TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2 , &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作模式为 PWM 输出模式 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能比较匹配输出极性 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //向上计数模式 TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //得到的占空比分别为 100%, 50%, 25%, 12.5% TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); /* 使能预装载寄存器 */ TIM_OC1PreloadConfig(TIM2 , TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM2 , TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM2 , TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM2 , TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); //注意!!这个要启动! TIM_Cmd(TIM2 , ENABLE);/* 启动 TIM 计数 */ } //不需要中断