一个小风扇,一次小实践!!

来源:互联网 发布:淘宝天天特价明日预告 编辑:程序博客网 时间:2024/04/28 04:22

    最近在将前边学的一些东西做一些强化,同时也是再一次的学习和回忆,对前期学习内容的加强和再理解,将学的东西做了一个简单整合,帮助自己的再次理解和认识,希望从中能多找到写新的体会;总体来看,其中遇到了很多的问题,不过大多数问题还是解决了,但还是存在很多的问题。

    总体的任务如下:例子分为了8个文件,分别为:TemMain.c 、I2C.h 、I2C.c 、AD.DA.h 、1602.h 、RL.c 、stepmotor.c 、Timer.c 。设想电机作为风扇的电机,其中可以通过遥控控制其中的开关和定时设定,通过AD转化模块来控制风扇的转动速度,即一般的速度调整开关,通过1602时钟来检测定时的时间。将这一些简单的工作做了一个小的整合。具体如下:

TemMain.c 文件如下;

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*--------------------------------------文件:TemMain.c-----------------------------------功能描述:主函数所在的文件,作为文件控制中心。日期:2015年3月24日人员:任长江------------------------------------------------------------------------------------------*/#include <reg51.h>#define uchar unsigned char#define uint unsigned int//引入的函数。extern Go();                  //风扇转动驱动extern ADCountrue();  //AD转化改变转速。extern lcd_init();   //LCD初始化。extern lcd_showstring(uchar ,uchar ,uchar *); //LCD显示控制extern Timing(uchar s,uchar m);   //定时控制extern uchar SpeedFlag;  //引入的变量。extern speed;extern uchar second,minute;extern uchar l_tmpdate[7];extern SetMinute; void lcd_work();  //控制LCD工作。uchar lcd_speed[] = "speed=00.00     ";  //要显示的速度。uchar lcd_time[] =  "timing=0        "; //要显示的定时时间。uchar Num = 20;void format_change(int d,uchar * a)//数据的转化,转化为LCD可以显示的数据。{*a = d + '0';}main(){//Set_RTC(); //如果用备用电池,可以不用置时间。lcd_init(); //LCD初始化。IE = 0X81; //中断配置。TCON = 0X01;SpeedFlag = 1;while(1){ADCountrue();   //做AD转化,采集速度数据。Timing(second,minute);   //定时检测。if(SpeedFlag)   //控制转动。Go();elsespeed = 0;lcd_work();//LCD显示控制。}}void lcd_work(){if(Num>=20){Num = 0;format_change(SetMinute,lcd_time+7); //显示定时。format_change(speed%10000/1000,lcd_speed+10);  //显示速度。format_change(speed%1000/100,lcd_speed+9);format_change(speed%100/10,lcd_speed+7);format_change(speed%10,lcd_speed+6);lcd_showstring(0,0,lcd_speed);lcd_showstring(1,0,lcd_time);}Num++;}</span>
I2C.h 文件如下:

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*---------------------------------------文件:I2C.h----------------------------------功能描述:为I2C调用,作为I2C所用到的函数或变量的声明。日期:2015年3月24日。---------------------------------------------------------------------------------------*/extern bit ack;//启动总线函数extern void Start_I2c();//结束总线函数extern void Stop_I2c();//应答子函数extern void Ack_I2c(bit a);//字节数据发送函数extern void SendByte(unsigned char c);//有子地址发送多字节数据函数extern bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);//无子地址发送多字节数据函数extern bit ISendStrExt(unsigned char sla,unsigned char *s,unsigned char no);//无子地址读字节数据函数extern unsigned char RcvByte();</span>

I2C.c文件如下:

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*---------------------------------------文件:I2C.c-------------------------------------功能描述:I2C总线的相关操作。日期:2015年3月24日。人员:任长江---------------------------------------------------------------------------------------*/#include <reg52.h>#include <intrins.h>#include <I2C.h>   #define _Nop() _nop_()  //空指令定义。#define uchar unsigned char #define uint unsigned intsbit SCL = P2^1;   //I2C 时钟sbit SDA = P2^0;   //I2C 数据bit ack;   //应答标志位/*-----------------------------------------------启动总线函数。功能:启动I2C总线,发送起始条件。------------------------------------------------*/void Start_I2c(){SDA = 1;//发送起始条件的数据信号。_Nop();SCL = 1;//起始条件建立延时,大于4.7us_Nop();_Nop();_Nop();_Nop();_Nop();SDA = 0; //发送起始信号。_Nop(); //起始条件锁定时间。_Nop();_Nop();_Nop();_Nop();SCL = 0; //准备发送数据。_Nop();_Nop();}/*-------------------------------------结束总线函数---------------------功能:结束I2C总线,发送结束信号。-------------------------------------------------------------------------*/void Stop_I2c(){SDA = 0;//发送结束条件数据信号。_Nop();SCL = 1;//发送结束条件的时钟信号。_Nop();//结束条件建立时间大于4us。_Nop();_Nop();_Nop();_Nop();SDA = 1; //发送I2C结束信号。_Nop();_Nop();_Nop();_Nop();}/*-------------------------------------字节发送函数--------------------功能;将数据C发送出去,可以使地址也可以使数据,发送完毕后根据应答位来做相应的操作。----------------------------------------------------------------------*/void SendByte(uchar c){uchar BitCnt;for(BitCnt=0;BitCnt<8;BitCnt++)  //要发送的数据长度8位。{if((c<<BitCnt)&0x80)  //判断发送位。SDA = 1;elseSDA = 0;_Nop();SCL = 1;  //时钟线置位,通知被控器开始接受数据位。_Nop();  //保证时钟高电平周期大于4us._Nop();_Nop();_Nop();_Nop();SCL = 0;}_Nop();_Nop();SDA = 1;   //8位数据发送完,释放数据线,准备接受应答位。_Nop();_Nop();SCL = 1;_Nop();_Nop();_Nop();if(SDA==1)   //判断是否接受到应答信号。ack = 0;elseack = 1;SCL = 0;_Nop();_Nop();}/*-----------------------------------字节数据接收函数---------------------功能:用来接收从器件传来的数据,发完后用应答函数应答从机。-------------------------------------------------------------------------*/uchar RcvByte(){uchar retc;uchar BitCnt;retc=0;SDA = 1;//数据线置位,用来接收。for(BitCnt=0;BitCnt<8;BitCnt++){_Nop();SCL=0;  //置时钟线为低,准备接受数据位。_Nop();  //低电平持续时间大于4.7us。_Nop();_Nop();_Nop();_Nop();SCL = 1;   //时钟线置位,数据线上数据有效。_Nop();_Nop();retc = retc<<1;if(SDA==1)//将读入的数据写入retc。retc=retc+1;_Nop();_Nop();}SCL = 0;_Nop();_Nop();return(retc);}/*--------------------------------应答子函数----------------功能:主控器进行应答信号。------------------------------------------------------------*/void Ack_I2c(bit a){if(a==0)  //发送应答或非应答信号。SDA = 0;elseSDA = 1;_Nop();_Nop();_Nop();SCL = 1;_Nop();_Nop();_Nop();_Nop();_Nop();SCL = 0; //时钟线清0,以便继续接受。_Nop();_Nop();}</span>

