主程序,整定的stc8a的程序。初步。

测试脉冲数,并且发送到电脑串口,利用stc8a芯片的串口3,定时器3产生波特率,利用PWM增强,PWM的P21接口产生PWM脉冲,有四个按键,+,-,模式选择,确定键。模式选择。
模式1是设定PWM的占空比,其中PWM的周期设定固定,500HZ频率,通过设置T1H的反转点,实现PWM,将反转点的值设置为变量,按键可控制该变量的增加或者变小,用示波器进行过验证,可行。
模式2是调节PID的P值参数,暂时不用,后续用PID矫正的时候,可以设置不同的P值,进行P整定;
模式3是PID的I值设置;
模式4/5是留空,后续进行扩展;
模式6是编码器的极限值,在后续的时候,可以设定这个数据,可以实现检测到编码脉冲的总数的时候,观察转的角度,实现脉冲数和旋转角度的对应;
模式7是定时器的定时次数的设置,每次定时器2产生50ms,定时20次,就是1秒,可以改变定时的时间,观察不同的时间内,旋转的角度;

#include “string.h” // strlen函数需用
#include <stdio.h> // sprintf函数需用
#include “LCD1602.H”
#include “key_single.h”
#include “myfun.H”
#include “PWM.h”
#define EncoderLimit 100
#define FOSC 11059200UL
#define BRT (65536 - FOSC / 115200 / 4)

