?? mouse_drive.c
字號:
#include "Mouse_Drive.h"
void Delay(unsigned long d);
void WheelPulseIni(void);
void GPIO_Port_A_ISR(void);
void GPIO_Port_B_ISR(void);
void Timer0Ini(void);
void PwmPercent(int32 percent);
void SendInfrared(uint32 frequency);
void ForbidInfrared(void);
void LeftWheelRun(int sel);
void RightWheelRun(int sel);
void SysTickIni(void);
void SysTick_ISR(void);
void wheeljamcheck(void);
void wheelJamdispose(void);
void MouseRUNIni( int run,int puls,int percent);
void Go_Ahead(uint32 n);
void Turnleft(void);
void Turnright(void);
void Turn180L(void);
void Turn180R(void);
void MouseRUN( int run);
void Timer1Ini(void);
void Timer1A_ISR(void);
void map_xy(void);
void MappulseClear(void);
void Check_Infrared(void);
void Judge(uint32 State);
void MicroMouseInit(void);
uint32 CheckKey(void);
void LEDDisplay(uint32 number,uint32 option);
void DirDisplay(void);
/*PA*/
#define SPEED_PULSE_R GPIO_PIN_0
#define STATE_L GPIO_PIN_1
#define STATE_F GPIO_PIN_2
#define STATE_R GPIO_PIN_3
#define RWC2 GPIO_PIN_4
#define LWC2 GPIO_PIN_5
/*PB*/
#define PWM GPIO_PIN_0 //PWM0
#define SPEED_PULSE_L GPIO_PIN_1
//#define INF_SEND_R GPIO_PIN_2
#define KEY GPIO_PIN_3
#define RWC1 GPIO_PIN_4
#define LWC1 GPIO_PIN_5
#define INF_SEND GPIO_PIN_6 //PWM1
#define LED5 GPIO_PIN_7
//PC
#define LED1 GPIO_PIN_3
#define LED2 GPIO_PIN_0
#define LED3 GPIO_PIN_1
#define LED4 GPIO_PIN_2
RUN_DATA g_Run = {0,0,0,0,0,0,0,STOP,1,0x11,50};
CHECK_MAZE Check_Maze_State[2]={0};
MAZEMAP MAP = {1,1,0,10,10};
uint32 goahead = 0;
//------------------------------------------------------------------------------------
// 函數(shù)名稱:Delay
// 函數(shù)功能:延時數(shù)量為 d 個指令周期。
// 輸入?yún)?shù):d,將要延時的時間數(shù)。
//------------------------------------------------------------------------------------
void Delay(unsigned long d)
{
for(;d;d--);
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: WheelPulseIni
// 函數(shù)功能: 輪子脈沖檢測初始化。
//
//------------------------------------------------------------------------------------
void WheelPulseIni(void)
{
// 配置引腳為輸入
GPIODirModeSet(GPIO_PORTA_BASE, SPEED_PULSE_R, GPIO_DIR_MODE_IN);
GPIODirModeSet(GPIO_PORTB_BASE, SPEED_PULSE_L, GPIO_DIR_MODE_IN);
// 配置引腳下降沿和上升沿觸發(fā)中斷
GPIOIntTypeSet(GPIO_PORTA_BASE,SPEED_PULSE_R,GPIO_BOTH_EDGES);
GPIOIntTypeSet(GPIO_PORTB_BASE,SPEED_PULSE_L,GPIO_BOTH_EDGES);
// 初始化禁止引腳輸入中斷
//GPIOPinIntDisable(GPIO_PORTA_BASE,SPEED_PULSE_R);
//GPIOPinIntDisable(GPIO_PORTB_BASE,SPEED_PULSE_L);
// 使能引腳輸入中斷
GPIOPinIntEnable(GPIO_PORTA_BASE,SPEED_PULSE_R);
GPIOPinIntEnable(GPIO_PORTB_BASE,SPEED_PULSE_L);
// 使能GPIO PA口和GPIO PB口中斷
IntEnable(INT_GPIOA);
IntEnable(INT_GPIOB);
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: GPIO_Port_A_ISR
// 函數(shù)功能: 右輪檢測脈沖中斷處函數(shù)
//
//------------------------------------------------------------------------------------
void GPIO_Port_A_ISR(void)
{
uint8 IntStatus;
IntStatus = GPIOPinIntStatus(GPIO_PORTA_BASE,true); // 讀PA口中斷狀態(tài)
if(IntStatus&SPEED_PULSE_R) // 是否為左輪脈沖中斷
{
GPIOPinIntClear(GPIO_PORTA_BASE,SPEED_PULSE_R); // 清中斷
if(g_Run.MouseStop)
LEDDisplay(5 , 2); // 車體停止后,如果輪子轉(zhuǎn)動則閃爍LED
g_Run.RightTime = g_Run.SysTick; // 計(jì)錄當(dāng)前系統(tǒng)(相對)時鐘
if(g_Run.COM_Run == GO_ON)
{
MAP.rightpulse ++;
}
g_Run.RightPulse++; // 脈沖加1計(jì)數(shù)
if( g_Run.RightPulse>=g_Run.PulseCount) // 脈沖計(jì)數(shù)已滿或溢出
if( !(g_Run.WheelStop&0x01)) // 輪子為轉(zhuǎn)動狀態(tài)則將其停止
{
RightWheelRun(0); // 右輪停止
g_Run.RightPulse -= g_Run.PulseCount; // 脈沖計(jì)數(shù)清零
//g_Run.RightPulse = 0;
}
}
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: GPIO_Port_B_ISR
// 函數(shù)功能: 左輪檢測脈沖中斷處函數(shù)
//
//------------------------------------------------------------------------------------
void GPIO_Port_B_ISR(void)
{
unsigned char IntStatus;
IntStatus = GPIOPinIntStatus(GPIO_PORTB_BASE,true); // 讀PA口中斷狀態(tài)
if(IntStatus&SPEED_PULSE_L) // 是否為右輪脈沖中斷
{
GPIOPinIntClear(GPIO_PORTB_BASE,SPEED_PULSE_L); // 清中斷
if(g_Run.MouseStop)
LEDDisplay(1, 2); // 車體停止后,如果輪子轉(zhuǎn)動則閃爍LED
g_Run.LeftTime = g_Run.SysTick; // 計(jì)錄當(dāng)前系統(tǒng)(相對)時鐘
if(g_Run.COM_Run == GO_ON)
{
MAP.leftpulse++;
}
g_Run.LeftPulse++; // 脈沖加1計(jì)數(shù)
if(g_Run.LeftPulse>=g_Run.PulseCount) // 脈沖計(jì)數(shù)已滿或溢出
if(!(g_Run.WheelStop&0x10)) // 輪子為轉(zhuǎn)動狀態(tài)則將其停止
{
LeftWheelRun(0); // 左輪停止
g_Run.LeftPulse -= g_Run.PulseCount; // 脈沖計(jì)數(shù)清零
//g_Run.LeftPulse = 0;
}
}
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: Timer0Ini
// 函數(shù)功能: 定時器0初始化。
//
//------------------------------------------------------------------------------------
void Timer0Ini(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // 使能定時器0模塊
GPIODirModeSet(GPIO_PORTB_BASE, LWC1|RWC1 , GPIO_DIR_MODE_OUT); // 控制引腳輸出
GPIOPinWrite(GPIO_PORTB_BASE, LWC1|RWC1 , 0xff); // GPIO輸出高電平
GPIODirModeSet(GPIO_PORTA_BASE, LWC2|RWC2 , GPIO_DIR_MODE_OUT); // 控制引腳輸出
GPIOPinWrite(GPIO_PORTA_BASE, LWC2|RWC2 , 0xff); // GPIO輸出高電平
GPIODirModeSet(GPIO_PORTB_BASE, PWM | INF_SEND, GPIO_DIR_MODE_HW);
/* 定時器配置*/
TimerConfigure(TIMER0_BASE,TIMER_CFG_16_BIT_PAIR
|TIMER_CFG_A_PWM|TIMER_CFG_B_PWM); // 16位PWM輸出
/*PWM*/
TimerControlLevel(TIMER0_BASE,TIMER_A,true); // PWM初始化有效信號為低電平
TimerLoadSet(TIMER0_BASE,TIMER_A,40000);
TimerMatchSet(TIMER0_BASE,TIMER_A,20000); // 設(shè)置占空比
TimerEnable(TIMER0_BASE,TIMER_A); // 使能定時器A
/*INF_SEND*/
TimerControlLevel(TIMER0_BASE,TIMER_B,true); // PWM初始化有效信號為低電平
TimerDisable(TIMER0_BASE,TIMER_B); // 禁止定時器
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: PwmPercent
// 函數(shù)功能: 設(shè)置占空比。
//
//------------------------------------------------------------------------------------
void PwmPercent(int32 percent)
{
int32 LoadValue;
LoadValue = (int32)400*percent;
TimerMatchSet(TIMER0_BASE,TIMER_A,LoadValue); // 設(shè)置占空比
//g_Run.percent = percent;
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: SendInfrared
// 函數(shù)功能: 發(fā)送紅外線。
// 輸入?yún)?shù): frequency,紅外線調(diào)制頻率
//------------------------------------------------------------------------------------
void SendInfrared(uint32 frequency)
{
uint32 LoadValue;
if(frequency == 38000)
LoadValue = 263;
else
LoadValue = (uint32)10000000/frequency;
TimerLoadSet(TIMER0_BASE,TIMER_B,LoadValue*2);
TimerMatchSet(TIMER0_BASE,TIMER_B,LoadValue); // 設(shè)置占空比
TimerEnable(TIMER0_BASE,TIMER_B); // 使能定時器B
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: ForbidInfrared
// 函數(shù)功能: 禁止發(fā)送調(diào)制紅外線。
//
//------------------------------------------------------------------------------------
void ForbidInfrared(void)
{
TimerDisable(TIMER0_BASE,TIMER_B); // 禁止定時器
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: LeftWheelRun
// 函數(shù)功能: 左輪控制函數(shù)。
// 輸入?yún)?shù): sel,選擇輪子的控制方式:0為停止,1為輪子向前,2為輪子向后。
// percen,占空比,其最大值為99,最小值為1,對于輪子的停止控制該參數(shù)無效。
//------------------------------------------------------------------------------------
void LeftWheelRun(int sel)
{
switch(sel)
{
/*輪子停止轉(zhuǎn)動*/
case 0:
GPIOPinWrite(GPIO_PORTA_BASE,LWC2, 0xff); // 控制引腳輸出高電平
GPIOPinWrite(GPIO_PORTB_BASE,LWC1, 0xff); // GPIO輸出高電平
g_Run.WheelStop |= 1<<4; // 標(biāo)記當(dāng)前狀態(tài)為停止
break;
/*左輪向前*/
case 1:
GPIOPinWrite(GPIO_PORTA_BASE,LWC2, 0xff); // PA4輸出高電平
GPIOPinWrite(GPIO_PORTB_BASE,LWC1, 0x00); // GPIO輸出高電平
g_Run.WheelStop &= 0xef; // 向前運(yùn)行
g_Run.WheelStop |= 0x80;
break;
/*左輪向后*/
case 2:
GPIOPinWrite(GPIO_PORTA_BASE,LWC2, 0x00); // PA4輸出低電平
GPIOPinWrite(GPIO_PORTB_BASE,LWC1, 0xff); // GPIO輸出高電平
g_Run.WheelStop &= 0x6f; // 向后運(yùn)行
break;
case 3:
GPIOPinWrite(GPIO_PORTA_BASE,LWC2, GPIOPinRead(GPIO_PORTA_BASE,LWC2)^LWC2); // PA4輸出低電平
GPIOPinWrite(GPIO_PORTB_BASE,LWC1, GPIOPinRead(GPIO_PORTB_BASE,LWC1)^LWC1); // GPIO輸出高電平
}
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: RightWheelRun
// 函數(shù)功能: 右輪控制函數(shù)。
// 輸入?yún)?shù): sel,選擇輪子的控制方式:0為停止,1為輪子向前,2為輪子向后。
// percen,占空比,其最大值為99,最小值為1,對于輪子的停止控制該參數(shù)無效。
// 全局變量: g_Run.WheelStop,標(biāo)記當(dāng)前狀態(tài)。
//------------------------------------------------------------------------------------
void RightWheelRun(int sel)
{
switch(sel)
{
/*輪子停止轉(zhuǎn)動*/
case 0:
GPIOPinWrite(GPIO_PORTA_BASE,RWC2,0xff); // 控制引腳輸出高電平
GPIOPinWrite(GPIO_PORTB_BASE,RWC1,0xff); // GPIO輸出高電平
g_Run.WheelStop |= 1;
break;
/*右輪向后*/
case 2:
GPIOPinWrite(GPIO_PORTA_BASE,RWC2,0xff); // 控制引腳輸出高電平
GPIOPinWrite(GPIO_PORTB_BASE,RWC1,0x00); // GPIO輸出高電平
g_Run.WheelStop &= 0xf6;
break;
/*右輪向前*/
case 1:
GPIOPinWrite(GPIO_PORTA_BASE,RWC2,0x00); // 控制引腳輸出高電平
GPIOPinWrite(GPIO_PORTB_BASE,RWC1,0xff); // GPIO輸出高電平
g_Run.WheelStop &= 0xfe;
g_Run.WheelStop |= 0x08;
break;
case 3:
GPIOPinWrite(GPIO_PORTA_BASE,RWC2,GPIOPinRead(GPIO_PORTA_BASE,RWC2)^RWC2); // 控制引腳輸出高電平
GPIOPinWrite(GPIO_PORTB_BASE,RWC1,GPIOPinRead(GPIO_PORTB_BASE,RWC1)^RWC1); // GPIO輸出高電平
}
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: SysTickIni
// 函數(shù)功能: 系統(tǒng)節(jié)拍定時器初始化。
//
//------------------------------------------------------------------------------------
void SysTickIni(void)
{
SysTickPeriodSet(SysCtlClockGet()/1000);
SysTickEnable();
SysTickIntEnable();
}
//------------------------------------------------------------------------------------
// 函數(shù)名稱: SysTick_ISR
// 函數(shù)功能: 定時中斷掃描。
//
//------------------------------------------------------------------------------------
void SysTick_ISR(void)
{
static uint32 l = 0,r =0;
g_Run.SysTick++; // 系統(tǒng)時鐘節(jié)拍加1,每中斷自加1
if((g_Run.WheelStop&0x11)==0x11 ) // 如果車已停止
{
if(g_Run.MousePulCount) // 總剩余脈沖數(shù)是否為0,否,則分段運(yùn)行
{
if(g_Run.MousePulCount>MAX_PER_PULS) // 脈沖數(shù)大于分段運(yùn)行脈沖數(shù)
{ // 運(yùn)行分段脈沖數(shù)
g_Run.PulseCount = MAX_PER_PULS;
MouseRUN(g_Run.COM_Run);
g_Run.MousePulCount -= g_Run.PulseCount; // 總脈沖數(shù)減已走脈數(shù)
}
else // 剩余脈沖數(shù)少于或等于分段運(yùn)行脈沖數(shù)
{ // 運(yùn)行總剩余脈沖數(shù)
g_Run.PulseCount = g_Run.MousePulCount;
MouseRUN(g_Run.COM_Run);
g_Run.MousePulCount =0;
}
if(g_Run.COM_Run == GO_ON)
{
if(Check_Maze_State[0].left_1)
{
g_Run.RightPulse++;
l++;
Check_Maze_State[0].left_1 = 0;
}
else
{
if(l)
{
if(l<4)
{
g_Run.LeftPulse ++;
l--;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -