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

📄 mcs51-项目开发经典.c

📁 本人自己写的经典51程序完全好用。包括7279
💻 C
📖 第 1 页 / 共 5 页
字号:
            for(wqy2=0;wqy2<200;wqy2++);
            //CLK_L297 =1;//步进脉冲高电平
			//for(t1_delay_time=0;t1_delay_time<40;);
           }

		 E_L297 =0;
		 test_command=0;
		 break;
	    }
	 //-----------------------------------------
	 case TEST_DC_MOTOR://13
	    {
		 dc_motor_z();
		 for(t1_delay_time=0;t1_delay_time<4;);//加200毫秒延时

		 motor_speed_delay=10;
		 for(t1_delay_time=0;t1_delay_time<60;)//正向加速
		   {PWM_DCMOTOR =OPEN;//电机开
            for(wqy2=0;wqy2<motor_speed_delay;wqy2++);
            PWM_DCMOTOR =CLOSE;//电机关
            for(wqy2=0;wqy2<200;wqy2++);
            motor_speed_delay+=10;
			if(motor_speed_delay>60000) motor_speed_delay=60000;
		   }
		 for(t1_delay_time=0;t1_delay_time<60;)//正向减速
		   {PWM_DCMOTOR =OPEN;//电机开
            for(wqy2=0;wqy2<motor_speed_delay;wqy2++);
            PWM_DCMOTOR =CLOSE;//电机关
            for(wqy2=0;wqy2<200;wqy2++);
            motor_speed_delay-=10;
			if(motor_speed_delay<10) motor_speed_delay=10;
		   }

		 dc_motor_stop();
         for(t1_delay_time=0;t1_delay_time<4;);//加200毫秒延时
         dc_motor_f();
		 for(t1_delay_time=0;t1_delay_time<4;);//加200毫秒延时

		 motor_speed_delay=10;
		 for(t1_delay_time=0;t1_delay_time<60;)//反向加速
		   {PWM_DCMOTOR =OPEN;//电机开
            for(wqy2=0;wqy2<motor_speed_delay;wqy2++);
            PWM_DCMOTOR =CLOSE;//电机关
            for(wqy2=0;wqy2<200;wqy2++);
            motor_speed_delay+=10;
			if(motor_speed_delay>60000) motor_speed_delay=60000;
		   }
		 for(t1_delay_time=0;t1_delay_time<60;)//反向减速
		   {PWM_DCMOTOR =OPEN;//电机开
            for(wqy2=0;wqy2<motor_speed_delay;wqy2++);
            PWM_DCMOTOR =CLOSE;//电机关
            for(wqy2=0;wqy2<200;wqy2++);
            motor_speed_delay-=10;
			if(motor_speed_delay<10) motor_speed_delay=10;
		   }

		 PWM_DCMOTOR =CLOSE;//电机关
         dc_motor_stop();
         test_command=0;
		 break;
	    }
	 //-----------------------------------------
     case TEST_LCM://14
        {
		 lcm_clear_ram();
         chinese_or_character_display (tab1);//显示 "沈阳单片机开发! WWW.SYMCUKF.COM"
		 for(t1_delay_time=0;t1_delay_time<60;);//延时3秒

         lcm_clear_ram();
         chinese_or_character_display (tab3);//显示 "鑫研电子有限公司. TEL:13066554250"
         for(t1_delay_time=0;t1_delay_time<60;);//延时3秒

         lcm_clear_ram();
         image_display (Picture_kfjd);//显示图形 "开发经典"

         test_command=0;
         break;
        }
	 //-----------------------------------------
	 default:break;
	}

//-------------------------------------------------------------------------------------------------
goto wqyloop;
}//The end of main()

//##########################  主程序结束  #########################################################
//##########################  子程序开始  #########################################################

