#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "PWM.h"
#include "mokuaicount.h"
/***************************************************/PWM模块
#include "stm32f10x.h" // Device header
#include "PWM.h"
#include "Delay.h"
void pwm_init(void)
{
//**1.打开总的RCC,要配置GPIO从而传入外部时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因为定时器2是通用定时器,在APB1总线上
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//**2.配置PWM输出引脚PA0
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//**3.配置时基单元
//配置为1000KHz,分辨率为1%
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//设置分频
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//设置向上计数
TIM_TimeBaseInitStruct.TIM_Period=20000-1;//设置预装载值 //外部时钟的话用不了这么高的频率
TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;//设置预分频值
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高级计数器功能,重复计数器
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化时基单元
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化时会产生标志位,需要清除
//**4.配置CCR
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC1Init(TIM2,&TIM_OCInitStruct);
//5.
//**6.开始计数
TIM_Cmd(TIM2,ENABLE);
}
void set_angle(uint16_t angle)
{
TIM_SetCompare1(TIM2,angle);
}
/***************************************************/GPIO初始化
#include "xuanniu.h"
#include "stm32f10x.h"
void Xuanniu_init(uint16_t GPIO_Pin)//需要指定端口Pin进行模式设置
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);//使能GPIOA的时钟
GPIO_InitTypeDef Xuanniu_InitStruct;
Xuanniu_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//设置为 上拉输入 模式
Xuanniu_InitStruct.GPIO_Pin=GPIO_Pin; //外界参数设置Pin口
Xuanniu_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //输出速度为50MHz,在输入模式下该设置没用
GPIO_Init( GPIOB,&Xuanniu_InitStruct); //以上三个都要传入该函数初始化
}
/***************************************************/计数模块
//**该模块由中断函数实现,可接入任意输入模式的模块实现计数
//**这里引入Key实现数据的减法,LightR实现加法
#include "stm32f10x.h" // Device header
#include "mokuaicount.h"
#include "Delay.h"
#include "xuanniu.h"
extern int num;
void Count_interrupt_init(void)
{
//1、2、**步骤一二在模块内已经实现
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//AFIO时钟需要使能
Xuanniu_init(GPIO_Pin_0|GPIO_Pin_1);
//3**配置AFIO,选择输入引脚PB1(C),PB0(A)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//Xuanniu旋钮
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
//4**配置EXTI寄存器,选择触发方式,这里配置EXTI和GPIO一样需要定义一个结构体
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line0|EXTI_Line1;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
//5**配置NVIC,选择合适的中断优先级 --------每一个外设要单独配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//要先分组,整个系统NVIC只分配一种模式
//**配置Xuanniu A端
NVIC_InitTypeDef NVIC_InitStruct_Xuanniu;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct_Xuanniu);
//**配置Xuanniu C端
NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI1_IRQn;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct_Xuanniu);
//****所有配置完成
}
//中断位置随便放,也不需要声明
void EXTI0_IRQHandler()//正转触发
{
if(EXTI_GetITStatus(EXTI_Line0)==SET)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==1)
{
num+=100;
}
}
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler()
{
if(EXTI_GetITStatus(EXTI_Line1)==SET)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==1)
{
num-=100;
}
}
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
/***************************************************/主函数
int num=1500;
int main(void)
{
OLED_Init();
pwm_init();
Count_interrupt_init();
OLED_ShowString(1,1,"Hello,my baby");
set_angle(num);//默认居中
while(1)
{
if(num<=0)
{
num=0;
OLED_ShowString(2,8,"Left Max ");
}
else if(num<1500)
{
OLED_ShowString(2,8,"Left ");
}
else if(num==1500)
{
OLED_ShowString(2,8,"Midel ");
}
else if(num<2500)
{
OLED_ShowString(2,8,"Right ");
}
else if(num>=2500)
{
num=2500;
OLED_ShowString(2,8,"Right Max");
}
OLED_ShowNum(2,1,num,5);
set_angle(num);
}
}
|