单片机
返回首页

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 计数 */

}

//不需要中断


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章