//=================================================================================================
// 函数功能:CPU初始化函数
// 串口波特率可以由T1或T2产生,本例中用T1产生波特率
// T2用于50毫秒精确定时
// T0用于PWM控制中频率的时基
//=================================================================================================
void init_cpu(void)
{ 
  TMOD=0x12;//T1为16位计数器,T0为8位自动重装载计数器

  ET1=1;
  TH1=0x4c;//11.0592M晶振时T1定时时间长度为50毫秒
  TL1=0x00;
  TR1=1;//T1开始定时

  ET0=1;//定时器T0中断允许
  TH0=0xfe;
  TL0=0xfe;
  //TR0=1;//T0开始定时,用于PWM控制

  T2CON=0x30;//定时器T2工作于波特率发生器方式
  RCAP2H=0xff;//11.0592M晶振,9600bps初值
  RCAP2L=0xdc;
  TH2=0xff;
  TL2=0xdc;
  //RCAP2H=0xfe;//11.0592M晶振,1200bps初值
  //RCAP2L=0xe0;
  //TH2=0xfe;
  //TL2=0xe0;
  TR2=1;//允许T2中断
  
  ES=1;     //串口中断允许
  PS=1;     //串口中断优先级设为高,因为要通过串口干预程序流程,为保证可靠接收所以有此设置
  SCON=0x50;//串口工作于方式1,启动串口接收

  EA=1;//CPU中断开放

  //以下是程序中软件逻辑需要的变量初值设置和硬件初始状态设置
  key_value_main=0xff;
  ctrl_74hc595(0xff);
  E_L297=0;//步进电机使能关
  PWM_DCMOTOR =CLOSE;//直流电机PWM控制端关
  dc_motor_stop();//直流电机换向继电器关
  
}
//=================================================================================================
// 74HC595实现串并转换
// 其输出允许控制端(13脚-EN)接地,表示永远允许输出
// 数据应从高位(MSB)到低位(LSB)串行送如74HC595
//=================================================================================================
void ctrl_74hc595(uchar led_display_data)//595的输出,控制8个LED
{ uchar i;
  for(i=0;i<8;i++)
    {if(led_display_data&0x80) SER_DATA_74HC595 =1;//判断数据最高位是0或1,并准备到595数据端
     else                      SER_DATA_74HC595 =0;
     CP_SR_74HC595=0;//时钟端上升沿将数据送入寄存器
     CP_SR_74HC595=1;
     led_display_data<<=1;//数据左移1位,为判断次高位做准备
    }
  CP_LA_74HC595 =0;//时钟端上升沿将寄存器中的数据送入锁存器
  CP_LA_74HC595 =1;
}
//=================================================================================================
// 以下是HD7279驱动程序
// 操作HD7279的关键是如何保证手册中给定的T1到T8这8个时间间隔
// 并且只有当HD7279的27脚外接R=1。5K、C=15P时,T1到T8才是手册中给的数值,建议不要随意改变R、C的值
// 弄清楚这个问题,则你对器件时序图的理解将上升到一个新的高度。任何器件的驱动程序只要看懂时序图就OK!
//=================================================================================================
// 函数功能:长延时,保证延时时间在50~250uS之间
void HD7279_LongDelay(void)
{ uchar i;
  for (i=0;i<30;i++);
}
//-------------------------------------------------------------------------------------------------
// 函数功能:短延时,保证延时时间在8~250uS之间
void HD7279_ShortDelay(void)
{ uchar i;
  for (i=0;i<8;i++);
}
//-------------------------------------------------------------------------------------------------
//函数功能:向HD7279写字节
void HD7279_SendByte(uchar out_byte)
{ uchar i;
  CLK_7279=0;//准备CLK脚状态
  CS_7279=0; //准备CS脚状态,置0允许操作7279
  HD7279_LongDelay();//延时T1,在带数据的命令中此延时相当于送数据之前的T4延时
  for(i=0;i<8;i++)
    {if(out_byte&0x80) DATA_7279=1;//准备数据,高位MSB先入
     else              DATA_7279=0;
	 CLK_7279=1;//CLK_7279下降沿时DATA_7279数据写入
	 HD7279_ShortDelay();//延时T2
	 CLK_7279=0;
	 HD7279_ShortDelay();//延时T3
     out_byte<<=1;//准备要写入数据的次高位
    }
}
//-------------------------------------------------------------------------------------------------
//函数功能:从HD7279读字节,只在读键值时用到
uchar HD7279_ReceiveByte(void)
{ uchar i;
  uchar in_byte;
  DATA_7279=1;//置单片机DATA_7279端为输入状态
  HD7279_LongDelay();//延时T5
  for(i=0;i<8;i++)
    {CLK_7279=1;
     HD7279_ShortDelay();//延时T7(因为T7=T6),此延时结束后HD7279_DATA数据才有效,
     in_byte=in_byte<<1;//键值的高位MSB先出,因为最低位LSB取出后不需要左移,所以有此操作
     if(DATA_7279) in_byte=in_byte|0x01;//取HD7279_DATA的数据状态,放入in_byte最低位LSB
     CLK_7279=0;
     HD7279_ShortDelay();//延时T3,这个延时手册中没有标出(因为T3>T8,所以最后1位取出后此T3相当于T8)
    }
  return (in_byte);
}
//----------------------------------------------------------------------------------------------
//函数功能:获得按键代码
uchar HD7279_GetKey(void)
{ uchar key;
  HD7279_SendByte(HD7279_READ_KEY);
  key=HD7279_ReceiveByte();
  return(key);
}
//-------------------------------------------------------------------------------------------------
// 函数功能:按方式0译码,在指定的1到8位置显示数据
// 通常情况下我们都使用方式0译码,方式1译码与之大同小异
// 形参:Position 显示位置(1-8),ShowData 数据(0-15),Have_DP 是否显示小数点(1显示,0不显示)
void HD7279_ShowData(uchar Position,uchar ShowData,bit Have_DP)
{ uchar Decode0_data;
  if(Have_DP) ShowData = ShowData|0x80;//处理小数点的显示与否
  Decode0_data=(Position-1)|HD7279_DECODE0;//将译码方式0和要显示的位置合并
  HD7279_SendByte(Decode0_data);//送命令
  HD7279_SendByte(ShowData);//送数据
  CS_7279=1;
}
//-------------------------------------------------------------------------------------------------
//函数功能:HD7279初始化,建议在工业现场干扰严重情况下,刷新显示时先执行此命令
void HD7279_Initial(void)
{
  HD7279_SendByte( HD7279_RESET );//复位
}
//=================================================================================================
// TLC5617驱动程序
// 形参:mode 工作模式、udata 10位DAC数据
//=================================================================================================
void TLC5617_Write(uchar mode,uint udata)
{  uchar i;
   uint WQY_dat;

   CS_TL5617=0;
   switch(mode)
     { case 0:WQY_dat=0x2000; break;           //掉电方式
       case 1:WQY_dat=0x8000|(udata<<2);break; //慢速,数据写入锁存器A,同时用缓冲器数据更新锁存器B
       case 2:WQY_dat=0x0000|(udata<<2);break; //慢速,数据写入锁存器B和缓冲器
       case 3:WQY_dat=0x1000|(udata<<2);break; //慢速,仅写缓冲器
       default:break;   
     }
   for(i=0;i<16;i++)//将上面生成的16位数据(包含命令及写入DA的数值)输入TLC5617
     {
       DIN_TL5617 =(bit)(WQY_dat&0x8000);//数据最高位MSB输入准备,同时也起到了延时作用
       SCLK_TL5617=1;//时钟端下降沿将数据写入
       WQY_dat<<=1;//准备数据的下一位,同时也起到了延时作用
       SCLK_TL5617=0;
     }
   SCLK_TL5617=1;
   _nop_();
   CS_TL5617=1;//CS上升沿使DA输出有效
   _nop_();
}
//=================================================================================================
// TLC2543驱动程序
// TLC2543的高8位控制字格式如下:(低8位无意义)
// D7 D6 D5 D4      D3  D2         D1              D0
// 通道选择       数据长度选择   前导选择        单双极性选择
// 0000---AIN0    01---8BIT      0---MSB first   0---Unipolar(单极性)
// 0001---AIN1    10---12BIT     1---LSB first   1---Bipolar(双极性)
// 0010---AIN2    11---16BIT
// 0011---AIN3
// 0100---AIN4
// 0101---AIN5
// 0110---AIN6
// 0111---AIN7
// 1000---AIN8
// 1001---AIN9
// 1010---AIN10
//=================================================================================================
//这个数组定义了通道状态,通过不同的数组下标可选择不同通道
//这里TLC2543的所有通道状态均定义为:
//数据长度为16BIT
//前导选择为MSB first(即高位MSB先进、先出)
//极性选择为unipolar
uchar code ad_chunnel_select[]={0x0C,0x1C,0x2C,0x3C,0x4C,0x5C,0x6C,0x7C,0x8C,0x9C,0xAC};
//-------------------------------------------------------------------------------------------------
//TLC2543操作的关键是:将16位状态及通道选择设置数据的每一位送入的同时,
//AD转换的结果数据的每一位同时输出,这一操作结束后该通道的下一次转换自动开始。
//一个隐含的问题必须注意,在TLC2543芯片通电后每个通道第一次获得的AD数据无意义。
uint ad2543_measure(uchar chunnel_select)//chunnel_select = 0 to 10
{   uint  din;
    uchar dout, i;
    din=0;
    dout=ad_chunnel_select[chunnel_select];//选择控制命令
    while(EOC_2543==0);
    CLK_2543=0;
    CS_2543=0;
    for(i=0;i<16;i++)
      {if(dout&0x80) DIN_2543=1;//控制命令从MSB-LSB,向AD发数
       else          DIN_2543=0;
       CLK_2543=1;
       dout<<=1 ;
       din<<=1 ;
       if(DOUT_2543==1) din|=0x0001;//接收AD数据,从MSB-LSB
       CLK_2543=0;
      }
    CS_2543=1;
    return (din>>4);  //因为是12位精度,而AD数据的MSB却在uint型变量din的最高位,所以右移4位
}
//=================================================================================================
// I2C总线的通用程序。包括:启动、停止、8位读、8位写、应答
//=================================================================================================
// 函数功能:I2C总线延时
// 操作I2C总线时是否需要延时需根据晶振频率,24C02的I2C总线操作频率最高为1MHz
// 如11。0592M晶振,CPU的机器周期为晶振频率的12分频,理论上可以不延时,此处加延时更可靠
void i2c_delay(void)
{ uchar i;
  for(i=0;i<8;i++);
}
//-------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

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