AD.DA.h文件如下;

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*-----------------------------------文件:AD-DA.c----------------------------------------功能:通过改变电位器的对应模拟输入,实现模拟输出。从而控制风扇的转速。接口为I2C总线。日期:2015年3月24日人员:任长江。----------------------------------------------------------------------------------------*/#include <reg51.h>#include <I2C.h>#define PCF8591 0x90  //PCF8591地址。#define uchar unsigned char#define uint unsigned intextern uchar  speed;uchar AD_CHANNEL;unsigned long xdata LedOut[8];uint D[5];/*---------------------------DAC转化函数--------------------------*/bit DACconversion(uchar sla,uchar c,uchar val){Start_I2c();//启动总线SendByte(sla); //发送器件地址if(ack==0)return(0);SendByte(c);//发送控制字节if(ack==0)return(0);SendByte(val);//发送DAC数据if(ack==0)return(0);Stop_I2c();//结束总线return(1);}/*---------------------------------ADC发送字节数据函数-------------------*/bit ISendByte(uchar sla,uchar c){Start_I2c();   //启动总线SendByte(sla);   //发送器件地址if(ack==0)return(0);SendByte(c);   //发送数据if(ack==0)return(0);Stop_I2c();//结束总线return(1);}/*----------------------------------ADC读字节数据----------------------*/uchar IRcvByte(uchar sla){uchar c;Start_I2c();  //启动总线SendByte(sla+1);  //发送器件地址if(ack==0)return(0);c=RcvByte();  //读取数据Ack_I2c(1);   //发送非应答位Stop_I2c();   //结束总线return(c);}void ADCountrue()  //做AD转化过程控制。{switch(AD_CHANNEL){case 0: ISendByte(PCF8591,0x41);D[0]=IRcvByte(PCF8591)*2;break;case 1: ISendByte(PCF8591,0x42);D[1]=IRcvByte(PCF8591)*2;break;case 2: ISendByte(PCF8591,0x43);D[2]=IRcvByte(PCF8591)*2;break;case 3: ISendByte(PCF8591,0x40);D[3]=IRcvByte(PCF8591)*2;break;case 4: DACconversion(PCF8591,0x40,D[4]/4);break;}D[4]=D[0];if(++AD_CHANNEL>4) AD_CHANNEL=0;if(D[0]>=47)   //通过采集的数据控制速度。speed = (int)(D[0]/10);elsespeed = 47/10;}</span>

1602.h文件如下:

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*------------------------------------文件:1602.c----------------------------------------功能说明:该文件用来驱动1602工作,用1602来显示风扇的转速和现在的温度。日期:2015年3月26日人员:任长江-----------------------------------------------------------------------------------------*/#include <reg51.h>//51寄存器文件#include <intrins.h>#define uchar unsigned char#define uint unsigned int//引脚的声明。sbit RS = P2^6;sbit RW = P2^5;sbit EN = P2^7;//函数的声明。void LCDDelay(int ms);bit lcd_bz();void lcd_wcmd(int cmd);void lcd_wdat(uchar dat);void lcd_showstring(uchar r,uchar c,uchar *str);void lcd_init();//延时函数。void LCDDelay(int ms)  {      int j;      while(ms--)      {          for(j=0;j<250;j++)          {              _nop_();              _nop_();              _nop_();              _nop_();          }      }  }    //侧忙,判断LCD是否为忙。  bit lcd_bz()  {      bit result;      RS = 0;      RW = 1;      EN = 1;      _nop_();      _nop_();      _nop_();      _nop_();      result = (bit)(P0 & 0x80);//检测P0最高位是否为1.      EN = 0;      return result;  //返回判断的结果。    }    //写命令函数。  void lcd_wcmd_8bit(int cmd)  {      while(lcd_bz());      RS = 0;      RW = 0;      EN = 0;     //先为低电平。      _nop_();      _nop_();      P0 = cmd;    //获得数据。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 1;      //将电平拉高。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 0;      //再拉低。  }      //写命令函数。  void lcd_wcmd(int cmd)  {      while(lcd_bz());      RS = 0;      RW = 0;      EN = 0;    //先为低电平。      _nop_();      _nop_();      P0 = cmd;   //获得高四位数据。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 1;     //拉高。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 0;     //再拉低。        P0 = (cmd & 0x0f)<<4;  //再获得低四位数据。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 1;      //将电平拉高。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 0;       //再拉低。  }      void lcd_showstring(uchar r,uchar c,uchar *str)  {      uchar i=0;      code uchar DDRAM[] = {0x80,0xc0};    //设定显示的位置。      lcd_wcmd(DDRAM[r] | c);      for(i=0;str[i] && i<16;i++)          lcd_wdat(str[i]);      for(;i<16;i++)          lcd_wdat(' ');  }    //数据写入的函数。  void lcd_wdat(uchar dat)  {      while(lcd_bz());      RS = 1;      RW = 0;      EN = 0;     //先处于低电平。      P0 = dat;    //获得数据高四位。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 1;      _nop_();      _nop_();      //再产生一个负脉冲。      _nop_();      _nop_();      EN = 0;        RS = 1;      RW = 0;      EN = 0;      _nop_();      _nop_();      _nop_();      _nop_();      P0 = (dat & 0x0f)<<4; //同理获得低四位。      _nop_();      _nop_();      _nop_();      _nop_();      EN = 1;      _nop_();      _nop_();      _nop_();      _nop_();      EN = 0;  }    //LCD初始化。  void lcd_init()  {      lcd_wcmd_8bit(0x38);      LCDDelay(1);      lcd_wcmd_8bit(0x38);      LCDDelay(1);      lcd_wcmd_8bit(0x38);      LCDDelay(1);      lcd_wcmd(0x38);      LCDDelay(1);      lcd_wcmd(0x0c);      LCDDelay(1);      lcd_wcmd(0x02);      LCDDelay(1);      lcd_wcmd(0x01);      LCDDelay(1);  }  </span>

RL.c文件如下:

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*------------------------------------------文件;RL.c------------------------------------功能说明:通过红外线遥控器来操作电机。日期:2015年3月23日。人员:任长江。---------------------------------------------------------------------------------------*/#include <reg51.h>#include <intrins.h>#define NOP() _nop_()#define delayNOP();{_nop_();_nop_();_nop_();_nop_();};#define uchar unsigned char#define uint unsigned intextern Read_RTC();extern l_tmpdate[7];void RLDelay(uchar x); //x*0.14MS延时。void GetTimeNow();sbit IRIN = P3^2;//红外接收器数据线。 uchar IRCOM[7];//前四个分别为:IRCOM[0]:低8位地址码 IRCOM[0]:高八位地址码 IRCOM[0]:8位数据吗  IRCOM[0]:8位数据码反码。uchar SpeedFlag;   uchar second,minute;uchar SetMinute=0;void IR_IN(void) interrupt 0    //外0中断服务,红外控制。{uchar j,k,N=0;EX0 = 0;RLDelay(15);if(IRIN==1)  //确认IRIN信号出现。{EX0 = 1;return;}while(!IRIN)  //等IRIN变为高电平,跳过9ms前导低电平。RLDelay(1);for(j=0;j<4;j++)//收集四组数据。{for(k=0;k<8;k++) //每组有8位数据。{while(IRIN) //等IRIN变为低电平,跳过4.5ms的前导高电平。RLDelay(1);while(!IRIN)  //等IRIN变为高电平。RLDelay(1);while(IRIN)  //在IRIN变为低电平之前通过N计算时长。{RLDelay(1);N++;if(N>=30){EX0 = 1;return;  //时间过长,退出。}}IRCOM[j] = IRCOM[j]>>1;  if(N>=8){IRCOM[j] = IRCOM[j] | 0x80;}//根据N的大小即时间长短来判断0或1。N=0;}//查找完1组数据。}//查找完4组数据。 if(IRCOM[2] != ~IRCOM[3])//数据码和数据反码不对应,返回。 { EX0 = 1;return; }switch(IRCOM[2]){case 0x0c: SetMinute = 1;GetTimeNow(); break;  //通过检测红外遥控的信息,做相应处理。case 0x18: SetMinute = 2;GetTimeNow(); break;case 0x5e: SetMinute = 3;GetTimeNow(); break;case 0x08: SetMinute = 4;GetTimeNow(); break;case 0x1c: SetMinute = 5;GetTimeNow(); break;case 0x5a: SetMinute = 6;GetTimeNow(); break;case 0x42: SetMinute = 7;GetTimeNow(); break;case 0x52: SetMinute = 8;GetTimeNow(); break;case 0x4a: SetMinute = 9;GetTimeNow(); break;case 0x45: SetMinute = 0;SpeedFlag=!SpeedFlag; break;  //开关控制。}EX0 = 1;}//定时控制。void RLDelay(uchar x){uchar i;while(x--){for(i=0;i<13;i++){}}}//获得时间信息。void GetTimeNow(){Read_RTC();minute = l_tmpdate[1] + SetMinute;second = l_tmpdate[0];}</span>

stepmotor.c文件如下;

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*--------------------------------------文件:stepmotor.c------------------------------功能说明:驱动电机,同时可以控制速度。日期:2015年3月23日人员;任长江---------------------------------------------------------------------------------------*//*该文件是基于四相两极式的电机。单四拍正转:A/(A非)、B、A、B/单四拍反转:B/、A、B、A/双四拍正转:A/B、AB、AB/、A/B/双四拍反转:A/B/、AB/、AB、A/B半步八拍正转:A/、A/B、B、AB、A、AB/、B/、A/B/半步八拍反转:A/B/、B/、AB/、A、AB、B、A/B/、A/UDN2916电流控制:控制电流可以控制速度。   I0I1控制输出电流00 最大10 最大*2/301 最大*1/311 0*/#include <reg51.h>#define uchar unsigned char#define uint unsigned intuchar speed; //通过控制延时时间控制速度。sbit PH1 = P1^0;   //定义各个引脚sbit PH2 = P1^1;sbit I01 = P1^2;sbit I11 = P1^3;sbit I02 = P1^4;sbit I12 = P1^5;//PH1、PH2分别控制A、B线圈电流方向(1为正向)。//I01、I11控制线圈A的电流大小。//I02、I12控制线圈B的电流大小。void SpeedDelay(int time);void Go(){//APH1 = 0;//A线圈电流反向I01 = 0;I11 = 0;//电流最大PH2 = 0;//B线圈电流反向I02 = 1;I12 = 1;//电流0SpeedDelay(speed);//0PH1 = 0;//A线圈电流反向I01 = 1;I11 = 1;//电流0PH2 = 1;//B线圈电流正向I02 = 0;I12 = 0;//电流最大SpeedDelay(speed);//BPH1 = 1;//A线圈电流正向I01 = 0;I11 = 0;//电流最大PH2 = 1;//B线圈电流正向I02 = 1;I12 = 1;//电流0SpeedDelay(speed);//0PH1 = 1;//A线圈电流正向I01 = 1;I11 = 1;//电流0PH2 = 0;//B线圈电流反向I02 = 0;I12 = 0;//电流最大SpeedDelay(speed);}//电机延时控制,通过延时可以控制转速。void SpeedDelay(int time){int i,j;for(j=0;j<=time;j++)for(i=0;i<=120;i++);}</span>

Timer.c文件如下;

