//P1.0~P1.7分別對應小車1N1~1N8。
#include <REGX52.H> //頭文件
#define uint unsigned int //宏定義
#define uchar unsigned char
#define left_moto_go {P1_0=1,P1_1=0,P1_2=1,P1_3=0;} //小車方位定義,左邊兩個電機正轉(前進)
#define left_moto_back {P1_0=0,P1_1=1,P1_2=0,P1_3=1;}∥左后退
#define left_moto_stop {P1_0=0,P1_1=0,P1_2=0,P1_3=0;}∥左停止
#define right_moto_go {P1_4=1,P1_5=0,P1_6=1,P1_7=0;}
#define right_moto_back {P1_4=0,P1_5=1,P1_6=0,P1_7=1;}
#define right_moto_stop {P1_4=0,P1_5=0,P1_6=0,P1_7=0;}
#define left_moto_pwm P1_1 //pwm信號端定義
#define left_moto_pwm1 P1_3
#define right_moto_pwm P1_5
#define right_moto_pwm1 P1_7
sbit key0=P3^2; //四位按鍵位聲明
sbit key1=P3^3;
sbit key2=P3^4;
sbit key3=P3^5;
uchar T0RH,T0RL; // 定時器配置
//uchar time; // pwm周期變量
uchar keybuf; // 按鍵
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90}; //共陽數碼管顯示數字0~9
uchar code dis[]={0XF7,0XFB,0XFD,0XFE}; //數碼管位選
uchar disbuf[4]={0}; //數碼管中間變量
uchar pwm_val_left=0; // 占空比有關變量
uchar push_val_left=0; // 左電機占空比 N/10
uchar pwm_val_right=0;
uchar push_val_right=0; //右
//延時
void delay_ms(uint a) //1ms
{
uint x,y;
for(x=0;x<a;x++)
for(y=0;y<115;y++)
;
}
//小車前進
void go(void)
{
left_moto_go ;
right_moto_go ;
}
//小車后退
void back(void)
{
left_moto_back ;
right_moto_back ;
}
//小車停止
void stop(void)
{
left_moto_stop;
right_moto_stop;
}
//小車左轉
void left(void)
{
left_moto_stop;
right_moto_go ;
}
//小車右轉
void right(void)
{
left_moto_go ;
right_moto_stop ;
}
/*
pwm調制電機轉速
*/
void pwm_moto_left(void) //左電機
{
if(pwm_val_left <= push_val_left) // 小于占空比
{
left_moto_pwm=1; //高電平
left_moto_pwm1=1;
}
else
{
left_moto_pwm=0;
left_moto_pwm1=0;
}
if(pwm_val_left>=11) //10個
pwm_val_left=0;
}
void pwm_moto_right(void) //右電機
{
if(pwm_val_right <= push_val_right )
{
right_moto_pwm=1;
right_moto_pwm1=1;
}
else
{
right_moto_pwm=0;
right_moto_pwm1=0;
}
if(pwm_val_right>=11)
pwm_val_right=0;
}
//按鍵掃描
uchar KEY_scan()
{
static uchar backup=1; //靜態變量(自動恢復初值),一次進入標志
if(backup==1&&(key0==0||key1==0||key2==0||key3==0)) //判斷是否有按鍵按下
{
delay_ms(10);
backup=0;
if(key0==0) return 1; //返回按鍵case1:
else if(key1==0) return 2;
else if(key2==0) return 3;
else if(key3==0) return 4;
}
else if(key0==1||key1==1||key2==1||key3==1) return 0; //判斷是否都未按下
}
//數碼管顯示
void display(uint t) //例3428
{
disbuf[0]=tab[t%10]; //個位顯示 3428%10=8
disbuf[1]=tab[t%100/10];
disbuf[2]=tab[t%1000/100];
disbuf[3]=tab[t/1000]; //千位 3428/1000=3
}
//定時器0配置
void timeT0(uint us)
{
unsigned long tmp;
tmp=11059200/12;
tmp=(tmp*us)/1000000;
tmp=65535-tmp;
tmp=tmp+18;
T0RH=(uchar)(tmp>>8);
T0RL=(uchar)tmp;
TMOD&=0XF0;
TMOD|=0X01; //模式1
TH0=T0RH; ∥高四位
TL0=T0RL;
TR0=1; //定時器0中斷
ET0=1; //打開定時器0
}
//主函數
void main()
{
EA=1; //總中斷開關
timeT0(100); //100us
go();
while(1) //無限循環
{
keybuf=KEY_scan();//按鍵調用
if(keybuf)
{
switch(keybuf) //選擇
{
case 1: pwm_val_left++;
pwm_val_right++; break;
case 2: pwm_val_left--;
pwm_val_right--; break;
case 3: break;
case 4: break;
default: break;
}
if(push_val_left<0||push_val_right<0)
{
push_val_left=10; // 十個等級
push_val_right=10;
}
if(push_val_left>11||push_val_right>11)
{
push_val_left=0;
push_val_right=0;
}
}
display( push_val_right*10); //數碼管顯示
}
}
//數碼管掃描
void LCD_scan()
{
static uchar i;
P2=0xFF; //消隱
switch(i) //從i中選擇
{
case 0: P2=dis[i];i++; //P2口賦 1111 0111
P0=disbuf[0]; break; //P0口賦數碼管顯示計算值(個位值)
case 1: P2=dis[i];i++;
if(disbuf[1]==0xc0&&disbuf[2]==0xc0) P0=0xff; //高位消影 個位十位顯示為數字0 P0=0xff
else P0=disbuf[1]; break;
case 2: P2=dis[i];i++;if(disbuf[2]==0xc0) P0=0xff;
else P0=disbuf[2]; break;
case 3: P2=dis[i];i=0;if(disbuf[3]==0xc0) P0=0xff;
else P0=disbuf[3]; break;
default: break;
}
}
//定時器0中斷
void time0() interrupt 1
{
static uchar time2ms=0;
static uint cnt=0;
TH0=T0RH;
TL0=T0RL;
push_val_left++; // 占空比增加
push_val_right++;
pwm_moto_left( ); //左電機調速調用
pwm_moto_right( );
LCD_scan(); //數碼管
}
|