STM32F103C8 旋转编码器 控制PWM 软件代码
[复制链接]
//encoder.h 如下
#ifndef __ENCODER_H
#define __ENCODER_H
#include "sys.h"
#include "delay.h"
#define ENCODER_PORT_A GPIOA //定义IO接口组
#define ENCODER_L GPIO_Pin_6 //定义IO接口
#define ENCODER_D GPIO_Pin_7 //定义IO接口
#define ENCODER_PORT_B GPIOB //定义IO接口组
#define ENCODER_R GPIO_Pin_2 //定义IO接口
void ENCODER_Init(void);//初始化
u8 ENCODER_READ(void);
void ENCODER_CTL(void);
void ENCODER_pwmctl_w(void);
void ENCODER_pwmctl_f(void);
void ENCODER_TIM4_pwmctl_w(void);
#endif
// 1 GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); LED1接口输出高电平1
// GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1)));取反LED1
// 2 GPIO_SetBits(LEDPORT,LED1);
// 3 GPIO_ResetBits(LEDPORT,LED1);
// 4 GPIO_Write(LEDPORT,0x0001); 直接数值操作将变量值写入LED
//选择IO接口工作方式:
//GPIO_Mode_AIN 模拟输入
//GPIO_Mode_IN_FLOATING 浮空输入
//GPIO_Mode_IPD 下拉输入
//GPIO_Mode_IPU 上拉输入
//GPIO_Mode_Out_PP 推挽输出
//GPIO_Mode_Out_OD 开漏输出
//GPIO_Mode_AF_PP 复用推挽输出
//GPIO_Mode_AF_OD 复用开漏输出
//encoder.c 如下
#include "encoder.h"
#include "touch_key.h"
#include "delay.h"
#include "usart.h"
#include "oled0561.h"
#include "flash.h"
#include "pwm.h"
#define FLASH_START_ADDR 0x0801f000 //写入的起始地址#define FLASH_START_ADDR 0x0801f000 //写入的起始地址
#define FLASH_data2_ADDR 0x0801f010
#define FLASH_data3_ADDR 0x0801f100
u8 KUP;//旋钮锁死标志(1为锁死)
u16 cou;
void ENCODER_Init(void)
{ //接口初始化
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO的初始化枚举结构
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin = ENCODER_L | ENCODER_D; //选择端口号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻
GPIO_Init(ENCODER_PORT_A,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ENCODER_R; //选择端口号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻
GPIO_Init(ENCODER_PORT_B,&GPIO_InitStructure);
}
u8 ENCODER_READ(void){ //接口初始化
u8 a;//存放按键的值
u8 kt;
a=0;
if(GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L))KUP=0; //判断旋钮是否解除锁死
if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)&&KUP==0){ //判断是否旋转旋钮,同时判断是否有旋钮锁死
delay_us(100);
kt=GPIO_ReadInputDataBit(ENCODER_PORT_B,ENCODER_R); //把旋钮另一端电平状态记录
delay_ms(3); //延时
if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)){ //去抖
if(kt==0){ //用另一端判断左或右旋转
a=1;//右转
}else{
a=2;//左转
}
cou=0; //初始锁死判断计数器
while(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)&&cou<60000){ //等待放开旋钮,同时累加判断锁死
cou++;KUP=1;delay_us(20); //
}
}
}
if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D)&&KUP==0)
{ //判断旋钮是否按下
delay_ms(20);
if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D))
{ //去抖动
a=3;//在按键按下时加上按键的状态值
while(GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D)==0)
; //等等旋钮放开
delay_ms(10);
}
}
return a;
}
void ENCODER_CTL(void)
{
u8 b=0;
u16 c=150;
u16 k;
k = FLASH_R(FLASH_START_ADDR);//从指定页的地址读FLASH
b=ENCODER_READ(); //读出旋转编码器值
if(b==1)//分析按键值,并加减计数器值。
{
k++;
if(k>=c)k=0;
printf("右转 %d \r\n",k);
}
if(b==2)
{
k--;
if(k==0)
k=c;
printf("左转 %d \r\n",k);
}
if(b==3)k=75, printf("OK %d \r\n",k);
if(b!=0)//如果有旋转器的操作
{
OLED_DISPLAY_8x16(6,13*8,k/100+0x30);
OLED_DISPLAY_8x16(6,14*8,k%100/10+0x30);
OLED_DISPLAY_8x16(6,15*8,k%100%10+0x30);
FLASH_W(FLASH_START_ADDR,k);
}
}
void ENCODER_pwmctl_w(void)
{
u8 b=0;
u16 c=140;
u16 t1pwm_w;
t1pwm_w = FLASH_R(FLASH_data2_ADDR);//从指定页的地址读FLASH
b=ENCODER_READ(); //读出旋转编码器值
if(b==1)//分析按键值,并加减计数器值。
{
t1pwm_w++;
if(t1pwm_w>=c)t1pwm_w=10;
printf("右转 %d \r\n",t1pwm_w);
}
if(b==2)
{
t1pwm_w--;
if(t1pwm_w<=10)
t1pwm_w=c;
printf("左转 %d \r\n",t1pwm_w);
}
if(b==3)t1pwm_w=72,
printf("OK %d \r\n",t1pwm_w);
if(b!=0)//如果有旋转器的操作
{
OLED_DISPLAY_8x16(6,13*8,t1pwm_w/100+0x30);
OLED_DISPLAY_8x16(6,14*8,t1pwm_w%100/10+0x30);
OLED_DISPLAY_8x16(6,15*8,t1pwm_w%100%10+0x30);
FLASH_W(FLASH_data2_ADDR,t1pwm_w);
TIM1_2PWM_Init( 144,0);
TIM_SetCompare1(TIM1,t1pwm_w);
TIM_SetCompare3(TIM1,t1pwm_w);
}
}
void ENCODER_TIM4_pwmctl_w(void)
{
u8 b=0;
u16 c=720;
u16 t4pwm_w;
t4pwm_w = FLASH_R(FLASH_data2_ADDR);//从指定页的地址读FLASH
b=ENCODER_READ(); //读出旋转编码器值
if(b==1)//分析按键值,并加减计数器值。
{
t4pwm_w++;
if(t4pwm_w>=c)t4pwm_w=10;
printf("右转 %d \r\n",t4pwm_w);
}
if(b==2)
{
t4pwm_w--;
if(t4pwm_w<=10)
t4pwm_w=c;
printf("左转 %d \r\n",t4pwm_w);
}
if(b==3)t4pwm_w=360,
printf("OK %d \r\n",t4pwm_w);
if(b!=0)//如果有旋转器的操作
{
OLED_DISPLAY_8x16(6,13*8,t4pwm_w/100+0x30);
OLED_DISPLAY_8x16(6,14*8,t4pwm_w%100/10+0x30);
OLED_DISPLAY_8x16(6,15*8,t4pwm_w%100%10+0x30);
FLASH_W(FLASH_data2_ADDR,t4pwm_w);
TIM4_PWM_Init( 720,0);
TIM_SetCompare3(TIM4,t4pwm_w);
}
}
void ENCODER_pwmctl_f(void)
{
u8 b=0;
u16 c=654;
u16 t1pwm_f;
t1pwm_f = FLASH_R(FLASH_data2_ADDR);//从指定页的地址读FLASH
b=ENCODER_READ(); //读出旋转编码器值
if(b==1)//分析按键值,并加减计数器值。
{
t1pwm_f++;
if(t1pwm_f>=c)t1pwm_f=343;
// TIM_SetCompare3(TIM3,k);
// TIM3_PWM_Init(pwm_f,0);
printf("右转 %d \r\n",t1pwm_f);
// OLED_DISPLAY_8x16(6,13*8,k/100+0x30);
// OLED_DISPLAY_8x16(6,14*8,k%100/10+0x30);
// OLED_DISPLAY_8x16(6,15*8,k%100%10+0x30);
}
if(b==2)
{
t1pwm_f--;
if(t1pwm_f==343)
t1pwm_f=c;
// TIM_SetCompare3(TIM3,k);
// TIM3_PWM_Init(pwm_f,0);
printf("左转 %d \r\n",t1pwm_f);
// OLED_DISPLAY_8x16(6,13*8,k/100+0x30);
// OLED_DISPLAY_8x16(6,14*8,k%100/10+0x30);
// OLED_DISPLAY_8x16(6,15*8,k%100%10+0x30);
}
if(b==3)t1pwm_f=600,
printf("OK %d \r\n",t1pwm_f);
if(b!=0)//如果有旋转器的操作
{
OLED_DISPLAY_8x16(6,13*8,t1pwm_f/100+0x30);
OLED_DISPLAY_8x16(6,14*8,t1pwm_f%100/10+0x30);
OLED_DISPLAY_8x16(6,15*8,t1pwm_f%100%10+0x30);
FLASH_W(FLASH_data2_ADDR,t1pwm_f);
TIM1_2PWM_Init( t1pwm_f,0);
TIM_SetCompare1(TIM1,t1pwm_f/2);
}
}
希望对你有帮助。。。。
|