电工技术基础_电工基础知识_电工之家-电工学习网

欢迎来到电工学习网!

单片机开发中的一些有用诀窍

2017-03-24 12:18分类:PLC基础知识 阅读:

 

 许多兄弟正在学习单片机开发技能,但开发中免不了要碰到这么、那样的疑问,有些疑问或许无碍全局,但有一些疑问却直接影响到商品的本钱、体积、功用。这儿介绍笔者的几个诀窍,期望对咱们的作业有帮忙。

  一.C言语中嵌入汇编言语

  单片机开发中,通常咱们运用C言语编写主程序,这么可以充沛凭借C言语东西供应的运算库函数及健壮的数据处理才华。但C言语的可控性不及汇编言语,在有些对时序恳求严峻的处理上,咱们还需用活络性更强的汇编言语来编写。上海AVR单片机操练这么就发作了C言语和汇编言语混合编程的疑问,通常分红三种办法:1.汇编言语调用C言语函数;2. C言语调用汇编言语;3. C言语中嵌入汇编言语。这儿咱们首要介绍第3种,即C言语中嵌入汇编言语。

  下面的一段程序是主程序调用准确的205μS延时子程序并使P1.0更换输出高、低电平的方波。

  /*------------程序名test.c------------*/

  #include P 晶振频率12.000MHz<>

  /****************/

  void delay(void)//延时205μS

  {

  #pragma asm

  MOV R0,#100

  LOOP:

  DJNZ R0,LOOP

  #pragma endasm

  }

  /***************/

  void main (void)//主函数,其功用使P1.0更换输出高、低电平的方波

  {

  while(1)

  {P1_0=!P1_0;

  delay();}

  }

  详细完毕进程为:

  1.先用汇编言语编制一段延时程序,在keil开发环境中编译,然后进行软件仿真,晶振频率的设置应和你的恳求相符。仿真时留心查询左面寄存器窗口内的时刻显现,调整延时程序的参数可得到咱们需求的准确延时。

  2.用C51编写主程序及延时子程序的外壳(等候嵌入汇编言语),假定此程序称谓为test.c。

  3.将第1步所得的汇编延时子程序放入C51编写的延时子程序外壳中。留心在开端及完毕时别离加上#pragma asm、#pragma endasm句子,这种办法是经过asm与endasm通知C51编译器,基地行不必编译为汇编行。

  4.依照Keil的运用办法,树立工程文件并增加源程序。

  5.点击富含汇编程序的C源程序后再右击,在弹出的下拉菜单中选中Options for File ‘test.c’(图1),这时呈现图2所示的界面,勾选Generate Assembler SRC File(生成汇编SRC文件)及Assembler SRC File(封装汇编文件)使其有用。

  6. 依据项意图编译办法加载封装库文件,通常在Small办法时为C51S.LIB(该文件在C:KeilC51LibC51S.LIB),详细见图3。

  7.点击Rebuild target(重建悉数方针文件)即可得到编译效果(图4)。

  

  图1

  

  图2

  

  图3

  

  图4

  二。用软件拓宽外部接连

  咱们知道,51单片机的外部接连只需2个,书本上曾介绍了一种拓宽外部接连源的办法,可是需增加硬件开支(见图5)。经或非门引进外接连源输入端(/INT0或/INT1),一同又连到某I/0口。这么,每个“源”都或许致使接连,在接连效劳程序中经过软件查询便可断定哪一个是正在恳求的接连源,其查询的次第则由接连源优先级抉择,这就可完毕多个外部接连源的拓宽。

  

  图5

  这种办法虽然拓宽了外部接连源,但也有不尽人意的本地,如计划一个具有8个接连源的电路,则需一个8输入端的或非门(或门),显着,对体积与本钱都晦气。这儿介绍笔者计划的拓宽外部接连源的办法,由纯软件完毕,不增加一个元件(见图6)。

  

  图6

  #include < P>

  static unsigned char data m;//m为全局变量

  /*-------延时子程序-------*/

  void delay(unsigned int k)

  {

  unsigned int i,j;

  for(i=0;i

  for(j=0;j<121;j++)

  {;}}

  }

  /*---外部接连INT0子程序---*/

  void init0()interrupt 0

  {

  delay(10);//延时10mS抗哆嗦搅扰

  if(P3_2==0)

  {

  EX0=0;//关INT0接连

  EA=0;//关总接连

  P3_2=0;//置P3.2为低电平

  P2=0xff;//置P2口为全1

  m=P2;//读取P2口状况至m

  P2=0x00;//康复P2口为全0

  P3_2=1; //置P3.2为高电平

  IT0=1;//置INT0为边际触发

  EX0=1; //开INT0接连

  EA=1;} //开总接连

  }

  /********主程序*********/

  void main(void)

  {

  P2=0x00;// 置P2口为全0

  P3_2=1;// 置P3.2为高电平

  IT0=1;// 置INT0为边际触发

  EX0=1;// 开INT0接连

  EA=1; //开总接连

  while(1)//无限循环

  {

  P0=m;//将全局变量m中的内容输出至P0口

  P3_0=!P3_0;//P3.0取反,指示程序状况

  delay(500);//延时500mS

  }

  }

  程序解说:无按键按下时,P3.0的发光管闪亮,作程序状况显现。主程序初始化时,置P2口为全0,置P3.2为高电平,一同置INT0为边际触发,并翻开接连。8个按键的任一个按下时都会致使INT0接连,进入接连效劳子程序后,首要封闭接连,然后置P3.2为低电平,置P2口为全1,再读取P2口状况至m,经过查询m的状况字即可知道正在恳求的接连源。这儿咱们选用的办法是将m输出至P0口点亮LED作指示。退出接连时,从头翻开接连。

 二。库函数的生成

  当将自个开发的程序供应给别人运用但又不方便利当当利揭露源代码时,把源代码做成库函数是一种可行的办法,这么可以维护自个的常识产权及利益,这儿咱们介绍生成库函数的办法及运用。

  /*------------程序名test1.c------------*/

  void delay(unsigned int k)

  {

  unsigned int i,j;

  for(i=0;i

  for(j=0;j<121;j++)

  {;}}

  }

  1.依照keil的运用办法,树立工程文件test1.uv2并增加上面的源程序test1.c。

  2.点击工程,在弹出的下拉菜单中点Options for Target ‘Target 1’,在Output 页面中,选中“Create Library:”后进行编译,则在指定的途径上生成与项目同名的“Lib”文件(图1)。需留心的是,存储办法(Large或Small)应与所运用的体系设置一样。

  

  图1

  3.%20树立另一个工程文件test2.uv2。

  /*------------程序名test2.c------------*/

  

  图2

  5. 点击Rebuild target(重建悉数方针文件)即可得到编译效果(图3)。

  

  图3

  三。批改Startup.a51开端代码

  单片机作业进程中免不了受搅扰,有时或许会构成死机,咱们可以运用“看门狗”来复位偏重启单片机。依据笔者的阅历,这时的内存区数据或许不必定会悉数冲垮,首要是PC指针紊乱所为。上海模仿电路/数字电路操练但运用C51编写的程序在复位后会施行一段Startup.a51“开端代码”,致使内存悉数清零,使正在作业的数据悉数扔掉。处理这一疑问的办法是批改Startup.a51“开端代码”,本刊本年1月的文章<谈谈C言语在单片机开发中的运用>也谈到这个疑问,但许多读者在keil集成开发环境中不知怎样做?这儿咱们经过一个实验程序来详解一下,实验选用<手把手教你学单片机>讲座的S2实验板(S2板的电路原理见2003年2月号<电子制造>)。

  /*------------程序名test3.c------------*/

  #include P 晶振频率11.0592MHz<>

  #define uchar unsigned char

  #define uint unsigned int

  uchar code DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,//0~9数码管字形码

  0x92,0x82,0xF8,0x80,0x90};

  uchar data counter1, counter2;//界说两个软件计数器

  void delay(uint k) //延时子程序

  {

  uint i,j;

  for(i=0;i

  for(j=0;j<121;j++)

  {;}}

  }

  void main(void) //主程序

  { delay(1); //延时1mS

  while(1) //无限循环

  {

  if(counter1==counter2)//如两个计数值持平

  {P0= DATA_7SEG[counter1];//输出至P0口显现

  delay(500); //延时500mS

  counter1++;counter2++;//计数值递加

  if(counter1>=10){ counter1=0;counter2=0;}//计数值在0~9循环

  }

  else

  { counter1=0xff;counter2=0xff;//不然计数值置0xff

  //…………犯错处理

  }

  }

  }

  1.依照keil的运用办法,树立工程文件test3.uv2并增加上面的源程序test3.c。在Output 页面中,勾选树立hex文件。

  2.点击Rebuild target(重建悉数方针文件)可得到编译效果。

  3. 编译通往后,将生成的test3.hex文件烧录到单片机89C51中,将89C51芯片刺进到S2型实验板上,通电作业后,右边的数码管从0至9开端循环显现。显现到某个数(例如5)时,按一下RESET键,右边的数码管又从0至9开端循环显现。 这是因为带电复位(热主张)时,C51施行了一段“开端代码”,将内存的128个单元悉数清零,致使计数值(例如5)扔掉。

  处理的进程如下:

  4.点击“文件”,鄙人拉菜单中挑选“翻开”,在弹出的搜索途径中,挑选C:KeilC51LibStartup.a51后翻开,可见到如下代码:

  ………………………………………………………………………………………………

  ………………………………………………………………………………………………

  IDATALEN EQU 80H ; the length of IDATA memory in bytes.

  ;

  XDATASTART EQU 0H ; the absolute start-address of XDATA memory

  XDATALEN EQU 0H ; the length of XDATA memory in bytes.

  ;

  PDATASTART EQU 0H ; the absolute start-address of PDATA memory

  PDATALEN EQU 0H ; the length of PDATA memory in bytes.

  ………………………………………………………………………………………………

  ………………………………………………………………………………………………

  咱们将IDATALEN EQU 80H ; the length of IDATA memory in bytes.改为IDATALEN EQU 00H ; the length of IDATA memory in bytes.然后保留封闭。

  5. 将Startup.a51增加到test3.uv2工程中(图4)。

  

  图4

  6. 点击Rebuild target(重建悉数方针文件)可得到编译效果。

  7. 将生成的test3.hex文件再烧录到单片机89C51中,将89C51芯片刺进到S2型实验板上,通电作业后,右边的数码管从0至9开端循环显现。显现到5时,按一下RESET键,右边的数码管从5起持续计数显现(留心:这次不是从0开端),完毕了热主张后的持续计数功用。

  这种技能十分有用,如因搅扰等要素致使“看门狗”动作后(即热主张),不会将正本正在处理的数据扔掉,然后可持续作业下去。或许有的读者会问,一旦搅扰冲垮了数据,那么持续作业的这些数据或许是过错的,岂不是错上加错。关于这个疑问,咱们可采纳数据冗余的办法,如正在计数的值由两个内存单元保留(例如本例中的counter1与counter2),运用时两个内存单元数据进行比照,一旦不等阐明搅扰损坏了数据,可进行犯错处理,不然可以为数据准确有用。

  四。必定地址拜访

  单片机体系作业进程中的抗搅扰才华巨细对错常首要的,抗搅扰才华强的单片机可在凌乱的工业环境中正常作业。而抗搅扰才华差的单片机,轻者体现为作业异常多,作业功率低下,重者底子不能作业,常常死机。上海AVR单片机操练因而一个单片机体系计划的好坏,与其抗搅扰才华的巨细有直接的联络。

  为了前进RAM区数据的牢靠性,咱们可在两个相隔较远的RAM单元(如20H、75H等)树立两个象征flag1、flag2,初始化时写入象征字(如88H),取用RAM数据时首要比照两个象征是不是持平,若不等阐明RAM区数据或许犯错,此刻程序跳转到犯错处理子程序,不然正常施行。这种办法使得程序施行时的数据牢靠度较高。上海FPGA/CPLD操练这牵涉到C言语中的必定地址拜访,下面介绍三种办法。

  1.运用_at_要害字

  其用法较简略,在数据声明后直接加上_at_及地址常量即可。但运用时应留心,必定地址变量不能被初始化,bit型函数及变量不能用_at_指定。

  例1:

  #include < P>

  static unsigned char data flag1 _at_ 0x0020;//将两个象征定坐落20H、75H

  static unsigned char data flag2 _at_ 0x0075;

  /******************/

  void main()

  {

  //进入主程序初始化时将flag1、flag2置为0x88

  flag1=0x88; flag2=0x88;

  while(1)

  {

  if((flag1==0x88)&&(flag2==0x88))//象征持平

  {//正常作业进程}

  else

  {//犯错处理}

  }

  }

  2.运用指针的办法

  例2:

  #include < P>

  char data *point1;//界说两个指向data区的指针

  char data *point2;

  /******************/

  void main()

  {point1=0x20;point1=0x75;//指向20H、75H单元

上一篇:单片机操控步进电机失步要素剖析

下一篇:单片机的作业原理

相关推荐

电工推荐

    电工技术基础_电工基础知识_电工之家-电工学习网
返回顶部