<span style="font-family:KaiTi_GB2312;font-size:24px;">
/*-----------------------------------------文件:Timer.c------------------------------------功能描述;作为定时而用,通过检测1302的时间来判断时间是否到,从而控制电机的转动。日期:2015年3月28日人员:任长江-------------------------------------------------------------------------------------------*/#include <reg52.h>  #include <intrins.h> #define uchar unsigned char#define uint unsigned int extern SpeedFlag;extern SetMinute;sbit SCK = P3^6;  //时钟线  sbit IO = P3^4;   //数据线  sbit RST = P3^5;  //DS1302复位线。     //七项数据:秒分时日月周年。  uchar l_tmpdate[7] = {0,0,12,15,5,3,8};    uchar second1,minute1;  //7个数据的写地址。  code uchar write_rtc_add[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};  //7个数据的读地址。  code uchar read_rtc_add[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};    //函数的声明。  void Write_Ds1302_byte(uchar temp);  void write_Ds1302(uchar add,uchar dat);  uchar Read_Ds1302(uchar add);  void Read_RTC();  void Set_RTC();  void Timing(uchar s,uchar m);  //向1302中发送一个字节数据。  void Write_Ds1302_Byte(uchar temp)  {      uchar i;      for(i=0;i<8;i++)  //循环8位依次写入数据。      {          SCK = 0;          IO = temp & 0x01;   //传输时从低到高。          temp>>=1;   //右移1位。          SCK = 1;        }  }      //从1302中的读出数据。  uchar Read_Ds1302(uchar add)  {      uchar i,temp=0x00;      RST = 0;      _nop_();      _nop_();      SCK = 0;      _nop_();      _nop_();      RST = 1;      _nop_();      _nop_();      Write_Ds1302_Byte(add);  //发送地址,找到地址。      for(i=0;i<8;i++)   //循环8次读出数据。      {          if(IO)      //传输从低到高。              temp |= 0x80;          SCK = 0;          temp>>=1; //右移1位。          _nop_();          _nop_();          _nop_();          SCK = 1;      }      RST = 0;            //之后为DS1302复位。      _nop_();      _nop_();      RST = 0;          SCK = 0;      _nop_();      _nop_();      _nop_();      _nop_();      SCK = 1;      _nop_();      _nop_();      IO = 0;      _nop_();      _nop_();      IO = 1;      _nop_();      _nop_();      return temp;    //将读到的数据返回。  }    //从时钟中读取数据。  void Read_RTC()  {      uchar i,*p;      p = read_rtc_add;  //读日历数据对应的地址。      for(i=0;i<7;i++) //分7次分别将:时分秒日月周年读出。      {          l_tmpdate[i] = Read_Ds1302(*p);          p++;     }  }  /************************说明:在需要设定时间是加上此函数并调用。***************************//向1302中写入数据。参数有要写入的地址和数据。  void Write_Ds1302(uchar add,uchar dat)  {      RST = 0;      _nop_();      SCK = 0;      _nop_();      RST = 1;      _nop_();      Write_Ds1302_Byte(add); //发送地址。      Write_Ds1302_Byte(dat); //发送数据。      RST = 0;  }  //设定时钟的时间数据。  void Set_RTC()  {      uchar i,*p,tmp;      for(i=0;i<7;i++)   //将数从BCD码转化出来,因为1302中用BCD码表示数值。      {          tmp = l_tmpdate[i]/10;          l_tmpdate[i] = l_tmpdate[i]%10;          l_tmpdate[i] = l_tmpdate[i] + tmp*16;      }        Write_Ds1302(0x8e,0x00);  //清除写入保护。        p = write_rtc_add;      //传送地址。      for(i=0;i<7;i++)     //将数据依次写入。      {          Write_Ds1302(*p,l_tmpdate[i]);          p++;      }        Write_Ds1302(0x8e,0x80);  //打开写入保护,不能再写入。  }****************************************************************************************/void Timing(uchar s,uchar m){uchar Num=0;if(SetMinute && Num == 20)   //一段时间检测一次。{Num = 0;Read_RTC();if(l_tmpdate[1]==m && l_tmpdate[0]>=s)   //判断时间是否已经完成。{SpeedFlag = 0;//定时完成后的处理。SetMinute = 0;}}Num++;}  </span>

    收获:在其中遇到了很多问题,对其中用到的一些器件红外遥控、AD转化、LCD、I2C、步进电机等各模块做了进一步的学习和回顾,做了进一步的学习,同时认识了对单片机的操作需要注重时间的精准度,做了一定思想上的过度,提升了自己对应的操作能力;其中最重要的是自己对硬件底层的认识程度提升了,为后期学习过程做了一个小小的铺垫。由于硬件的标准是多变的,所以真正学习的并不是某一个固定的硬件资源,而是对硬件底层的知识认识学习能力,在此过程中培养自己对一个硬件资源的学习过程和流程更加重要。

    遗留问题:1、转速不稳定,用于对DS1302的读取影响电机的转速。2、速度的显示不稳定。3、编译软件问题:变量的篡改问题。

自身问题说明:从这次程序的编写过程中发现自己如下问题:1、对基础知识掌握不牢固,对一些基本的问题的解决都需要很长时间,一个牢固的基础知识是以后学习的必备条件,也是自己以后发展的一项重要条件,所以有必要再次加强一下最基础的知识。2、对硬件的运用熟练程度有待加强,虽说现在只是对硬件知识的一个初步积累,但也需要踏踏实实做好本质工作。3、编写程序走了很多大的误区,不能站在最底层的角度思考问题,导致很多问题花了很长时间。4、代码的编写规范还有待注意,代码的格式和命令问题都没有一个统一的标准,一个好的代码编写习惯将是一件非常重要的事。5、实践问题,由于条件的限制,对动手的能力锻炼很是十分有限,学习单片机十分需要动手实践,需要在后期抓住机会做一些实践性的操作。 

     如果你是单片机初学者或学习需求者,希望这些东西能对你有所帮助,也希望广大学习者或有能力的人帮助小生指出其中的错误,不胜感激!!还有很多内容需要继续学习下去,希望自己在不断的学习中能有更多的收获吧,在此谢谢广大的阅读本博客的人!!


0 0
原创粉丝点击