基于STM32的SPWM源代码
- 格式:wps
- 大小:28.50 KB
- 文档页数:5
include "DSP281x_Device.h" // DSP281x Headerfile Include File# include "DSP281x_Examples.h" // DSP281x Examples Include Filevoid init_eva(void);void main(void){InitSysCtrl();// InitGpio(); 配置IO口功能为PWM模式EALLOW;GpioMuxRegs.GPAMUX.all = 0x00FF; // EVA PWM 1-6 pinsEDIS;DINT; //关CPU总中断InitPieCtrl(); //初始化PIE控制寄存器IER = 0x0000;IFR = 0x0000;InitPieVectTable(); //初始化PIE中断向量表init_eva(); //初始化EV-AEvaRegs.T1CON.bit.TENABLE=1; //手工启动定时器EINT; // 使能INTM(全局中断)ERTM; // Enable Global realtime interrupt DBGMfor(;;);}//EV-A初始化void init_eva(void){EvaRegs.T1PR = 37500; //周期值--连续增减时,PWM频率=TCLK/(2*T1PR)---频率设为1K, PWM=75M/(2*37500)EvaRegs.T1CMPR = 0x3C00; // Compare Reg--比较值EvaRegs.T1CNT = 0x0000; //计数器初值//连续增/减模式,x/1分频,内部时钟,使能比较,使用自己的周期,禁止定时器启动(等初始化全部完成后手工启动)EvaRegs.T1CON.all = 0x0802;EvaRegs.GPTCONA.bit.TCMPOE = 1; //通过逻辑产生T1 PWMEvaRegs.GPTCONA.bit.T1PIN = 1; //GP定时器1比较时低有效//使能比较产生1--6 PWM波1个比较单元控制2路互补的PWM输出,控制PWM占空比//连续增减--低有效时:PWM占空比=CMPR1/T1PR,高有效时:PWM占空比=(T1PR-CMPR1)/T1PR EvaRegs.CMPR1 = 15000; //第一路PWM占空比设为0.4,0.4=15000/37500EvaRegs.CMPR2 = 0x3C00;EvaRegs.CMPR3 = 0xFC00;// output pin 1 CMPR1 - 高有效,output pin 2 CMPR1 - 低有效// output pin 3 CMPR2 - 高有效,output pin 4 CMPR2 - 低有效// output pin 5 CMPR3 - 高有效,output pin 6 CMPR3 - 低有效EvaRegs.ACTRA.all = 0x0666; //比较方式控制寄存器,控制PWM引脚的高/低有效EvaRegs.DBTCONA.all = 0x0000; //静止死区CONA.all = 0xA600; //比较控制寄存器--禁止空间矢量PWM模式}总结:PWM波形产生流程1):将I/O口设置为PWM引脚模式2):设置装载TxCON,决定计数方式,启动比较操作3):设置装载TxPR,决定PWM波形周期4):初始化EvaRegs.CMPR1--3的值,每个比较单元控制2路互补的PWM输出,控制PWM占空比5):EvaRegs.ACTRA比较方式控制寄存器,控制PWM引脚的高/低有效6):EvaRegs.DBTCONA死区时间的设置7):CONA设置比较控制寄存器附:EvaRegs.DBTCONA.bit.DBT=5; //死区定时器周期为5EvaRegs.DBTCONA.bit.EDBT1=1; //死区定时器1使能EvaRegs.DBTCONA.bit.DBTPS=3; //死区定时器预定标因子,死区时钟为HSPCLK/8示例程序2:一个产生PWM波的样例程序,用于TMS320F2812(2006-07-24 21:59:09)转载这两个星期一直在做PWM波的程序,发现网上这方面的比较少,若有又没有中文注释。
这是main.c 主程序//这是STM32F103ZE的一个模板//在PA8 PB13 产生一个互补的PWM波,频率为10KHz,占空比为1/5#include "stm32f10x.h"BitAction bbt=0; //定义一个位变量bbt,并清0u16 i;int main(void){u16 InitValue,Pre_Divide,ZKB;SystemInit(); //系统时钟初始化,调用该函数后,系统时钟为72M,函数原形在system_stm32f10x.c中GPIO_init();//****TIM1_PWM波1通道设置****************************************************************InitValue=7200; //初值1000Pre_Divide=1; //预分频1ZKB=1200; //占空比TIM1_PWM_1_init(InitValue,Pre_Divide,ZKB);//TIM1->CCR1=2400; //修改占空比//***************************************************************************** *********while(1){//}}这是sysinit.c 系统程序#include "stm32f10x.h"void GPIO_init(){GPIO_InitTypeDef GPIO_InitStructure; //声明端口结构,需要放在前面RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);//开启相应端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//***************端口A8,A9,A10是TIM1_PWM波的输出端***************************GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PWM波设为复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口频率可设为2,10,50 GPIO_Init(GPIOA, &GPIO_InitStructure); //启动A端口//***************************************************************************//**************端口B13,B14,B15是TIM1_PWM波的互补输出端**********************GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //端口频率可设为2,10,50 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //PWM波的复用推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure); //启动B端口//***************************************************************************}//****TIM1_PWM波1通道初始化**********************************************************************void TIM1_PWM_1_init(u16 InitValue, u16 Pre_Divide, u16 CCR1_Val){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM_BDTRInitTypeDef TIM_BDTRInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);TIM_TimeBaseStructure.TIM_Period =InitValue;TIM_TimeBaseStructure.TIM_Prescaler =Pre_Divide-1;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;TIM_TimeBaseStructure.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);TIM_ARRPreloadConfig(TIM1,ENABLE); //使能TIM1在ARR上的预装载寄存器TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;// 选择定时器模式TIM脉冲宽度调制模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //选择输出比较状态TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //选择互补输出比较状态TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //选择输出极性TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //选择互补输出极性TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //设置待装入捕获比较寄存器的脉冲值TIM_OC1Init(TIM1, &TIM_OCInitStructure);//捕获比较匹配器结构1通道赋值TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR1上的预装载寄存器//死区设置TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;//TIM1_OSSRState设置在运行模式下非工作状态选项TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;//TIM1_OSSIState设置在空闲模式下非工作状态选项(使能TIM1 OSSI状态)TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; //TIM1_LOCKLevel设置了锁电平参数(不锁任何位)TIM_BDTRInitStructure.TIM_DeadTime = 0x90; //这里调整死区大小0-0xff,TIM1_DeadTIM1指定了输出打开和关闭状态之间的延时TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; //TIM1_Break使能或者失能TIM1刹车输入(失能TIM1刹车输入)TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;//TIM1_BreakPolarity 设置TIM1刹车输入管脚极性(TIM1刹车输入管脚极性高)TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//TIM1_AutomaticOutput使能或者失能自动输出功能(自动输出功能使能)TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);//(设置刹车特性,死区时间,锁电平,OSSI,OSSR状态和AOE(自动输出使能))TIM_Cmd(TIM1, ENABLE); //使能或者失能指定的TIM1TIM_CtrlPWMOutputs(TIM1, ENABLE); //使能或者失能TIM1外设的主输出}。
STM32笔记(二)TIM模块产生PWM这个是STM32的PWM输出模式,STM32的TIM1模块是增强型的定时器模块,天生就是为电机控制而生,可以产生3组6路PWM,同时每组2路PW M为互补,并可以带有死区,可以用来驱动H桥。
下面的代码,是利用TIM1模块的1、2通道产生一共4路PWM的代码例子,类似代码也可以参考ST的固件库中相应exampleC语言: TIM1模块产生PWM,带死区//Step1.开启TIM和相应端口时钟//启动GPIORCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GP IOB | \RCC_APB2Periph_GPIOC | RCC_APB2Periph_GP IOD,\ENABLE);//启动AFIORCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//启动TIM1RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//Step2. GPIO做相应设置,为AF输出//PA.8/9口设置为TIM1的OC1输出口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//PB.13/14口设置为TIM1_CH1N和TIM1_CH2N输出口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//Step3. TIM模块初始化void TIM_Configuration(void){TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM_BDTRInitTypeDef TIM_BDTRInitStructure;//TIM1基本计数器设置(设置PWM频率)//频率=TIM1_CLK/(ARR+1)TIM_BaseInitStructure.TIM_Period = 1000-1;TIM_BaseInitStructure.TIM_Prescaler = 72-1;TIM_BaseInitStructure.TIM_ClockDivision = 0;TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_BaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure);//启用ARR的影子寄存器(直到产生更新事件才更改设置)TIM_ARRPreloadConfig(TIM1, ENABLE);//TIM1_OC1模块设置(设置1通道占空比)TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enabl e;TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Ena ble;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_Pulse = 120;TIM_OC1Init(TIM1, &TIM_OCInitStructure);//启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置)TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//TIM2_OC2模块设置(设置2通道占空比)TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enabl e;TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Ena ble;TIM_OCInitStructure.TIM_Pulse = 680;TIM_OC2Init(TIM1, &TIM_OCInitStructure);//启用CCR2寄存器的影子寄存器(直到产生更新事件才更改设置)TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);//死区设置TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;TIM_BDTRInitStructure.TIM_DeadTime = 0x90; //这里调整死区大小0-0xffTIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity _High;TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOu tput_Enable;TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);//TIM1开启TIM_Cmd(TIM1, ENABLE);//TIM1_OC通道输出PWM(一定要加)TIM_CtrlPWMOutputs(TIM1, ENABLE);}其实,PWM模块还可以有很多花样可以玩,比方在异常时(如CPU时钟有问题),可以紧急关闭输出,以免发生电路烧毁等严重事故。
SPWM的程序说明用TMS320LF2407实现三相SPWM波形发生器FCL .usect ".data0",1 ;保存载波频率浮点数的低位FCH .usect ".data0",1 ;保存载波频率浮点数的高位FRL .usect ".data0",1 ;保存信号频率浮点数的低位FRH .usect ".data0",1 ;保存信号频率浮点数的高位AL .usect ".data0",1 ;保存调谐度浮点数低位AH .usect ".data0",1 ;保存调谐度浮点数高位N .usect ".data0",1 ;保存一个周期要输出的PWM脉冲个数NL .usect ".data0",1 ;保存一个周期要输出的PWM脉冲个数浮点数低位NH .usect ".data0",1 ;保存一个周期要输出的PWM脉冲个数浮点数低位I .usect ".data0",1 ;保存当前输出的是第几个脉冲T3PR_TEMPL .usect ".data0",1 ;保存定时器3周期寄存器值的浮点数低位T3PR_TEMPH .usect ".data0",1 ;保存定时器3周期寄存器值的浮点数高位DATIOL .usect ".data0",1 ;保存占空比浮点数低位DATIOH .usect ".data0",1 ;保存占空比浮点数低位DFLAG .usect ".data0",1 ;送出一个脉冲的标志寄存器.include "F2407REGS.H" ;引用头部文件.ref F$$ITOF,F$$DIV,F$$MUL,F$$FTOI,F$$ADD,F$$LTOF,F$$SUB .ref _sin.def _c_int0;(1)建立中断向量表.sect ".vectors" ;定义主向量段RSVECT B _c_int0 ;PM 0 Reset Vector 1INT1 B PHANTOM ;PM 2 Int level 1 4INT2 B GISR2 ;PM 4 Int level 2 5INT3 B PHANTOM ;PM 6 Int level 3 6INT4 B PHANTOM ;PM 8 Int level 4 7INT5 B PHANTOM ;PM A Int level 5 8INT6 B PHANTOM ;PM C Int level 6 9RESERVED B PHANTOM ;PM E (Analysis Int) 10SW_INT8 B PHANTOM ;PM 10 User S/W int —••SW_INT31 B PHANTOM ;PM 3E User S/W int —;中断子向量入口定义pvecs.sect ".pvecs" ;定义子向量段PVECTORS B PHANTOM ;Reserved pvector addr offset-0000hB PHANTOM ;Reserved pvector addr offset-0001h••B PHANTOM ;Reserved pvector addr offset-002EhB T3GP_ISR ;Reserved pvector addr offset-002Fh T3PINT中断B PHANTOM ;Reserved pvector addr offset-0030h••B PHANTOM ;Reserved pvector addr offset-0041h;(2)主程序.text_c_int0:CALL SYSINIT ;调系统初始化子程序CALL PWM_INIT ;调PWM初始化子程序LDP #5SPLK #2710H,FCL ;载波频率SPLK #0,FCHSPLK #032H,FRL ;信号频率SPLK #0,FRHSPLK #3E8H,AL ;调谐度AL=A*1000SPLK #0,AHSPLK #0,I ;I=0SPLK #1,DFLAGCALL JISUANLOOP:LDP #5BIT DFLAG,BIT0BCND LOOP,NTCLACL DFLAGAND #0FFFEHSACL DFLAGCALL DATIOB LOOP;(3)系统初始化程序SYSINIT:SETC INTMCLRC CNFLDP #0SPLK #02h,IMR ;使能第1级中断2SPLK #0FFFFh,IFR ;清第1级所有中断标志位LDP #DP_PF1SPLK #0E8h,WDCR ;禁止WDTLDP #00E0HSPLK #81FEH,SCSR1 ;CLKIN=6M,CLKOUT=24 M RET;(4)EVB模块的PWM初始化程序PWM_INIT:LDP #DP_PF2LACL MCRAOR #07EH ;IOPE1~IOPE6SACL MCRC ;配置为特殊功能LACL MCRCSACL MCRCLDP #DP_EVBSPLK #0FFFFh,EVBIFRA ;清EV A的所有中断标志位SPLK #0555h,ACTRB ;PWM6,4,2 为低,PWM5,3,1 为高SPLK #00h,DBTCONB ;禁止死区控制SPLK #1fh,CMPR4 ;给比较寄存器赋初值SPLK #2Fh,CMPR5SPLK #3fh,CMPR6SPLK #0960h,T3PR ;给周期寄存器赋初值LDP #5SPLK #0960h,T3PR_TEMPLSPLK #0,T3PR_TEMPHLDP #DP_EVBSPLK #0A600h,COMCONB ;禁止比较功能SPLK 0,T3CNTSPLK #41h,GPTCONBSPLK #080h,EVBIMRASPLK #0000101101001110b,T3CONCLRC INTMRET;(5)将一些整数转换为浮点数子程序,得到计算占空比要用的常数JISUAN:LDP #5 ;调谐度由整形转换为浮点LACL ALLRLK AR1,STACK ;设置STACK指针SETC SXMCALL F$$ITOF,AR1 ;A=a×1000CLRC SXMMAR *-LACC *-,16ADDS *SACL ALSACH AHLRLK AR1,STACK ;A/2000=0.5 aSETC SXMLACL #0SACL *+LACL #44FAH ;44FA 0000h =2000SACL *+LACL ALSACL *+LACL AHSACL *+CALL F$$DIVLACC *-,16ADDS *SACL ALSACH AHLACL T3PR_TEMPLLRLK AR1,STACKSETC SXM ;定时器周期寄存器;的值转换为浮点数CALL F$$ITOF,AR1CLRC SXMMAR *-LACC *-,16ADDS *SACL T3PR_TEMPLSACH T3PR_TEMPHLACL FCL ;FC值转换为浮点数LRLK AR1,STACKSETC SXMCALL F$$LTOF,AR1CLRC SXMMAR *-LACC *-,16ADDS *SACL FCLSACH FCHLACL FRLLRLK AR1,STACKSETC SXM ;FR值转换为浮点数CALL F$$ITOF,AR1CLRC SXMMAR *-LACC *-,16ADDS *SACL FRLSACH FRHLRLK AR1,STACK ;N=FC/FR LACL FRLSACL *+LACL FRHSACL *+LACL FCLSACL *+LACL FCHCALL F$$DIVMAR *-LACC *-,16ADDS *SACL NLSACH NH ;N的浮点数LRLK AR1,STACKSETC SXMSACL *+SACH *+CALL F$$FTOISACL N ;N的整数LRLK AR1,STACKSACL *+LACL NHSACL *+LACL #0F5C3H ;40C8F5C3h=6.282=2×3.141 SACL *+LACL #40C8HSACL *+CALL F$$DIVMAR *-LACC *-,16ADDS *SACL NLSACH NHRET;(6)计算占空比子程序DATIO:LDP #5LACL I ;I由整形转换为浮点数LRLK AR1,STACKSETC SXMCALL F$$ITOF,AR1CLRC SXMMAR *-LACC *-,16ADDS * ;结果保存在ACCLRLK AR1,STACK ;i*2*3.14/NSACL *+SACH *+LACL NLSACL *+LACL NHCALL F$$MULMAR *-ZALH *-ADDS *LRLK AR1,STACK ;sin(i*2*3.14/N)SACL *+SACH *+CALL _sin ;结果在ACCLRLK AR1,STACK ;0.5a*sin(i*2*3.14/N)SACL *+SACH *+LACL ALSACL *+LACL AHSACL *+CALL F$$MULMAR *-ZALH *-ADDS * ;结果在ACCLRLK AR1,STACK ;D=0.5+A*sin(i*2*3.14/N) SACL *+SACH *+LACL #0SACL *+LACL #3F00H ;3F00 0000h =0.5SACL *+CALL F$$ADDMAR *-ZALH *-ADDS * ;结果在ACCLRLK AR1,STACKSACL *+SACH *+LACL T3PR_TEMPLSACL *+LACL T3PR_TEMPHSACL *+CALL F$$MULMAR *-ZALH *-ADDS * ;结果在ACCLRLK AR1,STACK ;CMPR的浮点数转换为整数SETC SXMSACH *+CALL F$$FTOI,AR1CLRC SXM ;结果在ACCSACL DATIOLLDP #5LACC ISUB NBCND NSPWM,GEQLACC IADD #1SACL IB RRETNSPWM:SPLK #0,I ;断是否是下一个周期RRET:RETPHANTOM:KICK_DOG ;复位WD计数器RET;(7)定时器3中断程序GISR2:SST #0,ST0_CON1 ;保存状态寄存器SST #1,ST1_CON1LDP #0E0h ;DP指针指向PIVR 所在的数据区LACC PIVR,1 ;读EVIVRB, 结果左移一位ADD #PVECTORS ;加上偏移量BACCT3GP_ISR:LDP #5LACC DFLAGOR #1 ;设置DFLAG.15=1SACL DFLAGLACL DATIOLLDP #DP_EVBSACL CMPR4 ;更新比较寄存器的值ADD #32HSACL CMPR5ADD #32HSACL CMPR6LDP #0LST #1,ST1_CON1LST #0,ST0_CON1LDP #DP_EVBSPLK #0FFFFH,EVBIFRACLRC INTMRETEND。
基于单片机的逆变电源设计摘要:为了适应当今新能源发展速度,逆变电源技术也在不断更新换代。
本文介绍了一款基于STM32芯片的SPWM逆变电源系统。
采用BOOST升压技术和SPWM逆变技术,将180V的直流电转换成220V的工频优质正弦交流电。
直流电经过升压斩波电路进入控制电路,在经过LC低通滤波器,滤除高次谐波,得到频率可调的正弦波交流输出。
本系统由升压模块,逆变模块,控制模块,反馈模块,保护模块构成具有良好的性能并实现了数字智能化为家用电器提供了一种可靠、优质的交流电源。
关键词:STM32逆变电源SPWM升压斩波电路1.课题研究背景和意义在日新月异的今天,新能源的应用范围越来广阔,而对于如何将其所转化的电输入到电网或者设备所需要的稳压恒频、体积小、重量轻、噪音低、效率高的交流电成为了成为逆变电源研制领域所要解决的问题。
逆变电源是一种采用电力电子技术进行电能变换的装置,它的作用是将输入的高低不同压,大小不同频的电转化为电网、设备、用户所需频率的交流电输出。
目前逆变电源所跨领域之大,所涉范围之广逆变电源的改进不仅能在新能源中有着不可缺少的作用,还在车载电器、野外作业、应急抢险和移动办公中有着重要的地位;而各行各业要求着逆变电源朝着更高的效率,更低的成本和更高的可靠性,还必须环保无污染,但是传统的逆变电源难以实现以上要求。
因而研究数字化、模块化的绿色逆变电源技术对当今提出的节能,高效,绿色,环保工业口号实现具有重要意义。
1.课题研究内容本论文基于当前新能源发展活跃的背景下市场对逆变电源特定负载性能和外特性功能要求下,设计了一种还具备安全可靠、高效、高功率因素、低噪音、绿色无污染的基于STM32单片机芯片的逆变电源。
1.系统总体设计1.系统设计指标采用STM32单片机作为控制主控芯片来设计一款能产生可靠、优质的交流正弦逆变电源。
开关频率:21.5KHz输入电压:直流电48V输出电压:交流电220V/50Hz输出功率:5kw逆变效率:90%1.1.总体设计方案本文采用TL494芯片与 STM32芯片来分别控制前一部分直流升压电路和后一部分的逆变电路。
智林STM32程序源代码的分析和整理一、目的1、前些天,编写了开发板上键盘扫描、字符输入和简单shell的程序,该程序的编写是在以前工程的基础上修改而成的,源代码的组织比较乱,也没有很好的注释。
这两天,先把代码整理一下,加上比较详细的注释,使得可读性、扩展性更好。
2、乘这个机会,也把程序里与STM32硬件相关的部分好好学习一下。
二、开发板配置分析1、PA口PA0对应按键PB3,开发板右下角。
PA1用于模拟电位器,JP1在这里。
PA2用定时器的PWM产生液晶的背光电源。
PA4-PA7用于SPI模式操作SD卡。
PA9,PA10用于串口0通信。
PA11,PA12是USB差分线。
PA13、PA14、PA15是JTAG的三个脚。
PA3、PA8没用到。
2、PB口PB0用于扬声器,PB2与JP4用于Boot1选择。
PB3和PB4是JTAG的另外两个脚。
PB5控制绿色指示灯,在SD卡上面。
PB6、PB7用于I2C的存储器。
PB8、PB9用于CAN收发器。
PB11-PB15用于摇杆按键。
PB1和PB10没有用到3、PC口PC0到PC7用于液晶的数据口,PB8-PB12分别用于读、写、命令数据选择、复位和片选。
PB13是P B2按键,在PB3左边。
PB14-PB15外接32.768KHz晶振。
4、PD口PD0-PD1外接12MHz晶振,PD2用于USB的连接断开控制,低电平主机能检测到,高电平断开连接,JP3可直接控制连接。
另外还有BOOT 0脚,模式受控于JB5。
下面还有复位引脚。
这里5个脚加上上面48个,共53个引脚。
5、电源口共11个脚,还有电池引脚。
到这里,开发板的IO配置基本已经很清晰了。
三、初始化配置程序的编写程序中采用ucos操作系统,在调用OS_Init()之前,先调用BSP_Config()进行开发板IO配置工作。
下面是程序框架的源代码。
/* 下面是包含文件*/#include "stm32f10x_lib.h"#include "bsp_config.h"/* 可以在这里定义一些意义较为清晰地常量,如果不用改变,就放在文件user_conf.h里*//* 用户自己的全局变量在这里定义,按意义进行组合*/static GPIO_InitTypeDef GPIO_InitStructure; //进行GPIO端口设置的数据结构static NVIC_InitTypeDef NVIC_InitStructure;//进行中断设置的数据结构,前面的变量是用typedef在nvic的头文件中定义的。
/******************************************************************************** * @file TIM/6Steps/main.c* @author MCD Application Team* @version V3.5.0* @date 08-April-2011* @brief Main program body****************************************************************************** * @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONL Y AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>****************************************************************************** *//* Includes ------------------------------------------------------------------*/#include "stm32f10x.h"/** @addtogroup STM32F10x_StdPeriph_Examples* @{*//** @addtogroup TIM_6Steps* @{*//* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM_BDTRInitTypeDef TIM_BDTRInitStructure;uint16_t CCR1_Val = 32767;uint16_t CCR2_Val = 24575;uint16_t CCR3_Val = 16383;uint16_t CCR4_Val = 8191;/* Private function prototypes -----------------------------------------------*/void RCC_Configuration(void);void GPIO_Configuration(void);void SysTick_Configuration(void);void NVIC_Configuration(void);/* Private functions ---------------------------------------------------------*//*** @brief Main program* @param None* @retval None*/int main(void){/*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startupfile (startup_stm32f10x_xx.s) before to branch to application main.To reconfigure the default setting of SystemInit() function, refer tosystem_stm32f10x.c file*//* System Clocks Configuration */RCC_Configuration();/* NVIC Configuration */NVIC_Configuration();/* GPIO Configuration */GPIO_Configuration();/* SysTick Configuration */SysTick_Configuration();/*-----------------------------------------------------------------------------The STM32F10x TIM1 peripheral offers the possibility to program in advance the configuration for the next TIM1 outputs behaviour (step) and change the configuration of all the channels at the same time. This operation is possible when the COM (commutation) event is used.The COM event can be generated by software by setting the COM bit in the TIM1_EGR register or by hardware (on TRC rising edge).In this example, a software COM event is generated each 100 ms: using the Systick interrupt.The TIM1 is configured in Timing Mode, each time a COM event occurs,a new TIM1 configuration will be set in advance.The following Table describes the TIM1 Channels states:-----------------------------------------------| Step1 | Step2 | Step3 | Step4 | Step5 | Step6 |----------------------------------------------------------|Channel1 | 1 | 0 | 0 | 0 | 0 | 1 |----------------------------------------------------------|Channel1N | 0 | 0 | 1 | 1 | 0 | 0 |----------------------------------------------------------|Channel2 | 0 | 0 | 0 | 1 | 1 | 0 |----------------------------------------------------------|Channel2N | 1 | 1 | 0 | 0 | 0 | 0 |----------------------------------------------------------|Channel3 | 0 | 1 | 1 | 0 | 0 | 0 |----------------------------------------------------------|Channel3N | 0 | 0 | 0 | 0 | 1 | 1 |---------------------------------------------------------------------------------------------------------------------------------------*//* Time Base configuration */TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_Period = 4095;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);/* Channel 1, 2,3 and 4 Configuration in PWM mode */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;TIM_OCInitStructure.TIM_Pulse = 2047;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;TIM_OC1Init(TIM1, &TIM_OCInitStructure);TIM_OCInitStructure.TIM_Pulse = 1023;TIM_OC2Init(TIM1, &TIM_OCInitStructure);TIM_OCInitStructure.TIM_Pulse = 511;TIM_OC3Init(TIM1, &TIM_OCInitStructure);/* Automatic Output enable, Break, dead time and lock configuration*/TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;TIM_BDTRInitStructure.TIM_DeadTime = 1;TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);TIM_CCPreloadControl(TIM1, ENABLE);TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE);/* TIM1 counter enable */TIM_Cmd(TIM1, ENABLE);/* Main Output Enable */TIM_CtrlPWMOutputs(TIM1, ENABLE);while (1){}}/*** @brief Configures the different system clocks.* @param None* @retval None*/void RCC_Configuration(void){/* TIM1, GPIOA, GPIOB, GPIOE and AFIO clocks enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE); }/*** @brief Configure the TIM1 Pins.* @param None* @retval None*/void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* GPIOE Configuration: Channel 1/1N, 2/2N, 3/3N as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_8|GPIO_Pin_10|GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOE, &GPIO_InitStructure);/* GPIOE Configuration: BKIN pin */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOE, &GPIO_InitStructure);/* TIM1 Full remapping pins */GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);}/*** @brief Configures the SysTick.* @param None* @retval None*/void SysTick_Configuration(void){/* Setup SysTick Timer for 100 msec interrupts */if (SysTick_Config((SystemCoreClock) / 10)){/* Capture error */while (1);}NVIC_SetPriority(SysTick_IRQn, 0x0);}/*** @brief Configures the nested vectored interrupt controller.* @param None* @retval None*/void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;/* Enable the TIM1 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM1_TRG_COM_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t* file, uint32_t line){/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */while (1){}}#endif/*** @}*//*** @}*//******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ /******************************************************************************** * @file TIM/6Steps/stm32f10x_it.c* @author MCD Application Team* @version V3.5.0* @date 08-April-2011* @brief Main Interrupt Service Routines.* This file provides template for all exceptions handler and peripherals* interrupt service routine.****************************************************************************** * @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONL Y AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>****************************************************************************** *//* Includes ------------------------------------------------------------------*/#include "stm32f10x_it.h"/** @addtogroup STM32F10x_StdPeriph_Examples* @{*//** @addtogroup TIM_6Steps* @{*//* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/__IO uint32_t step = 1;/* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//****************************************************************************** //* Cortex-M3 Processor Exceptions Handlers *//****************************************************************************** //*** @brief This function handles NMI exception.* @param None* @retval None*/void NMI_Handler(void){}/*** @brief This function handles Hard Fault exception.* @param None* @retval None*/void HardFault_Handler(void){/* Go to infinite loop when Hard Fault exception occurs */ while (1){}}/*** @brief This function handles Memory Manage exception.* @param None* @retval None*/void MemManage_Handler(void){/* Go to infinite loop when Memory Manage exception occurs */ while (1){}}/*** @brief This function handles Bus Fault exception.* @param None* @retval None*/void BusFault_Handler(void){/* Go to infinite loop when Bus Fault exception occurs */while (1){}}/*** @brief This function handles Usage Fault exception.* @param None* @retval None*/void UsageFault_Handler(void){/* Go to infinite loop when Usage Fault exception occurs */ while (1){}}/*** @brief This function handles Debug Monitor exception.* @param None* @retval None*/void DebugMon_Handler(void){}/*** @brief This function handles SVCall exception.* @param None* @retval None*/void SVC_Handler(void){}/*** @brief This function handles PendSV_Handler exception.* @param None* @retval None*/void PendSV_Handler(void){}/*** @brief This function handles SysTick Handler.* @param None* @retval None*/void SysTick_Handler(void){/* Generate TIM1 COM event by software */TIM_GenerateEvent(TIM1, TIM_EventSource_COM);}/****************************************************************************** //* STM32F10x Peripherals Interrupt Handlers *//****************************************************************************** //*** @brief This function handles TIM1 Trigger and commutation interrupts* requests.* @param None* @retval None*/void TIM1_TRG_COM_IRQHandler(void){/* Clear TIM1 COM pending bit */TIM_ClearITPendingBit(TIM1, TIM_IT_COM);if (step == 1){/* Next step: Step 2 Configuration ---------------------------- *//* Channel3 configuration */TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);/* Channel1 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);/* Channel2 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1 );TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);step++;}else if (step == 2){/* Next step: Step 3 Configuration ---------------------------- *//* Channel2 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);/* Channel3 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);/* Channel1 configuration */TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);step++;}else if (step == 3){/* Next step: Step 4 Configuration ---------------------------- *//* Channel3 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1); TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);/* Channel2 configuration */TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);/* Channel1 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1); TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable); step++;}else if (step == 4){/* Next step: Step 5 Configuration ---------------------------- *//* Channel3 configuration */TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);/* Channel1 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1); TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);/* Channel2 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1); TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable); step++;}else if (step == 5){/* Next step: Step 6 Configuration ---------------------------- *//* Channel3 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1); TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);/* Channel1 configuration */TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);/* Channel2 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);step++;}else{/* Next step: Step 1 Configuration ---------------------------- *//* Channel1 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);/* Channel3 configuration */TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);/* Channel2 configuration */TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);step = 1;}}/****************************************************************************** //* STM32F10x Peripherals Interrupt Handlers *//* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the *//* available peripheral interrupt handler's name please refer to the startup *//* file (startup_stm32f10x_xx.s). *//****************************************************************************** //*** @brief This function handles PPP interrupt request.* @param None* @retval None*//*void PPP_IRQHandler(void){}*//*** @}*//*** @}*//******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/。
基于寄存器操作的STM32高级定时器TIM1的四路PWM输出程序讲解STM32高级定时器TIM1具有四个独立的PWM输出通道,可以用来控制四个不同的设备或驱动器。
在本篇文章中,我们将详细讲解如何使用寄存器操作实现TIM1的四路PWM输出。
首先,需要了解几个相关的概念。
STM32的定时器是通过寄存器进行配置和操作的,其中TIM1是高级定时器,具有更高级的功能和更多的寄存器。
PWM(脉冲宽度调制)是一种常见的控制技术,可实现模拟信号的数字化控制,通过调整高电平和低电平的时间比例来控制目标设备或驱动器的动作。
在开始编写程序之前,我们首先需要对TIM1进行初始化和配置。
以下是一个基本的初始化函数示例:```void TIM1_PWM_Init//开启TIM1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//初始化TIM1的配置TIM_TimeBaseInitTypeDef TIM_BaseStruct;TIM_OCInitTypeDef TIM_OCStruct;TIM_BaseStruct.TIM_Prescaler = 0;TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_BaseStruct.TIM_Period = 999; // 设置周期为1000TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_BaseStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_BaseStruct);//配置输出比较通道TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCStruct.TIM_Pulse = 0; // 设置脉冲宽度,0表示低电平TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC1Init(TIM1, &TIM_OCStruct);TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_OC2Init(TIM1, &TIM_OCStruct);TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_OC3Init(TIM1, &TIM_OCStruct);TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_OC4Init(TIM1, &TIM_OCStruct);TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);//启动定时器TIM_Cmd(TIM1, ENABLE);```上述代码是一个初始化TIM1的函数示例,其中包含了基本的配置步骤。
使用irmp库创建的基于stm32的红外遥控例程+源代码+文档说明全文共四篇示例,供读者参考第一篇示例:使用irmp库创建的基于stm32的红外遥控例程引言红外遥控技术在现代生活中得到了广泛应用,无论是电视遥控、空调遥控还是其它家用电器遥控,都离不开红外遥控技术。
而在嵌入式系统中,基于STM32开发的红外遥控系统也广泛应用于各种智能家居、智能家电中。
本文将介绍如何使用irmp库创建一个基于STM32的红外遥控例程,并提供源代码和文档说明。
一、什么是irmp库irmp库是一个用C语言编写的红外接收器解码库,可以用于解码不同品牌、型号的红外遥控器信号。
它支持多种不同的协议,包括NEC、SONY、RC-5等。
irmp库可以很方便地在STM32系列的单片机中使用,实现红外信号的接收和解码。
二、STM32开发环境搭建在使用irmp库创建红外遥控例程之前,首先需要搭建STM32开发环境。
可以选择Keil、IAR等集成开发环境进行开发。
在安装好开发环境后,需要配置好对应的STM32系列的芯片支持,包括芯片型号、引脚配置、时钟设置等。
然后创建一个新的工程,并导入irmp库的源代码。
三、irmp库的使用irmp库的使用主要分为两个部分:初始化红外接收器和处理接收到的红外码。
首先需要在初始化阶段对红外接收器进行配置,包括选择引脚、设置定时器等。
然后就可以启动红外接收器,开始接收红外信号。
在接收到红外信号后,irmp库会自动对信号进行解码,并将解码后的红外码存储在一个全局变量中。
在接收到红外码后,可以通过对不同的红外码进行判断,实现不同功能的控制。
四、红外遥控例程的实现下面以一个简单的LED控制为例,来演示如何使用irmp库创建一个基于STM32的红外遥控例程。
假设我们要用红外遥控器控制一个LED灯的开关。
1. 创建一个新的工程,并导入irmp库的源代码。
2. 配置红外接收器的引脚和定时器。
3. 在主函数中启动红外接收器,并进入一个无限循环。
基于STM32的SPWM源代码 1、TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。 1.1 PWM输出模式 STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下:110:PWM模式1-在向上计数时,一旦TIMx_CNTTIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。111:PWM模式2-在向上计数时,一旦TIMx_CNT时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。 1.2 PWM输出管脚 PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如说TIM3的第2个通道,在没有重映像的时候,指定的管脚是PA.7,如果设置部分重映像之后,TIM3_CH2的输出就被映射到PB.5上了,如果设置了完全重映像的话,TIM3_CH2的输出就被映射到PC.7上了。 1.3 PWM输出信号 PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR预分频器所决定的,具体设置方法在前面一个学习笔记中有详细的交代。而输出信号的占空比则是由TIMx_CRRx寄存器确定的。其公式为“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通过向CRR中填入适当的数来输出自己所需的频率和占空比的方波信号。
2、TIMER输出PWM源代码 #include "stm32f10x.h" /* Private typedef -----------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ u16 TimerPeriod = 7200; u16 DutyFactor = 50; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ void RCC_Configure(); void GPIO_Configure(); void TIM_Configure(); void PWM_Configure(); void NVIC_Configure(); /** * @brief Main program. * @param None * @retval None */
void RCC_Configure() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 | RCC_APB1Periph_TIM3,ENABLE); }
void GPIO_Configure() { /* GPIOA配置:通道PA.6和PA.7为 输出引脚*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); }
void TIM_Configure() { /* Time Base configuration 这里配置的就是PWM的周期,pwm还真是比AVR的强劲*/ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方式 TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_DeInit(TIM4); //这边是普通定时器的初始化和中断申请 TIM_TimeBaseStructure.TIM_Period=1; //自动重装载寄存器的值 TIM_TimeBaseStructure.TIM_Prescaler= 3599; //时钟预分频数 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_ClearFlag(TIM4, TIM_FLAG_Update); //清除溢出中断标志 TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); // 计数溢出时触发中断 } void PWM_Configure() { /* 通道1,2和3配置在PWM模式 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = DutyFactor * 7200 / 100;//设置占空比 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//这里的4行代码就是设置PWM的空闲电平、波形方式的!一开始自己一不小心搞成了都高的死区,这里是都低电平的死区~ TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化两组互补的PWM /* 自动输出使能,中断,死区相关的设置*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 12;//死区时间为 12/SYSTEMCLK (ns) TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//关闭外部break功能,当然在产品中最好加入这个保护,蛮好用的。 TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM3, &TIM_BDTRInitStructure); TIM_CtrlPWMOutputs(TIM3, ENABLE); /* 主输出启用 */ }