参考了之前实验课上老师讲的编码器的程序,但我还是理解的不太清楚,也不确定我的连线是否正确,可以给我再讲讲吗。我理解是利用定时器0去对脉冲进行计数,确定电机转动的圈数,T1用来每1s检测一次,然后利用液晶显示速度。但把这部分加进我的程序中,好像没有效果。
- //#include <reg52.h>
- #include <STC15.H>
- #include <intrins.h>
- #include <stdio.h>
- #include "DataForm_STC15.H"
- #include "LCD1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define K 21/8
- sbit KEY1=P1^0;// 电机启动
- sbit KEY2=P1^1;// 电机停止
- sbit KEY3=P1^2;// 电机加速
- sbit KEY4=P1^3; //减速
- bit KEY_flag=0; //按键标志位
- bit Timer1S_flag=0; // 定时器到1S标志位
- uint16 Timer1S_num=0; // 定时器溢出中断计数,一千次为1S
- uint count = 0; //计时变量
- uint PWM = 0; //占空比控制变量
- uint EX0_counter=0,rad;//EX0_counter为脉冲数
- uchar8 LCD_BUFFER[16]={0}; // 液晶显示缓冲区
- sbit MOTOR_A1=P1^4; //l293D芯片引脚定义
- sbit MOTOR_A2=P1^5;
- sbit MOTOR_B1=P1^6;
- sbit MOTOR_B2=P1^7;
- sbit ENA=P3^0;
- sbit ENB=P3^1;
- void delay1ms() //@11.0592MHz延时函数
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- void delayms(uint t) //1ms延时函数
- {
- uint x,y;
- for(x=t;x>0;x--)
- for(y=120;y>0;y--);
- }
- void Motor_Forward()//电机正转
- {
- MOTOR_A1=1;
- MOTOR_A2=0;
- ENA=1;
- MOTOR_B1=1;
- MOTOR_B2=0;
- ENB=1;
- }
-
- void Motor_Stop()//电机停止
- {
- MOTOR_A1=0;
- MOTOR_A2=0;
- ENA=1;
- MOTOR_B1=0;
- MOTOR_B2=0;
- ENB=1;
- }
- void Start()
- {
- LCD_Init();
- LCD_Display_String(4,0,"Treadmill");
- }
- void Speed_Up()
- {
- LCD_Init();
- LCD_Display_String(4,0,"speed up");
- }
- void Speed_Down()
- {
- LCD_Init();
- LCD_Display_String(4,0,"speed down");
- }
- void KEY_Scan() // 按键驱动函数
- {
- if(KEY1==0) // 判断是否按下 下同
- {
- delay1ms(); //消抖
- if(KEY1==0)
- {
- KEY_flag=~KEY_flag; //加速减速标志位取反
- Motor_Forward();
- PWM=30; //初始PWM=30,电机速度大约为22
-
- }
- while(KEY1==0); //检测按键是否松开
- }
- if(KEY2==0) // 判断是否按下 下同
- {
- delay1ms(); //消抖
- if(KEY2==0)
- {
- KEY_flag=0; //加速减速标志位清零
- Motor_Stop();
- PWM=0; //PWM清零
-
- }
- while(KEY2==0); //检测按键是否松开
- }
- if(KEY3==0) // 判断是否按下 下同
- {
- delay1ms(); //消抖
- if(KEY3==0)
- {
- if(KEY_flag==1) //判断标志位只有在电机启动的时候才能加速
- {
- if(PWM<250)
- {
- Speed_Up();
- PWM=PWM+30; //每次PWM+10 直到250
- }
- delayms(10); //给一个延时,让电机反应快一些可减少此延时时间
- }
- }
- while(KEY3==0); //检测按键是否松开
- }
- if(KEY4==0) // 判断是否按下 下同
- {
- delay1ms(); //消抖
- if(KEY4==0)
- {
- if(KEY_flag==1) //判断标志位只有在电机启动的时候才能减速
- {
- if(PWM>0)
- {
- Speed_Down();
- PWM=PWM-30;
- }
- delayms(10);
- }
- }
- while(KEY4==0); //检测按键是否松开
- }
- }
- void Timer0()
- {
- TMOD = 0x02; //定时器0,工作模式2,8位定时模式
- TH0=210; //写入预置初值(取值1-255,数越大PWM频率越高)
- TL0=210; //写入预置值 (取值1-255,数越大PWM频率越高)
- TR0=1; //启动定时器
- ET0=1; //允许定时器0中断
- EA=1; //允许总中断
- }
- //定时器0中断模拟PWM
- void serviceTimer0() interrupt 1
- {
- count++; //每次定时器溢出加1
- if(count==250) //PWM周期 100个单位
- {
- count=0; //使t=0,开始新的PWM周期
- Motor_Forward();
- }
-
- if(PWM==count) //按照当前占空比切换输出为低电平
- {
- Motor_Stop();
- }
- }
- void Init_EINT0( ) // T0外部中断初始化
- {
- IT0=1; // 外部信号下降沿触发
- EX0=1; // 开T0外部中断
- EA=1; // 开总中断
- }
- void EINT0( ) interrupt 0 // T0外部中断子程序
- {
- EX0_counter++; // 每中断一次计数加1
- }
- void Init_Timer1( ) // 定时器T1初始化
- {
- AUXR |= 0x40; // 定时器时钟为1T模式
- TMOD &= 0x0F; // 设置定时器模式,16位自动重装
- TL1 = 0xCD; // 定时常数
- TH1 = 0xD4; // 定时常数
- TF1 = 0; // 清溢出标志位
- ET1=1; // 开T1溢出中断
- EA=1; // 开总中断
- }
- void Enable_Timer1( ) //开定时器
- {
- TR1=1;
- }
- void Disable_Timer1( ) //关定时器
- {
- TR1=0;
- }
- void Timer1( ) interrupt 3 // T1中断子程序
- {
- Timer1S_num++; // 定时器溢出中断计数,每中断一次计数加1
- TF1 = 0; // 清溢出标志位
- if(Timer1S_num>=1000) // 中断计数一千次为1S,到1S计数清零,1S标志位置1,即每1S检测一次
- {
- Timer1S_num=0;
- Timer1S_flag=1;
- }
- }
- void Speed_Display() //计算速度
- {
- rad=EX0_counter*K;
- sprintf(LCD_BUFFER,"v=%.2f",rad);
- LCD_Display_String(2,1,LCD_BUFFER);
- }
- void main()
- {
- Start();//初始化显示跑步机
- Timer0();//定时器0初始化
- Init_Timer1( );//定时器1初始化
- Enable_Timer1( );
- Init_EINT0( ); //电机编码器中断初始化
- EX0_counter=0; //电机旋转圈数初始化
- Timer1S_num=0; //计时次数初始化
- Motor_Forward();//启动电机
- // PWM=30; //PWM初始值
-
- while(1)
- {
- KEY_Scan();
- if(Timer1S_flag==1) // 如果时间到1S
- {
- Speed_Display(); // 液晶显示
- EX0_counter=0; // 外部中断计数清零
- Timer1S_flag=0; // 1S计数清零
- }
-
- }
- }
复制代码
|