sbit PWMx = P2^1;
sbit PLED = P7^2;
sbit EcoderDir=P6^5; //编码器正反方向,EcoderDir=1,A超B,=0;B超A,
sbit A0=P6^6; //电机正反转
sbit A1=P6^7; //正反
sbit L0=P1^4; //灯0
sbit L1=P1^5; //灯1;
sbit L2=P1^6; //灯2;
sbit L3=P1^7; //灯3;
bit FlagPWM=0;
bit Flag2=1,Flag3=0;
bit S3TI0=0;
unsigned char dir=0;
int time=0;
long int TimeCount=100;//默认5秒
unsigned long EncoderNum0=100,EncoderNum=0;
unsigned char BufMode[3],Buf[9];
unsigned char datas[] = {0, 0, 0, 0, 0};
void port_mode() // 端口模式
{
P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;
P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00;
}
void main()
{
unsigned int keymode=1;
unsigned int keynum=10;
unsigned int PwmValue=10;
// int ding=0;
int t=0;
float PValue=1.05;
float IValue=1.05;
float PosValue=90.0;
// unsigned char *s1=“M”;
// unsigned char *s2=“W”;
// unsigned char *s3=“U”;
// unsigned char *s4=“T”;
// unsigned char *s5=“P”;
// unsigned char *s6=“I”;
unsigned char s7=‘S’;//运行状态,S代表停止,R代表运行;
unsigned char s8=’+’;
// 存放9个待发送ASCII码
port_mode(); // 所有IO口设为准双向弱上拉方式。
PWM_Init();

 P_SW2 |= 0x02;   // RXD3_2/P5.0, TXD3_2/P5.1

//定时器3做串口3的波特率发生器
S3CON = 0x50;//0100	 禁止串口接收数据

// T3L = BRT;
// T3H = BRT >> 8;
T3L =0xE0;
T3H =0xFE;
T4T3M = 0x0a;
IE2 = 0x00; //中断使能寄存器2

 ET0 = 1;
 ET1 = 1;
 TMOD = 0x16; //定时器1为方式1,计数器0为方式2,T0选择C/T=1,计数器方式,脉冲由外部提供
 TH0 = 0xff;
 TL0 = 0xff;
 TR0 = 1;
 TH1 = (65536 - 50000) / 256;
 TL1 = (65536 - 50000) % 256;
 TR1 = 1;
 EA=0;

/************************/
P1=0xff;
delay100ms(); // 等待LCD1602上电时内部复位
LCD1602_Init();
SetCur(CurFlash); // 开光标显示、闪烁,NoCur——有显示无光标,NoDisp——无显示,
A0=0;A1=0; // CurNoFlash——有光标但不闪烁 ,CurFlash——有光标且闪烁
//0123456789abcdef
//M0 W20 U99999T03
//P10.55 I10.55 +R
WriteString(0,0,“M”); // X坐标、Y坐标、字符串,屏幕左上角为坐标原点
WriteString(3,0,“W”);
WriteString(7,0,“U”);
WriteString(13,0,“T”);
WriteString(0,1,“P”);
WriteString(7,1,“I”);
WriteString(14,1,&s7);
WriteString(15,1,&s8);
while(1)
{
keynum=KeyScan();
switch(keynum)
{
case 2: //模式选择:PWM,P,I,默认,电机运动方向
{
if(keymode8)keymode=0;
keymode++;
} break;
case 0:
{
switch(keymode)
{
case 1:
{
// L0=1;L1=1;L2=1;L3=0;
if(PwmValue
90.00)PwmValue=5;
PwmValue+=5;
} break;
case 2:
{
// L0=1;L1=1;L2=0;L3=1;
if(PValue20)PValue=0.01;
PValue+=0.01;
} break;
case 3:
{
// L0=1;L1=1;L2=0;L3=0;
if(IValue
20) IValue=0.01;
IValue+=0.01;
} break;
case 4:
{
// L0=1;L1=0;L2=1;L3=1;
} break;
case 5:
{
// L0=1;L1=0;L2=1;L3=0;

// if(dir1)
// {dir=0;s8=’+’;}
// else if(dir
0)
// {dir=1;s8=’-’;}
// break;
} break;
case 6:
{
// L0=1;L1=0;L2=0;L3=1;
if(EncoderNum0==10000)EncoderNum0=50;
EncoderNum0+=10;

				} 	break;
			case 7:
			   {
	//				L0=0;L1=0;L2=0;L3=0;
					  //最大50*600=30000=30s,最小1s,0.5秒增加
					 if(TimeCount==600)
					   TimeCount=20;
			    	TimeCount+=10;	
						   	  
				} 	break;
				default:break;
			 }
		//	default:break;
			}
			break;
		case 1:
		   {
		 	switch(keymode)
			{case 1:
			   {
			//	L0=1;L1=1;L2=1;L3=0;
				if(PwmValue==5)PwmValue=90;
			    PwmValue-=5;
				}  
				break;
			case 2:
				{
				//	L0=1;L1=1;L2=0;L3=1;
			  		if(PValue==0.01)PValue=20;
					PValue-=0.01;			   		
				}  
             	break;
			case 3:
				{
				//	L0=1;L1=1;L2=0;L3=0;	
					if(IValue==0.01) IValue=20;
					IValue-=0.01;	
					break;	   	
				}
			case 4:
				{
				//	L0=1;L1=0;L2=1;L3=1;
						
				}break;
			case 5:
				{
					L0=1;L1=0;L2=1;L3=0;	
				
				 } 	break;
			case 6:
				{
				//	L0=1;L1=0;L2=0;L3=1;	
					if(EncoderNum0==50)EncoderNum0=10000;
					EncoderNum0-=10;
						   		   
				} 	break;
			case 7:
				{
				//	L0=0;L1=0;L2=0;L3=0;
					  //最大50*600=30000=30s,最小1s,0.5秒增加
					 if(TimeCount==20)
					   TimeCount=600;
			    	TimeCount-=10;	
						   	  
				} 	break;
			default:break;
				}
			//default:break;
		   }  
		   break;
		 case 3://确定,启动电机
		 	{	 			   	
		        A0=1;  //电平方向
				A1=0;
		   	  	Speed_Motor(PwmValue);  //设置PWM占空比
                L0=0;//指示灯
				L1=1;
				EA=1;  //开启总中断
				delay100ms();	 //延时等待稳定
				EncoderNum=0;	//初始值为0
				PWMCR =0x82; //开启PWM
				Flag2=1;
				keymode=1;
				while(Flag2)	
				{
					keynum=KeyScan();
					if(keynum==NoKey&&Flag3==10)
					{
					 L0=0;//指示灯
				             L2=0;
							
							//串口发送到电脑端;
						   	datas[0] = EncoderNum / 10000;	 //万位
							datas[1] = EncoderNum % 10000 / 1000;//千位
							datas[2] = EncoderNum % 1000 / 100;	//百位
							datas[3] = EncoderNum % 100 / 10; //十位
							datas[4] = EncoderNum % 10;	 //	 个位
							TR0=0;TR1=0;//关闭定时和脉冲计数
							for(t=0;t<5;t++)
							{
								S3BUF = '0'+datas[t];//将接收到的数据放入到发送寄存器
                        		while (!(S3CON&0x04));			         //等待发送数据完成

// //S3T1不能位寻址,xxxx xx0x
S3CON=0x50;//将S3T1清零
}
delay50ms();
S3BUF = 0x0a;//将接收到的数据放入到发送寄存器
while (!(S3CON&0x04)); //等待发送数据完成
// //S3T1不能位寻址,xxxx xx0x
S3CON=0x50;//将S3T1清零
// Flag2=0;
//延时5秒,再次开启计数器中断,定时中断,进行计数
for(t=20;t>0;t–)
delay50ms(); //200cheng50=10000ms=10miao
EA=1;
TR0=1;TR1=1;
A0=1;A1=0;
Long_Str(EncoderNum,Buf);
WriteString(8,0,Buf);
WriteString(0,0,“M”);
EncoderNum=0;
PWMCR=0x82;//
Flag3=0;
//Long_Str(EncoderNum,Buf);
// WriteString(8,0,Buf);
// WriteString(0,0,“M”);
} //任意键按下,退出这个
else //有按键按下,显示定时计数得到的脉冲数
{

						}

				}	 	
			} 
			break;
	 default:break;		 
	}

// if(FlagPWM==12)
// {
// PWMCR =0X02; //关闭PWM
// // Speed_Motor(0); //占空比为0;
// FlagPWM=0;
// }
// keynum=100;
//0123456789abcdef
//M0 W20 U99999T03
//P10.55 I10.55 +R
//显示
Int_Str(keymode,BufMode);WriteString(1,0,BufMode);
Int_Str(TimeCount,BufMode);WriteString(14,0,BufMode);
Int_Str(PwmValue,Buf);WriteString(4,0,Buf);
Long_Str(EncoderNum,Buf);WriteString(8,0,Buf);
sprintf(Buf,"%0.2f",PValue);WriteString(1,1,Buf); // 保留2位小数
sprintf(Buf,"%0.2f",IValue);WriteString(8,1,Buf);
}
}

////////////////
void TM0_Isr() interrupt 1 using 1
{
EncoderNum++; //
}

void Time1()interrupt 3
{
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256; //50ms,200*50=10000ms=10s
++time;
if (time ==TimeCount) //定时到50cheng100ms=5秒,关闭中断和PWM
{
EA = 0;
FlagPWM=12;
Flag3=10;
time=0;
A0=0;A1=0;
PWMCR=0x02;
}
}

猜你喜欢

转载自blog.csdn.net/lmf666/article/details/87741666
今日推荐