📄 car.c
字号:
//设置T2为系统时基 500Hz,周期为2ms.
//T1为uart0时基
//T3为小车运行时间时基
//uart0数据桢格式 起始 '#' + 'rc'+(0 to 10)+ '*'
// 起始 '#' + 'tk'+(1 to 2)+ '*'
/* 速度共三档: 正常速度1, 两倍速度2, 一半速度3;
运动方式6种 直线前进1 直线后退2 走左圆3 走右圆4 原地左转5 原地右转6
运动时间 0-255秒以内
数据定义为结构体 */
#include <c8051F330.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sfr16 ADC0VAL=0xbd; //ADC0转换值=ADC0L+ADC0H
sfr16 PCA0CP0=0xfb; //CEX0捕捉比较寄存器=PCA0CPL0+PCA0CPH0
sfr16 PCA0CP1=0xe9;
sfr16 PCA0CP2=0xeb;
sfr16 TMR2=0xcc; //定时器2计数器寄存器
sfr16 TMR2RL=0xca; //定时器2重载寄存器
sfr16 TMR3=0x94; //定时器3计数器寄存器
sfr16 TMR3RL=0x92; //定时器3重载寄存器
#define SYSCLK 24000000 //采用外部晶振,24M
#define T2_Freq = 500 //T2系统时基500Hz
#define BAUDRATE 9600 //串口通信波特率
#define Buffer_COUNT 4 //定义接收缓冲区大小
#define car_mode_front 0x0a //1010 小车后退 2
#define car_mode_back 0x06 //0101 小车前进 1
#define car_mode_l_resolve 0x09 //1001 小车原地左转 3
#define car_mode_r_resolve 0x09 //0110 小车原地左转 4
#define Car_sudu_common 30000
#define Car_sudu_double 40000
#define Car_sudu_half 11000
//-----------------------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------------------
void Timer2_ISR ();
void Timer3_ISR ();
void Stop_car ();
void Start_car();
void Timer2_Init (uint val) ;
void Timer3_Init (uint val) ;
void Pca_Init();
void Pwm_set(uint pwm1,uint pwm2) ;
void Data_Init();
void uart0_Init() ;
void config();
void turnleft(); //小车向左转
void turnright(); //小车向右转
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
uchar count_led=0; //LED延时控制变量
uchar count_pwm=0; //PWM占空比进行数据刷新控制变量
sbit P15_LED=P1^5;
sbit P10=P1^0; //小车方向控制变量
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit SENSE1=P0^0; //SENSE1==0 表示传感器在黑线上
sbit SENSE2=P0^1;
sbit SENSE3=P1^6;
sbit SENSE4=P1^7;
uint pwm1=Car_sudu_half;
uint pwm2=Car_sudu_half;
static uint Car_sudu_temp=6800; // 三档速度中间变量
static uint Car_sudu_traking=8600;
static uint Car_run_mode=0; //小车运行方式选择,1 为寻线模式, 2 为远程控制模式
uchar point; // uart0接收数据个数指示变量
uchar receive_buffer[Buffer_COUNT]; //定义接收数据缓冲区
uchar receive_data[3];
static unsigned int Com_Time=0;
static uchar Car_run_time=100;
bit Com_Flag=0;
static char new_data=0;
/*struct
{
char sudu;
char move_mode;
uchar time;
}receive_data;*/
//-----------------------------------------------------------------------------
// T0初始化
//-----------------------------------------------------------------------------
/*void Timer0_Init()
{
}*/
//-----------------------------------------------------------------------------
// 启动小车
//-----------------------------------------------------------------------------
/*void Start_car()
{ Car_run_time=receive_data.time; // 小车运行时间设置
TMR3CN|=0x04; //启动T3
switch (receive_data.sudu) // 小车速度设置
{
case 1: Car_sudu_temp=Car_sudu_common; break;
case 2: Car_sudu_temp=Car_sudu_double; break;
case 3: Car_sudu_temp=Car_sudu_half; break;
default: break;
}
switch (receive_data.move_mode) //小车运行方式设置
{
case 1: pwm1=Car_sudu_temp;pwm2=Car_sudu_temp;
P10=0;P11=1;P12=0;P13=1; break; //小车前进
case 2: pwm1=Car_sudu_temp; pwm2=Car_sudu_temp;
P10=1;P11=0;P12=1;P13=0; break; //小车后退
case 3: pwm1=Car_sudu_temp; pwm2=Car_sudu_temp;
P10=0;P11=1;P12=1;P13=0; break; //小车原地左转
case 4: pwm1=Car_sudu_temp; pwm2=Car_sudu_temp;
P10=1;P11=0;P12=0;P13=1; break; //小车原地右转
case 5: pwm1=Car_sudu_temp*1.3; pwm2=Car_sudu_temp*0.5;
P10=0;P11=1;P12=0;P13=1; break; // 原地右转
case 6: pwm1=Car_sudu_temp*0.5; pwm2=Car_sudu_temp*1.3;
P10=0;P11=1;P12=0;P13=1; break; // 原地后退
default : break;
}
Pwm_set(pwm1,pwm2);
}*/
//-----------------------------------------------------------------------------
// 急停小车
//-----------------------------------------------------------------------------
void Stop_car ()
{
P10=0;P11=0;P12=0;P13=0;
}
//-----------------------------------------------------------------------------
// T2初始化
//-----------------------------------------------------------------------------
void Timer2_Init (uint val) //2ms
{
TMR2CN = 0x00; // 选择定时器2外部时钟为(SYSCLK/12),16 位自动重装载方式
CKCON &= 0xdf; // Timer2 clocked based on T2XCLK;
TMR2RL = ~val+1; // Init reload values
TMR2 = 0xffff; // set to reload immediately
ET2 = 1; // enable Timer2 interrupts
TR2 = 1; // 启动定时器2
}
void Timer3_Init (uint val) //20ms
{
TMR3CN = 0x00; // 选择定时器3外部时钟为(SYSCLK/12),16 位自动重装载方式
CKCON &= 0xbf; // Timer3 clocked based on T3XCLK;
TMR3RL = ~val+1; // Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE1 |= 0x80; // enable Timer3 interrupts
}
//-----------------------------------------------------------------------------
// PWM初始化,PWM频率为12.5M/256=93.8KHz
//-----------------------------------------------------------------------------
void Pca_Init()
{
PCA0MD|=0x08; //08 PCA采用系统时钟24M,(02 4分频) PCA溢出中断禁止
PCA0CN=0x40; //启动PCA计数器
PCA0CPM0=0xcb; //CEX0为16位PWM输出模式
PCA0CPM1=0xcb; //CEX1为16位PWM输出模式
}
void turnleft()
{
uint i;
uint j;
Pwm_set(Car_sudu_traking*0.2,Car_sudu_traking*3);
for (i=0;i<2000;i++)
for (j=0;j<30;j++);
Pwm_set(Car_sudu_traking,Car_sudu_traking);
}
void turnright()
{
uint i;
uint j;
Pwm_set(Car_sudu_traking*3,Car_sudu_traking*0.2);
for (i=0;i<2000;i++)
for (j=0;j<30;j++);
Pwm_set(Car_sudu_traking,Car_sudu_traking);
}
//-----------------------------------------------------------------------------
// PWM占空比设置
//-----------------------------------------------------------------------------
void Pwm_set(uint pwm1,uint pwm2) //pwm1,pwm2的范围在0-65535内
{
uint mid_value;
mid_value=(~pwm1)+1;
PCA0CPL0=mid_value&0x00FF;
PCA0CPH0=((int)mid_value>>8)&0x00FF;
mid_value=(~pwm2)+1;
PCA0CPL1=mid_value&0x00FF;
PCA0CPH1=((int)mid_value>>8)&0x00FF;
}
//-----------------------------------------------------------------------------
// 数据初始化
//-----------------------------------------------------------------------------
void Data_Init() //pwm1,pwm2的范围在0-255内
{
P10=0;P11=0;P12=0;P13=0; //小车停止
Pwm_set(Car_sudu_traking,Car_sudu_traking);
}
//-----------------------------------------------------------------------------
// UART0 初始化 串口通信波特率9600
// 接收数据帧格式 共5个字节 起始位为 (0xaa),然后是四个有效数据字节
// aa |速度位 |运动方式|运动时间|
//-----------------------------------------------------------------------------
void uart0_Init()
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x09;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
TL1 = TH1; // init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
//-----------------------------------------------------------------------------
// 处理器配置
//-----------------------------------------------------------------------------
void config()
{
uint i,j;
PCA0MD&=0x9f; //看门狗定时器被禁止
//用端口输入方式寄存器(PnMDIN)选择所有端口引脚输入方式
P0MDIN=0xff; // 0为模拟输入,1为数字输入
P1MDIN=0xff;
// 用端口输出方式寄存器(PnMDOUT)选择所有端口引脚的输出方式(漏极开路或推挽)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -