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

📄 0402car2007.c

📁 2007年电子大赛小车过跷跷板的程序。主控芯片为C8051F040
💻 C
📖 第 1 页 / 共 2 页
字号:
	TMR2CN = 0x04;  // T2为16bit定时器模式,并启动定时器运行
}
//---------------------------------- 
void t2_baud(uint t2reload)
{//每隔t2reload个T2时钟,产生一次定时溢出
	SFRPAGE = 0x00;
	RCAP2=~t2reload+1;//相当于65536-t2reload
	TMR2=RCAP2;
}
//---------------------------------- 
void adc0_mux(uchar type,uchar source)
{//type 配置测量方式为差动还是单端输入
//source 为ADC0通道选择(共有9个通道)
	SFRPAGE=0x00;
	AMX0CF=type;
	AMX0SL=source;
}
//---------------------------------- 
void adc0_ini()
{
	SFRPAGE=0x00;
	ADC0CF=0x00;//ADC0时钟为系统时钟2分频,PGA增益为1
	ADC0CN=0x8c;//AD0TM=0,ADC0为连续跟踪模式,由T2溢出率启动ADC0
	//AD0LJST=0,数据存储格式右对齐,即ADC0H存放12bit高四位
	REF0CN&=0x0f;//AD0VRS=0,ADC0参考电压为VREFA
	REF0CN|=0x07;//TEMPE=1,内部温度传感器工作
	//BIASE=1,偏移产生器工作
	
	/*REFBE=1,内部参考电平工作,电路部分须将VREF参考输出(C8051F40的第12管脚)与	VREF0(C8051F040的16管脚相连,并最好并联一个4.7uF和0.1uF的旁路电容以电平滤波*/
	
	adc0_mux(0x08,2);//PORT3IC=1,ADC0 6、7通道为差动模式
	//HVDA2C=0,4、5通道为单端模式
	//AIN0.0-AIN0.3均为单端模式
	//选择AIN0.2为ADC0转化通道
	EIE2 |= 0x02;        //开ADC0中断
	t2_ini();
	t2_baud(2000);//每隔2000个T2时钟产生一次ADC0采样
	SFRPAGE=0x00;
	TR2=1;
}
//=====================================================================================
//端口及交叉开关配置
void config()
{
	EA=0;
//晶振配置,采用内部晶振8分频
	SFRPAGE = 0x0F;
 	CLKSEL = 0x00;  
	OSCXCN = 0x00;	
	OSCICN = 0x84;	
///spi_init()
     SFRPAGE   = SPI0_PAGE;
      SPI0CFG   = 0x40;
      SPI0CN    = 0x01;
      SPI0CKR   = 0x6D;
//看门狗禁止
	WDTCN = 0x07;	
    WDTCN = 0xDE;   
   	WDTCN = 0xAD;
	SFRPAGE = 0x0F;

//port_init()
    SFRPAGE   = 0x0F;//CONFIG_PAGE;
    P0MDOUT=0xfe;
    XBR0      = 0x06;
    XBR2      = 0x40;

//交叉开关配置,CEX0-CEX5配置到P0.0-P0.5
	//XBR0 = 0x30;	
	XBR1 = 0x00;	
	//XBR2 = 0x40;
 	XBR3 = 0x00;   
//管脚输出配置,P0口为开漏输出,其中P0.6接上拉电阻,P0为数字输入口
 	SFRPAGE = 0x0F;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
 	//P0MDOUT = 0x00; //端口配置,P0-P3,P6-P7口为开漏输出
    P1MDOUT = 0x00; 
    P2MDOUT = 0x00; 
    P3MDOUT = 0x00; 
    P4MDOUT = 0x00; //P4口为开漏,也可推挽
    P5MDOUT = 0x00; 
    P6MDOUT = 0x00; 
    P7MDOUT = 0x00; 
    P1MDIN = 0xFF;  //所有端口为数字输入,没有模拟输入端口
   // P2MDIN = 0xFF;  
    P3MDIN = 0xFF; 
//配置定时器
	SFRPAGE=0x00;
   	TMOD|=0x01;
	CKCON=0x00;//12fp
    TH0 = 0xf6;
    TL0 = 0x08;
	ET0=1;
	TR0=1;

	EA=1;//开启全局中断
}
//=====================================================================================
//直流电机控制
void Forward_slow(uchar speed)//前进
{  
   MOTO_FORD;
   PWM0_set(speed);
   delay1ms(270);
   MOTO_BREAK;
}
//----------------------------------  
void Backward_slow(uchar speed)//后退
{
   MOTO_BACK;
   PWM0_set(speed);
   delay1ms(270);
   MOTO_BREAK;
}
//---------------------------------- 
void Forward_lx(uchar speed)//前进
{  
   MOTO_FORD;
   PWM0_set(speed);
}
//---------------------------------- 
void Backward_lx(uchar speed)//后退
{
   MOTO_BACK;
   PWM0_set(speed);
}
//---------------------------------- 
void stop_stop()//后退
{
   MOTO_BREAK;
   delay1ms(200);
}

//=====================================================================================
//步进电机控制
void bjdj_Init(void)
{
    reset=0;
    delay1ms(10);
    reset=1;
    delay1ms(10);
}
//---------------------------------- 
void DuoJi_Forward(uint counter)
{   uint i;
    control= 0;
    ccw=1;
    for(i=0;i<counter;i++)
	{
      clock=1;
      delay1ms(1);
	  clock=0;
	  delay1ms(1);
    }
    control= 1;
}
//---------------------------------- 
void DuoJi_Backward(uint counter)
{   uint i;
    control= 0;
    ccw=0;
    for(i=0;i<counter;i++)
	{
      clock=1;
      delay1ms(1);
	  clock=0;
	  delay1ms(1);
    }
    control= 1;
}
//======================================================================================
void delay1ms(uint time)
{//延迟1ms*time,这不是一个精确值
	uint i;
	uint j;
	for (i=0;i<time;i++){
		for(j=0;j<300;j++);
	}
}	
//---------------------------------- 
void delay1us(uint time)
{//延迟1us*time,这不是一个精确值
	uint i;
	uint j;
	for (i=0;i<time;i++){
		for(j=0;j<3;j++);
	}
}	
//---------------------------------- 
void writelcd(uchar spi_data) 
{
    uint i,j;
 	for(i=0;i<9;i++);
	LcdCs=0;
	delay1us(1);	
	SPI_BUSY=1;
	SFRPAGE   = SPI0_PAGE;
	SPI0DAT=spi_data;
	for(j=0;j<500;j++)
	{
	   if(!SPI_BUSY)break;
	} 
	delay1us(1);
	LcdCs=1;
	delay1us(6);
	//for(k=0;k<5000;k++);
}
//---------------------------------- 
void writecode(uchar ins) 
     {
      uchar t;
	  uint  j;
	  for(j=0;j<500;j++);	
	  virt_port|=ins&0xf0;					//取高字节向1602写数据 
	  writelcd(virt_port);					//先写高4位后再写低4位 这是在选择四个数据线的时候
	  virt_port|=0x08;						  
	  writelcd(virt_port);					//使能E脚为高电平
      virt_port&=~0x08;					
	  writelcd(virt_port);					//使能E脚为低电平
      t=ins<<4;             
      virt_port|=t&0xf0;          			//取低字节向1602写数据
	  writelcd(virt_port);
      virt_port|=0x08;						//使能E脚为高电平
	  writelcd(virt_port);
      virt_port&=~0x08;					    //使能E脚为低电平
	  writelcd(virt_port);
      virt_port=0;
	  writelcd(virt_port);
     }
//---------------------------------- 
void writedata(uchar d)	
     {
      uchar i,t;
	  uint  j;
      for(j=0;j<50;j++);		
      virt_port|=0x02;					   //光标返回指令
	  writelcd(virt_port);
      virt_port|=d&0xf0;				   //取高字节数据给数据寄存器
	  writelcd(virt_port);
      virt_port|=0x08;                     //使能E脚为高电平
	  writelcd(virt_port);
      virt_port&=0xf7;      			   //使能E脚为低电平
	  writelcd(virt_port);
      virt_port&=0x07;					   //设置光标右移,文字也右移
      writelcd(virt_port);
      t=d&0x0f;
      virt_port|=t<<4;					   //取低字节数据给数据寄存器
	  writelcd(virt_port);
	  virt_port|=0x08;      			   //使能E脚为高电平
	  writelcd(virt_port);
      for(i=3;i>0;i--); 
      virt_port&=0xf7;                     //使能E脚为低电平
	  writelcd(virt_port);
      virt_port=0;						   //数据清零
	  writelcd(virt_port);
    }
//---------------------------------- 
void lcdchar(uchar line) 
 {
     uchar i;
     if(line==0)
     {
	   writecode(0x00);// 换行  
       for(i=0;i<16;i++) writedata(lcm_data1[i]);
     }
	 if(line==1)
	 {
       writecode(0xb0);// 换行                   
       for(i=0;i<16;i++) writedata(lcm_data2[i]);
     }
}
//---------------------------------- 
void lcdinit()
{
      uint xdata i;
      virt_port=0x00;
	  writelcd(virt_port);	     //RS脚为零写指令寄存器	 RW为低电平
      virt_port|=0x08;     	     //使能脚E=1
	  writelcd(virt_port);
 	  virt_port&=0xf7;    		 //使E=0使能脚发生跳变高--低
	  writelcd(virt_port);
	  for(i=1000;i>0;i--);	     //3次延时,重要!
	  for(i=8000;i>0;i--);		 //用延时代替查询	  
      virt_port=0;				 //写入20码,设置为4位总线方式,非常重要!!!!!
	  writelcd(virt_port);
      virt_port|=0x20;			 //只写高字节
	  writelcd(virt_port);
      virt_port|=0x08;           //E=1
	  writelcd(virt_port);
	  for(i=20;i>0;i--);		 //使命令执行
      virt_port&=0xf7;           //E=0
	  writelcd(virt_port);
	  for(i=10;i>0;i--);
      virt_port=0;
	  writelcd(virt_port);
      writecode(0x38);	    	//设两行显示,4线方式5*10字符显示
      for(i=50;i>0;i--);
	  writecode(0x06);			//光标右移
      for(i=50;i>0;i--);
	  writecode(0x0c);		    //开显示指令
      for(i=50;i>0;i--);
      writecode(0x02);			//光标返回指令
      for(i=50;i>0;i--);
	  writecode(0x01);			//清屏指令
	  for(i=50;i>0;i--);
}
//**************************************************************************************
//ADC0中断
void ADC0_ISR() interrupt 15
{   
   static uint  int_dec=20;
   static ulong accumulator=0L;  
   uint temp_l;
   uint temp_h;

   SFRPAGE=0x00;
   AD0INT=0;
   temp_l = ADC0L;
   temp_h = ADC0H;
   accumulator += ((temp_h<<8) | temp_l);

   int_dec--;

   if (int_dec == 0)
   {
      int_dec = 20;
      Value = accumulator/20;
      accumulator = 0L;
   }
}
//****************************************************************************************
void spi_srs  () interrupt 6
{
	if(SPIF)		
	{
	    SFRPAGE   = SPI0_PAGE;
	    SPIF=0;
		SPI_BUSY=0;
	}
	if(WCOL)
	{
	    SFRPAGE   = SPI0_PAGE;
		WCOL=0;
	}
}
//****************************************************************************************
void t0_ISR() interrupt 1    //T0中断处理
{
   static uchar time_counter;
   static uchar time_data;
   TH0 = 0xf6;
   TL0 = 0x08;

   time_counter++;
   if(time_counter>100)
      {time_counter=0;
	   time_data++;
	   show_time(time_data);
	  }
}
//****************************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -