⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 car.c

📁 自制用C8051F330控制的自动循线小车
💻 C
📖 第 1 页 / 共 2 页
字号:

//设置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 + -