- #include<reg52.h>
- #include<math.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar Buffer =0; // 從串口接收的數據
- uint URTAReceivedCount=0,n=1;
- uchar dataTempdatatable[5],CommandDatatable[5];// 數據包
- uchar serVal[2];
- uintpwm[]={1120,1190,1382,1382,1382,1382,1382,1382}; // 初始 90 度 , (實際是 1382.4 ,取整得 1382 )
- uchar pwm_flag=0;
- uint code ms0_5Con=461; //0.5ms 計數 (實際是 460.8 ,取整得 461 )
- uint code ms2_5Con=2304; //2.5ms 計數
- bit key_stime_ok;
- sbit StatusLight=P2^0; // 狀態燈
- sbit MainLight=P2^1; // 主大燈
- sbit servo0=P0^0; // 舵機控制
- sbit servo1=P0^1;
- sbit servo2=P0^2;
- sbit servo3=P0^3;
- sbit servo4=P0^4;
- sbit servo5=P0^5;
- sbit servo6=P0^6;
- sbit servo7=P0^7;
- // 定義智能小車驅動模塊輸入 IO
- sbit IN1 = P1^0; // 高電平 1 后退(反轉)
- sbit IN2 = P1^1; // 高電平 1 前進(正轉)
- sbit IN3 = P1^2; // 高電平 1 前進(正轉)
- sbit IN4 = P1^3; // 高電平 1 后退(反轉)
- sbit EN1 = P1^4; // 高電平使能
- sbit EN2 = P1^5; // 高電平使能
- /********************************************************************
- * 名稱 : Delay_1ms()
- * 功能 : 延時子程序,延時時間為 1ms * x
- * 輸入 : x ( 延時一毫秒的個數 )
- * 輸出 : 無
- ***********************************************************************/
- void Delay_1ms(uint i)//1ms 延時
- {
- uchar x,j;
- for(j=0;j<i;j++)
- for(x=0;x<=148;x++);
- }
- void TurnOnStatusLight()
- {
- StatusLight=0;
- }
- /********************************************************************
- * 名稱 : Send_Data()
- * 功能 : 向上位機傳送字符
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Send_Data(uchar type,uchar cmd,uchardat)
- {
- uchardata Buffer[5];// 構建數據包
- uchar*p;
- uintSend_Count=0;
- p =Buffer;
- Buffer[0]=0XFF;
- Buffer[1]=type;
- Buffer[2]=cmd;
- Buffer[3]=dat;
- Buffer[4]=0XFF;
- while(1)
- {
- if(*p==0XFF)
- {
- Send_Count++; //0XFF 標志統計位
- }
- SBUF= *p; // 發送
- while(!TI) // 如果發送完畢,硬件會置位 TI ,等待發送完畢
- {
- _nop_();
- }
- p++;
- TI =0;
- if(Send_Count == 2) // 當統計到兩次出現 0XFF ,則認為一個數據包發送完畢,跳出循環
- {
- TI =0;
- break;
- }
- }
- }
- /********************************************************************
- 協議規定:
- 包頭 類型位 數據位 數據位 結束位
- 0XFF 0X** OX** 0X** 0XFF
- 各命令說明:
- 類型位 數據位 數據位 功能
- 0X00 0X02 0X00 前進
- 0X00 0X01 0X00 后退
- 0X00 0X03 0X00 左轉
- 0X00 0X04 0X00 右轉
- 0X00 0X00 0X00 停止
- 0X01 0X01 角度 舵機 1
- 0X01 0X02 . 舵機 2
- 0X01 0X01 . 舵機 3
- 0X01 0X02 . 舵機 4
- 0X01 0X01 . 舵機 5
- 0X01 0X02 . 舵機 6
- 0X01 0X01 . 舵機 7
- 0X01 0X02 數據 舵機 8
- 0X02 0X01 車燈亮
- 0X02 0X02 車燈滅
- 0X03 雷達數據 發送雷達數據
- ***********************************************************************/
- /********************************************************************
- * 名稱 : Com_Int()
- * 功能 : 串口中斷子函數
- ***********************************************************************/
- void Com_Int(void) interrupt 4
- {
- uchar temp;
- ES=0; // 關串口中斷
- RI=0; // 軟件清除接收中斷
- temp=SBUF;
- if(temp==0XFF &&URTAReceivedCount<3)
- {
- Tempdatatable[0]==0XFF; // 包頭
- URTAReceivedCount++;
- }
- else
- {
- Tempdatatable[n]=temp;
- n++;
- if(URTAReceivedCount==0&&n==2)
- n=1;
- }
- if(URTAReceivedCount==2)// 包尾
- {
- Tempdatatable[0]=0XFF;
- Tempdatatable[4]=0XFF;
- n=1;
- URTAReceivedCount=0; // 組包完畢
- temp="";
- //Send_Data(Tempdatatable[1],Tempdatatable[2],Tempdatatable[3]); // 發送組成的數據包回去
- }
- CommandDatatable[0]=Tempdatatable[0];
- CommandDatatable[1]=Tempdatatable[1];
- CommandDatatable[2]=Tempdatatable[2];
- CommandDatatable[3]=Tempdatatable[3];
- CommandDatatable[4]=Tempdatatable[4];
- ES=1;// 開串口中斷
- }
- /********************************************************************
- * 名稱 : Com_Init()
- * 功能 : 串口初始化,晶振 11.0592, 波特率 9600 ,使能了串口中斷
- ***********************************************************************/
- void Com_Init(void)
- {
- TMOD= 0x21;
- PCON= 0x00;
- SCON= 0x50;
- TH1 =0xFd; // 設置波特率 9600
- TL1 =0xFd;
- TR1 =1; // 啟動定時器 1
- ES =1; // 開串口中斷
- EA =1; // 開總中斷
- IT0=0;
- EX0=1;
- }
- /********************************************************************
- * 名稱 :Moto_Forward()
- * 功能 : 電機 1 、 2 啟動,都是前進,整車表現為前進。
- ***********************************************************************/
- void Moto_Forward()
- {
- IN1=0; // 左電機
- IN2=1;
- IN3=1; // 右電機
- IN4=0;
- EN1=1;
- EN2=1;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名稱 :Moto_Backward()
- * 功能 : 電機 1 、 2 啟動,都是后退,整車表現為后退。
- ***********************************************************************/
- void Moto_Backward()
- {
- IN1=1; // 左電機
- IN2=0;
- IN3=0; // 右電機
- IN4=1;
- EN1=1;
- EN2=1;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名稱 :Moto_TurnLeft()
- * 功能 : 電機 1 后退,電機 2 前進,整車表現為左轉。
- ***********************************************************************/
- void Moto_TurnLeft()
- {
- IN1=0; // 左電機
- IN2=0;
- IN3=1; // 右電機
- IN4=0;
- EN1=1;
- EN2=1;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名稱 :Moto_TurnRight()
- * 功能 : 電機 1 前進,電機 2 后退,整車表現為右轉。
- ***********************************************************************/
- void Moto_TurnRight()
- {
- IN1=0; // 左電機
- IN2=1;
- IN3=0; // 右電機
- IN4=0;
- EN1=1;
- EN2=1;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名稱 :Moto_Stop()
- * 功能 : 電機 1 停止,電機 2 停止,整車表現為停止。
- ***********************************************************************/
- void Moto_Stop()
- {
- IN1=0; // 左電機
- IN2=0;
- IN3=0; // 右電機
- IN4=0;
- EN1=1;
- EN2=1;
- Delay_1ms(100);
- }
- /********************************************************************
- * 功能 : 舵機 PWM 中斷初始化
- ***********************************************************************/
- void Timer0Init()
- {
- /*0 度 =0.5ms, 45 度 =1ms, 90 度 =1.5ms, 135 度 =2ms, 180 度 =2.5ms
- /.5ms 初始值 F700, (12n/11059200=2.5/1000,n=2304, X=65536-2304=63232 > F700)*/
- TMOD|= 0x01; // 使用模式 1 , 16 位定時器,使用 "|" 符號可以在使用多個定時器時不受影響
- TH0=-ms2_5Con>>8; // 給定初值, 17ms 中斷
- TL0=-ms2_5Con;
- EA=1;// 總中斷打開
- ET0=1; // 定時器 0 中斷打開
- TR0=1; // 定時器 0 開關打開
- }
- /********************************************************************
- * 功能 : 舵機 PWM 中斷 , // 舵機控制函數 周期為 20ms 一個循環 20MS = 8*2.5ms
- ***********************************************************************/
- void SteeringGear() interrupt 1
- {
- switch(pwm_flag)
- {
- case1: servo0=1; TH0=-pwm[0]>>8; TL0=-pwm[0]; break;
- case2: servo0=0; TH0=-(ms2_5Con-pwm[0])>>8; TL0=-(ms2_5Con-pwm[0]); break;
- case3: servo1=1; TH0=-pwm[1]>>8; TL0=-pwm[1]; break;
- case4: servo1=0; TH0=-(ms2_5Con-pwm[1])>>8; TL0=-(ms2_5Con-pwm[1]); break;
- case5: servo2=1; TH0=-pwm[2]>>8; TL0=-pwm[2]; break;
- case6: servo2=0; TH0=-(ms2_5Con-pwm[2])>>8; TL0=-(ms2_5Con-pwm[2]); break;
- case7: servo3=1; TH0=-pwm[3]>>8; TL0=-pwm[3]; break;
- case8: servo3=0; TH0=-(ms2_5Con-pwm[3])>>8; TL0=-(ms2_5Con-pwm[3]); break;
- case9: servo4=1; TH0=-pwm[4]>>8; TL0=-pwm[4]; break;
- case10: servo4=0; TH0=-(ms2_5Con-pwm[4])>>8; TL0=-(ms2_5Con-pwm[4]); break;
- case11: servo5=1; TH0=-pwm[5]>>8; TL0=-pwm[5]; break;
- case12: servo5=0; TH0=-(ms2_5Con-pwm[5])>>8; TL0=-(ms2_5Con-pwm[5]); break;
- case13: servo6=1;TH0=-pwm[6]>>8; TL0=-pwm[6]; break;
- case14: servo6=0;TH0=-(ms2_5Con-pwm[6])>>8; TL0=-(ms2_5Con-pwm[6]); break;
- case15: servo7=1;TH0=-pwm[7]>>8; TL0=-pwm[7]; break;
- case16: servo7=0;TH0=-(ms2_5Con-pwm[7])>>8; TL0=-(ms2_5Con-pwm[7]); break;
- default: TH0=0xff; TL0=0x80; pwm_flag=0;
- }
- pwm_flag++;
- }
- voidSetSteeringGear(uchar i, uchar val)
- {
- uinta = (val+46)*10;
- if(a<ms0_5Con)
- a=ms0_5Con;
- if(a>ms2_5Con)
- a=ms2_5Con;
- pwm[i]=a;
- CommandDatatable[2]=0xff; // 清除緩存
- }
- /********************************************************************
- * 功能 : 串口中斷接收數據
- ***********************************************************************/
- /*********************************************************************************
- ** 函數功能 : 主函數
- *********************************************************************************/
- void main()
- {
- MainLight=0;
- Delay_1ms(200);
- Com_Init();// 串口初始化
- Timer0Init();// 舵機 PWM 中斷初始化
- while(1)
- {
- if(CommandDatatable[0]==0XFF &&CommandDatatable[4]==0XFF)
- {
- switch (CommandDatatable[1]) // 根據鍵值不同,執行不同的內容
- {
- case0X00: // 類型位 0X00 ,表明是控制數據包,進入控制數據 case
- switch(CommandDatatable[2]) // 根據數據位的值來進行選擇執行不同的動作
- {
- case0X00:Moto_Stop();break;
- case0X01:Moto_Forward();break;
- case0X02:Moto_Backward();break;
- case0X03:Moto_TurnLeft();break;
- case0X04:Moto_TurnRight();break;
- default : break;
- }
- break;
- case0X01: // 類型位 0X01 ,表明是舵機數據包,進入舵機 case
- switch(CommandDatatable[2])
- {
- case0x01:SetSteeringGear(0,CommandDatatable[3]);break;
- case 0x02:SetSteeringGear(1,CommandDatatable[3]);break;
- case 0x03:SetSteeringGear(2,CommandDatatable[3]);break;
- case 0x04:SetSteeringGear(3,CommandDatatable[3]);break;
- case 0x05:SetSteeringGear(4,CommandDatatable[3]);break;
- case 0x06:SetSteeringGear(5,CommandDatatable[3]);break;
- case 0x07:SetSteeringGear(6,CommandDatatable[3]);break;
- case 0x08:SetSteeringGear(7,CommandDatatable[3]);break;
- default : break;
- }
- break;
- case0X02: // 類型位 0X02 ,表明是大燈數據包,進入大燈 case
- switch(CommandDatatable[2])
- {
- case0X01:MainLight=1;break;
- case0X02:MainLight=0;break;
- default : break;
- }
- break;
- default : break;
- }
- }
- }
- }
復制代碼
|