📄 car.c
字号:
P0MDOUT=0x90; //1为推挽输出 输入要配置成开漏输出
P1MDOUT=0x3f;
// 用端口跳过寄存器(PnSKIP)选择应被交叉开关跳过的那些引脚
P0SKIP=0x4f; // 1时对应交叉开关跳过
P1SKIP=0xef;
//将引脚分配给要使用的外设 ,使能交叉开关(XBARE = ‘1’)
XBR0=0x01; //XBR0.0=1:UART TX0, RX0连到端口引脚P0.4和P0.5。
XBR1=0xc2; //弱上拉禁止;交叉开关使能;:CEX0、CEX1连到端口引脚
// 晶振配置,开始采用内部晶振,等稳定后采用外部晶振
CLKSEL=0x00; //选择内部晶振
OSCICN=0x82; //内部H-F振荡器使能, SYSCLK为内部H-F频振荡器2分频 24.5/2=12.25MHz 2>>>0
OSCXCN=0x67; // 关闭 01100111 使能外部振荡器,晶体振荡器方式 24MHz
for (i=0;i<20;i++) // 等待至少1ms
{
for(j=0;j<200;j++);
}
while ( (OSCXCN & 0x80) == 0 ); // 等待晶振稳定 //查询XTLVLD =>'1'?
CLKSEL=0x01; //将系统时钟切换到外部振荡器
}
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------
main()
{
config(); // 处理器配置
Pca_Init(); // PWM初始化
Timer2_Init(4000);//T2定时器溢出1/(500Hz)=2ms,定时计数 SYSCLK/(12*T2_Freq)=4000
Timer3_Init(40000);//T2定时器溢出1/(50Hz)=20ms,定时计数 SYSCLK/(12*T2_Freq)=40000
Data_Init() ;
uart0_Init() ;
EA=1; //开全局中断
IE|=0x10; //允许uart0中断
while(1)
{
//-----------------------------------------------------------------------------
// 任务一
// 控制LED定时1秒闪烁 1000/4=250
//-----------------------------------------------------------------------------
if (count_led>=250)
{
count_led=0;
P15_LED=~P15_LED;
}
/*if(Com_Time>=20)
{
Com_Time=0;
Com_Flag=1;
TI0=1;
}*/
//-----------------------------------------------------------------------------
// 任务二
// 启动小车
//-----------------------------------------------------------------------------
/*if(point==4 && receive_buffer[1]<='3' && receive_buffer[2]<='6' && receive_buffer[3]<='9') //uart0收到完整数据桢
{
Stop_car();
point=0;
receive_data.sudu=receive_buffer[1];
receive_data.move_mode=receive_buffer[2];
receive_data.time=receive_buffer[3];
Start_car();
}*/
//-----------------------------------------------------------------------------
// 任务三
// 停止小车
//-----------------------------------------------------------------------------
/* if (Car_run_time==0)
{
Stop_car();
Car_run_time=100;
TMR3CN &=0xfb;
} */
//-----------------------------------------------------------------------------
// 任务四
// 获得传感器数据 小车进行寻线模式
//-----------------------------------------------------------------------------
if( Car_run_mode==1) // 小车进行寻线模式
{
if (SENSE1==0 && SENSE2==0 && SENSE3==0 && SENSE4==1)//小车左转
{
turnleft();
}
if (SENSE1==0 && SENSE2==0 && SENSE3==1 && SENSE4==0) //小车右转
{
turnright();
}
if (SENSE1==0 && SENSE2==1 && SENSE3==0 && SENSE4==1) //小车右转
{
turnright();
}
if (SENSE1==0 && SENSE2==1 && SENSE3==1 && SENSE4==0) //小车左转
{
turnleft();
}
if (SENSE1==0 && SENSE2==1 && SENSE3==1 && SENSE4==1) //小车右转
{
turnright();
}
if (SENSE1==1 && SENSE2==0 && SENSE3==0 && SENSE4==1) //小车左转
{
turnleft();
}
if (SENSE1==1 && SENSE2==0 && SENSE3==1 && SENSE4==1) //小车右转
{
turnright();
}
if (SENSE1==1 && SENSE2==0 && SENSE3==1 && SENSE4==1) // 倒退
{
//turnright();
}
if (SENSE1==1 && SENSE2==1 && SENSE3==0 && SENSE4==1) //小车左转
{
turnleft();
}
if (SENSE1==1 && SENSE2==1 && SENSE3==1 && SENSE4==0) //小车右转
{
turnright();
}
if (SENSE1==1 && SENSE2==1 && SENSE3==1 && SENSE4==1) // 倒退
{
//turnright();
}
}
//-----------------------------------------------------------------------------
// 任务五
// 小车进行远程控制模式
//-----------------------------------------------------------------------------
if( Car_run_mode==2 && new_data==1) // 小车进行远程控制模式
{
new_data=0;
switch (receive_data[0])
{
case '0': Stop_car (); //停止小车
break;
case '1': Pwm_set(Car_sudu_half,Car_sudu_half); Car_sudu_temp=Car_sudu_half;
P10=0;P11=1;P12=0;P13=1; //启动小车低速前进
break;
case '2': Pwm_set(Car_sudu_half,Car_sudu_half); Car_sudu_temp=Car_sudu_half;
P10=1;P11=0;P12=1;P13=0; //启动小车低速后退
break;
case '3': Pwm_set(Car_sudu_half*0.5, Car_sudu_half*2.2);//小车左转
break;
case '4':
Pwm_set(Car_sudu_half*2.2, Car_sudu_half*0.5);//小车右转
break;
case '5':
Pwm_set(Car_sudu_half*2.2, Car_sudu_half*0.5);//小车后左转
break;
case '6':
Pwm_set(Car_sudu_half*0.5,Car_sudu_half*2.2); //小车后右转
break;
case '7': Pwm_set(Car_sudu_half*2.5,Car_sudu_half*2.5); //小车原地左转
P10=0;P11=1;P12=1;P13=0;
break;
case '8': Pwm_set(Car_sudu_half*2.5,Car_sudu_half*2.5); //小车原地右转
P10=1;P11=0;P12=0;P13=1;
break;
case '9': if( Car_sudu_temp<=50000) //小车加速
{ Car_sudu_temp+=4000; Pwm_set( Car_sudu_temp, Car_sudu_temp); }
break;
default :
break;
}
}
//-----------------------------------------------------------------------------
// 任务六
// 对PWM占空比进行数据更新范围(0-255) 刷新率5Hz
//-----------------------------------------------------------------------------
/* if (count_pwm>=100)
{
count_pwm=0;
pwm1=10;pwm2=10;
Pwm_set(~pwm1,~pwm2);
}
*/
}
}
//-----------------------------------------------------------------------------
// 中断服务程序
//-----------------------------------------------------------------------------
void Timer2_ISR()interrupt 5 //T2定时溢出处理
{
TF2H=0; //溢出标志软件清0
count_led++;
count_pwm++;
Com_Time++;
}
void Timer3_ISR()interrupt 14 //T2定时溢出处理
{
static char t3_i=0;
TMR3CN &=0x7f; //溢出标志软件清0
if (t3_i>=50)
{ t3_i=0; Car_run_time--;}
t3_i++;
}
void uart0_ISR() interrupt 4 //全双工uart接收
{
uchar receive_temp;
if (RI0==1) //处理接收中断
{
RI0=0; //清除中断标志位
receive_temp=SBUF0; //接收串口数据
if (point==0)
{
if(receive_temp=='#') //判断是否起始位
point++;
else
point=0;
}
else if (point>0 && point<=3) //判断是否接收够4bit
receive_buffer[point++]= receive_temp;
else if (point==4) //判断是否接收够4bit
{
if(receive_temp=='*')
{
receive_data[0]= receive_buffer[3];
if(receive_buffer[1]=='r' && receive_buffer[2]=='c')
{
Car_run_mode=2; new_data=1;
}
if(receive_buffer[1]=='t' && receive_buffer[2]=='k')
{
Car_run_mode=1;
switch ( receive_data[0])
{
case '1': Pwm_set(Car_sudu_traking,Car_sudu_traking);
P10=0;P11=1;P12=0;P13=1;
break;
case '2': P10=0;P11=0;P12=0;P13=0;
break;
}
}
point=0;
}
else
point=0;
}
else point=0; //缓冲区已满,清除缓冲区内数据,重新接收
}
if (TI0)
{
TI0=0;
/*if(Com_Flag)
{
SBUF0='s';
Com_Flag=0;
}*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -