STM32Min开发板四路触屏可调PWM互补输出
在正点原子的开发例程上,结合PWM输出实验和触摸屏实验代码进行修改。
定义了几个全局变量存储定时器ARR值和占空比:
u32 F1=50; //频率 50KHz
u32 r1=50,r2=50; //占空比50%
u16 arr1=1439,comp1=719,comp2=719; //arr和ccr
首先进行初始化,LCD和触摸屏初始化与例程相同。
TIM1_PWM_Init(arr1,0);//不分频。PWM频率50Khz
LCD_Init(); //初始化LCD
tp_dev.init(); //触摸屏初始化
定时器1初始化了四个通道,GPIO分别是PA8、9、10、11。
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH1-4的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_8|GPIO_Pin_9; //TIM_CH1-4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1预装载使能
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH2预装载使能
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH3预装载使能
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH4预装载使能
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
需要注意的是其中在开发板上PA9和PA10接到了串口,PA8接到了LED0。
然后是显示界面的设计:
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(30,30,200,16,16,"PWM1,PWM2 PWM3,PWM4");
LCD_ShowString(30,50,200,16,16,"F1: KHz ");
LCD_ShowString(30,70,200,16,16,"r1: % r2: %");
LCD_ShowString(20,120,200,16,16," F1+ F1-");
LCD_ShowString(20,170,200,16,16,"r1+ r1- r2+ r2-");
LCD_ShowString(30,250,200,16,16," PWM1:PA8 PWM2:PA9");
LCD_ShowString(30,270,200,16,16," PWM3:PA10 PWM4:PA11");
LCD_DrawLine(10,108,230,108);
LCD_DrawLine(10,148,230,148);
LCD_DrawLine(10,198,230,198);
LCD_DrawLine(10,108,10,198);
LCD_DrawLine(62,148,62,198);
LCD_DrawLine(118,108,118,198);
LCD_DrawLine(178,148,178,198);
LCD_DrawLine(230,108,230,198);
LCD_ShowNum(54,50,F1,2,16);
LCD_ShowNum(54,70,r1,2,16);
LCD_ShowNum(158,70,r2,2,16);
LCD_ShowString(100,220,200,16,16,"key:");
显示效果如下,比较简略:
主函数里边用while循环一直扫描触屏是否被按下,按下后在判断按下的区域,在执行对应的操作,改变定时器1的ARR或者CCR寄存器,从而改变PWM输出的频率和占空比。
while(1)
{
tp_dev.scan(0);
if(tp_dev.sta&TP_PRES_DOWN) //触摸屏被按下
{
if((tp_dev.x[0]>10&&tp_dev.x[0]<230) &&(tp_dev.y[0]>108&&tp_dev.y[0]<198))
{
if((tp_dev.x[0]>10&&tp_dev.x[0]<118) &&(tp_dev.y[0]>108&&tp_dev.y[0]<148)) //1
{
F1 += 5;
key = 1;
}
else if((tp_dev.x[0]>118&&tp_dev.x[0]<230) &&(tp_dev.y[0]>108&&tp_dev.y[0]<148)) //2
{
F1 -= 5;
key = 2;
}
else if((tp_dev.x[0]>10&&tp_dev.x[0]<62) &&(tp_dev.y[0]>148&&tp_dev.y[0]<198)) //5
{
r1 += 5;
key = 3;
}
else if((tp_dev.x[0]>62&&tp_dev.x[0]<118) &&(tp_dev.y[0]>148&&tp_dev.y[0]<198)) //6
{
r1 -= 5;
key = 4;
}
else if((tp_dev.x[0]>118&&tp_dev.x[0]<178) &&(tp_dev.y[0]>148&&tp_dev.y[0]<198)) //7
{
r2 += 5;
key = 5;
}
else if((tp_dev.x[0]>178&&tp_dev.x[0]<230) &&(tp_dev.y[0]>148&&tp_dev.y[0]<198)) //8
{
r2 -= 5;
key = 6;
}
if(F1<20)
F1 = 20;
else if(F1>80)
F1 = 80;
if(r1>100)
r1 = 100;
if(r2>100)
r2 = 100;
arr1 = 72000000/(F1*1000);
comp1 = arr1*r1/100;
comp2 = arr1*r2/100;
TIM1->ARR = arr1;
TIM1->CCR1 = comp1;
TIM1->CCR2 = comp1;
TIM1->CCR3 = comp2;
TIM1->CCR4 = comp2;
LCD_ShowNum(54,50,F1,2,16);
LCD_ShowNum(54,70,r1,3,16);
LCD_ShowNum(158,70,r2,3,16);
LCD_ShowNum(135,220,key,1,16);
while(tp_dev.sta&TP_PRES_DOWN) //等待松开
{
tp_dev.scan(0);
}
}
}else delay_ms(10); //没有按键按下的时候
}
完整工程:
STM32Min开发板四路触屏可调PWM互补输出