收藏0 举报
/* * Dasen - 2023/4/28 * pwm.c - 产生三组互补PWM波 */ #include "pwm.h" void Pwm_gpioInit(void) { //PA8(复用) - CH0 | PB13(复用) - CH0-N //PA9(复用) - CH1 | PB14(复用) - CH1-N //PA10(复用) - CH2 | PB15(复用) - CH2-N RCU_APB2EN |=(1<<2);//GPIOA时钟使能 RCU_APB2EN |=(1<<3);//GPIOB时钟使能 RCU_APB2EN |=(1<<0);//复用IO时钟使能 //PA8 GPIO_CTL1(GPIOA) &=~(0X0F<<0);//清除CTL配置 GPIO_CTL1(GPIOA) |=(3<<0);//输出模式,最大速度50MHz GPIO_CTL1(GPIOA) |=(2<<2);//AFIO推挽输出 //PA9 GPIO_CTL1(GPIOA) &=~(0X0F<<4);//清除CTL配置 GPIO_CTL1(GPIOA) |=(3<<4);//输出模式,最大速度50MHz GPIO_CTL1(GPIOA) |=(2<<6);//AFIO推挽输出 //PA10 GPIO_CTL1(GPIOA) &=~(0X0F<<8);//清除CTL配置 GPIO_CTL1(GPIOA) |=(3<<8);//输出模式,最大速度50MHz GPIO_CTL1(GPIOA) |=(2<<10);//AFIO推挽输出 //PB13 GPIO_CTL1(GPIOB) &=~(0X0F<<20);//清除CTL配置 GPIO_CTL1(GPIOB) |=(3<<20);//输出模式,最大速度50MHz GPIO_CTL1(GPIOB) |=(2<<22);//AFIO推挽输出 //PB14 GPIO_CTL1(GPIOB) &=~(0X0F<<24);//清除CTL配置 GPIO_CTL1(GPIOB) |=(3<<24);//输出模式,最大速度50MHz GPIO_CTL1(GPIOB) |=(2<<26);//AFIO推挽输出 //PB15 GPIO_CTL1(GPIOB) &=~(0X0F<<28);//清除CTL配置 GPIO_CTL1(GPIOB) |=(3<<28);//输出模式,最大速度50MHz GPIO_CTL1(GPIOB) |=(2<<30);//AFIO推挽输出 AFIO_PCF0 &=~(3<<6); AFIO_PCF0 |=(0<<6);//没有重映射 } void Timer0_InitPwm(uint16_t prescale, uint16_t period) { RCU_APB2EN |=(1<<11);//TIMER0时钟使能 Pwm_gpioInit();//gpio config TIMER_CTL0(TIMER0) = 0;//清除控制寄存器0配置 TIMER_CTL0(TIMER0) |=(0<<8);//通过软件配置CKDIV,规定定时器时钟(CK_TIMER) 与死区时间和数字滤波器采样时钟(DTS)之间的分频系数。: //00:fDTS=fCK_TIMER; //01:fDTS= fCK_TIMER /2; //10:fDTS= fCK_TIMER /4; //11:保留 TIMER_CTL0(TIMER0) |=(1<<7);//1:使能TIMERx_CAR寄存器的影子寄存器(自动重载影子使能) TIMER_CTL0(TIMER0) |=(0<<5);//计数器对齐模式选择:00:无中央对齐计数模式(边沿对齐模式)。 DIR位指定了计数方向。其他值为中央对齐模式 TIMER_CTL0(TIMER0) |=(0<<4);//0:向上计数;1:向下计数 TIMER_CTL0(TIMER0) |=(1<<2);//选择更新事件源。1:下列事件会产生更新中断或DMA请求:计数器溢出/下溢 TIMER_CTL0(TIMER0) |=(0<<1);//该位用来使能或禁能更新事件的产生。0:更新事件使能.1:更新事件禁能. TIMER_CTL1(TIMER0)=0;//清除控制寄存器1配置 TIMER_CTL1(TIMER0) |=(1<<3);//DMA请求源选择:0:当通道捕获/比较事件发生时,发送通道x的DMA请求 .1:当更新事件发生,发送通道x的DMA请求 TIMER_CTL1(TIMER0) |=(0<<2);//换相控制影子寄存器更新控制:当换相控制影子寄存器(CHxEN, CHxNEN和CHxCOMCTL位)使能(CCSE=1),这些影子寄存器更新控制如下:(当通道没有互补输出时,此位无效。) //0:CMTG位被置1时更新影子寄存器 //1:当CMTG位被置1或检测到TRIGI上升沿时,影子寄存器更新 TIMER_CTL1(TIMER0) |=(1<<0);//换相控制影子使能:0:影子寄存器CHxEN, CHxNEN和CHxCOMCTL位禁能. //1:影子寄存器CHxEN, CHxNEN和CHxCOMCTL位使能. //如果这些位已经被写入了,换相事件到来时这些位才被更新 //当通道没有互补输出时,此位无效 TIMER_SMCFG(TIMER0) =0;//清除从模式配置寄存器配置 TIMER_DMAINTEN(TIMER0) =0;//清除DMA和中断使能寄存器 TIMER_DMAINTEN(TIMER0) |=(0<<0);//0:禁止更新中断;1:使能更新中断 TIMER_INTF(TIMER0) =0;//中断标志位清零 【TIMER_INTF(TIMER0)&(1<<0) 为UPIF更新中断标志位:1:发生更新中断;0:无更新中断发生。】 TIMER_SWEVG(TIMER0) =0;//软件事件产生寄存器清零 /******************************PWM通道配置 START*********************************/ //先把CHCTL2的CHxEN清零,才配置CHCTL0 TIMER_CHCTL2(TIMER0) =0;//通道控制寄存器2清零 TIMER_CHCTL0(TIMER0) =0;//通道控制寄存器0清零 TIMER_CHCTL1(TIMER0) =0;//通道控制寄存器1清零 //CH0 TIMER_CHCTL0(TIMER0) |=(0<<0);//通道0 I/O模式选择:00:通道0配置为输出 TIMER_CHCTL0(TIMER0) |=(1<<3);//1:使能通道0输出/比较影子寄存器 TIMER_CHCTL0(TIMER0) |=(6<<4);//110:PWM 模式0。在向上计数时,一旦计数器值小于TIMERx_CH0CV时,O0CPRE为高电平,否则为低电平。在向下计数时,一旦计数器的值大于TIMERx_CH0CV时,O0CPRE 为低电平,否则为高电平。 //CH1 TIMER_CHCTL0(TIMER0) |=(0<<8); TIMER_CHCTL0(TIMER0) |=(1<<11); TIMER_CHCTL0(TIMER0) |=(6<<12); //CH2 TIMER_CHCTL1(TIMER0) |=(0<<0); TIMER_CHCTL1(TIMER0) |=(1<<3); TIMER_CHCTL1(TIMER0) |=(6<<4); //CH0 EN TIMER_CHCTL2(TIMER0) |=(1<<0);//1:使能通道x TIMER_CHCTL2(TIMER0) |=(0<<1);//通道x极性:0:通道x高电平为有效电平;1:通道x低电平为有效电平 //CH0-N EN TIMER_CHCTL2(TIMER0) |=(1<<2);//1:使能通道x互补输出 TIMER_CHCTL2(TIMER0) |=(0<<3);//通道x互补输出极性:0:通道x互补输出高电平为有效电平;1:通道x互补输出低电平为有效电平 //CH1 EN TIMER_CHCTL2(TIMER0) |=(1<<4);//1:使能通道x TIMER_CHCTL2(TIMER0) |=(0<<5);//通道x极性:0:通道x高电平为有效电平;1:通道x低电平为有效电平 //CH1-N EN TIMER_CHCTL2(TIMER0) |=(1<<6);//1:使能通道x互补输出 TIMER_CHCTL2(TIMER0) |=(0<<7);//通道x互补输出极性:0:通道x互补输出高电平为有效电平;1:通道x互补输出低电平为有效电平 //CH2 EN TIMER_CHCTL2(TIMER0) |=(1<<8);//1:使能通道x TIMER_CHCTL2(TIMER0) |=(0<<9);//通道x极性:0:通道x高电平为有效电平;1:通道x低电平为有效电平 //CH2-N EN TIMER_CHCTL2(TIMER0) |=(1<<10);//1:使能通道x互补输出 TIMER_CHCTL2(TIMER0) |=(0<<11);//通道x互补输出极性:0:通道x互补输出高电平为有效电平;1:通道x互补输出低电平为有效电平 TIMER_SWEVG(TIMER0) |=(1<<5);//通道换相更新事件发生:1:产生通道控制更新事件。此位由软件置1,由硬件自动清0. 当此位被置1,通道捕获/比较控制寄存器 (CHxEN, CHxNEN 和CHxCOMCTL) 的互补输出被更新。 /******************************PWM通道配置 END*********************************/ //时基配置 TIMER_CNT(TIMER0)=0;//计数器寄存器清零 TIMER_PSC(TIMER0) =prescale;//TIM_CLK=120MHz/(prescale+1)。计数器时钟等于TIMER_CK时钟除以(PSC+1),每次当更新事件产生时,PSC 的值被装入到对应的影子寄存器。 TIMER_CAR(TIMER0) =period;//计数器自动重载值 TIMER_CREP(TIMER0) = 5;//重复计数器的值;这些位定义了更新事件的产生速率。重复计数器计数值减为0时产生更新事件。影子寄存器的更新速率也会受这些位影响(前提是影子寄存器被使能)。 //比较寄存器配置 TIMER_CH0CV(TIMER0) = period>>1;//当通道0配置为输出模式时,这些位包含了即将和计数器比较的值。使能相应影子寄存器后,影子寄存器值随每次更新事件更新。 TIMER_CH1CV(TIMER0) = period>>1; TIMER_CH2CV(TIMER0) = period>>1; TIMER_CCHP(TIMER0) &=~(3<<8);//00:禁能保护模式。无写保护. TIMER_CCHP(TIMER0) =0;//互补通道保护寄存器清零 TIMER_CCHP(TIMER0) |=(1<<15);//所有的通道输出使能 TIMER_CCHP(TIMER0) |=(0<<14);//自动输出使能:0:POEN位只能使用软件方式置1;1:如果中止输入无效,下一次更新事件发生时,POEN位将会置1 //此位只有在TIMERx_CCHP寄存器的PROT [1:0] =00时才可修改。 TIMER_CCHP(TIMER0) |=(1<<11);//0:当POEN位被置1,通道输出信号 (CHx_O/ CHx_ON)被禁止;1:当POEN位被置1,通道输出信号 (CHx_O / CHx_ON)被使能,和TIMER0_CHCTL2寄存器CHxEN/CHxNEN位有关 //此位在TIMERx_CCHP寄存器的PROT [1:0]=10或11时不能被更改。 TIMER_CCHP(TIMER0) |=(0<<10);//0:当POEN位被清0,通道输出信号 (CHx_O/ CHx_ON)被禁止;1:当POEN位被清0,通道输出信号 (CHx_O / CHx_ON)被使能,和TIMER0_CHCTL2寄存器CHxEN/CHxNEN位有关 //此位在TIMERx_CCHP寄存器的PROT [1:0]=10或11时不能被更改。 //死区时间 TIMER_CCHP(TIMER0) |=(96<<0);//DELAY >= 8.33ns*96=799.68ns TIMER_CFG(TIMER0)=0; TIMER_CFG(TIMER0)|=1;//1:如果POEN位与IOS位均为0,则输出无效 TIMER_SWEVG(TIMER0) |=(1<<0);//更新事件产生:1:产生更新事件。此位由软件置1,被硬件自动清0。当此位被置1,如果选择了中央对齐或向上计数模式,计数器被清0。否则(向下计数模式)计数器将载入自动重载值,预分频计数器将同时被清除。 TIMER_CTL0(TIMER0) |=(1<<0);//计数器使能:0:计数器禁能;1:计数器使能 }
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
人才类勋章
62
426
3
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号