编程工具

在单片机编程的过程中,如果一名设计者能够同时掌握多门编程语言,那么这名设计者肯定是一位非常优秀的人才。但是想要同时精通汇编、C语言、C++这三门语言实在是太难了,很多初学者在其中一门的学习中就已经到处碰壁,苦不堪言。本文特意为大家整理了拥有嵌入式编程领域多年工作经验的工程师意见,汇总成了一篇能够对嵌入式编程经验有着指导意义的注意事项,感兴趣的朋友快来看一看吧。

在单片机嵌入式编程中,最难的两部分是interrupt和MM(memorymanage),之所以有人觉得并不困难,那是因为太多数情况下芯片制造商都已经直接写好,但是如果设计者本身就在为芯片制造商工作,那就必须自己会写配置文件。

这两个东西之所以比较难是因为要用汇编或类C来写,属于比较低层的东西,中断有外部中断和内部中断,外部中断有两种实现模式,硬件中断模式和软件中断模式,相对来说比较简单,属于应用层面的,相比之下,内部中断就要复杂得多,内部中断主要是发生重起,总线出错、溢出、校验出错等情况产生的,很多软件开发人员基本上不写对应的中断服务程序,因为它太难了而且一般也用不到。但是一旦发生,那就是致命错误,因此从整个系统健壮性来考虑必须要有相应的ISR才行,这也是freescale的专家建议的,因所以下面就谈一下嵌入式编程应该注意的问题。

延时

嵌入式编程经常会涉及到硬件的操作,如ADC,打开或者关闭一个电流源,这些都是需要时间的,因此当在发出这些指令的时候立即读取寄存器的值是得不到想要的结果的,而且还找不出原因,有时候需要的延时还比较长,达到ms级,一般情况下us级就够了,根据各芯片的时钟频率而定,不单指MCU的总线时钟频率。

变量

一般来说如果非常明确某个变量的作用域和生命周期就应该定义相对的变量,如const、static等,这样不容易出错,不建议将所有变量都定义成全局变量,这样管理起来比较麻烦,程序一旦出错,破坏性也比较大,函数也是如此,全局变量和通用函数一定要申明,这样在调用的时候不容易出错,而且有些编译器对于未申明的函数是不会报错的,但在调用的时候又会发出类型隐含转换的警告,在这里就不举例子了,总之这点要特别小心。

宏定义

在程序编写过程对于一些特定的数字应该尽量使用宏定义,这样做有个好处就是比较直观,便于日后维护,要不然时间久了看到那个数字根本就想不起它代表什么意思,宏定义并不会给程序带来任何负担,因为它在编译的时候就已经全部替代了,所以尽可以广而用之。值得一提的是宏定义并不局限于使用常量,它可以定义函数,因为它是直接替换,因此避免了入栈和出栈,提高了程序执行的效率,当时同时增加了代码量,因此一般用比较简单的函数,它还有一个缺点是在替换的过程不检查参数类型是否正常,从而增加了安全隐患,解决此问题的方法是使用一个称之为inline的内联函数,它继承了宏定义的优点,又弥补了它的缺点,是个最佳的选择,但是这个属于C++的范畴,有一定的难度,在这里也不多讲,有兴趣的朋友可以参考一下相关资料。

浮点运算

大多数低档次的单片机都是不支持浮点运算的,因此在实际使用过程中也很少用到,因此为了降低成本,一般都去掉了浮点运算模块,这就带来了一个问题,如果万一要用到浮点运算怎么办?细心的朋友可能会发现,即使不具有浮点运算的单片机在仿真调试过程依然可以使用floatordouble的数据类型进行计算,而且结果也很准确,这是为什么呢?这个因为编译器自动调用了库函数来实现的,一般是通过迭代的方法,因此它的执行效率非常慢,不建议采用此方法,而通常采用的是“定点”的方法来解决这个问题,比如说一个32bit的数据,可以假定它的低8位是小数位,然后移位计算,类似于整数运算,这种方法比较复杂,但是可以非常精确,还有一种方法就是直接放大10的N次方倍进行整数的计算,可以得出近似值,因此为了不增加不必要的麻烦,应该总是尽量避免使用浮点运算,一般情况也都是可以避免的。

watch dog

以三重watch dog为例,watch dog1检查时钟频率,watch dog2监视一小段代码,它必须在一个比较短的时间里喂一次,一般要求在250us到650us之间喂一次,watch dog3监视一大段代码,要求在比较长的时间内喂一次,一般是100ms以内,三个条件必须同时满足才行,这要求对代码的执行过程非常清楚,或者将导致喂狗出错重起。

这里需要向大家强调的是,在单片机嵌入式的编程过程中程序的好坏往往是由细节决定的,一个程序写的是否详细、灵活,是与日积月累的知识积累与实际磨练成正比的。虽然编程是意见非常枯燥甚至乏味的过程,但成功后的喜悦能够让大家相信这份付出是值得的。

文章来源:互联网

围观 377

上机1 发光二极管的闪烁

;开关断开,发光二极管灭;开关闭合,奇偶数发光二极管间隔0.1s交替点亮。

ORG 0

AJMP MAIN

ORG 0100H

MAIN: JB P3.0,DK

BH: MOV P1,#55H

ACALL YS01S

MOV P1,#0AAH

ACALL YS01S

SJMP MAIN

DK: MOV P1,#0FFH

SJMP MAIN

;延时0.1s 

YS01S: MOV R4,#100 

LOOP: MOV R3,#249 

LOOP1: NOP 
       
NOP                          

DJNZ R3,LOOP1        

NOP 
       
DJNZ R4,LOOP        

RET        

END 

上机2 秒表、倒计时 

;(1)可设置初值的秒表          

JS EQU 60

CZ EQU 0    

ORG 0000H    

AJMP MAIN  
 
ORG 0100H 

MAIN:    MOV DPTR,#TAB          

MOV R0,#CZ 

LOOP:  ACALL HBCD    

ACALL DISP    

INC R0 
   
CJNE R0,#JS,LOOP    

MOV R0,#0   
 
SJMP LOOP 
 
HBCD:    MOV A,R0          

MOV B,#10    

DIV AB    

MOV R1,A    

MOV R2,B
   
RET  

DISP:    MOV R3,#10 

LOOP3:   MOV A,R1

MOVC A,@A+DPTR          

MOV P2,A          

MOV P3,#01H    

ACALL YS50MS    

MOV P3,#0   
 
MOV A,R2 
         
MOVC A,@A+DPTR    

MOV P2,A    

MOV P3,#02H    

ACALL YS50MS    

MOV P3,#0    

DJNZ R3,LOOP3   
 
RET 
 

YS50MS:  MOV R4,#50 

LOOP1:   MOV R5,#249 

LOOP2:   NOP          

NOP    

DJNZ R5,LOOP2    

NOP 
   
DJNZ R4,LOOP1   
 
RET

;共阳数码管显示1~9的查表值   

TAB:   DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H     

END 
 
;(2)可设置初值的倒计时,最大初值99          

DJS EQU 0    

CZ EQU 10    

ORG 0000H    

AJMP MAIN   
 
ORG 0100H 

MAIN:    MOV DPTR,#TAB          

MOV R0,#CZ 

LOOP:  ACALL HBCD    

ACALL DISP    

DEC R0 
  
CJNE R0,#DJS,LOOP 
      
ACALL HBCD 

NEXT:    ACALL DISP   
 
SJMP NEXT 
 
HBCD:    MOV A,R0 

MOV B,#10

DIV AB

MOV R1,A

MOV R2,B

RET DISP:

MOV R3,#10

LOOP3: MOV A,R1

MOVC A,@A+DPTR

MOV P2,A

MOV P3,#01H

ACALL YS50MS

MOV P3,#0

MOV A,R2

MOVC A,@A+DPTR

MOV P2,A

MOV P3,#02H

ACALL YS50MS

MOV P3,#0

DJNZ R3,LOOP3

RET

YS50MS:  MOV R4,#50 

LOOP1:   MOV R5,#249 

LOOP2:   NOP          

NOP    

DJNZ R5,LOOP2    

NOP 
   
DJNZ R4,LOOP1   
 
RET 
 
;共阳数码管显示1~9的查表值  
 
TAB:   DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H  

END 

上机3 交通灯的模拟

;模拟十字路口红绿灯          

GREENL EQU 50    

GREENS EQU 6    

YELLOWS EQU 4    

ORG 0    

AJMP MAIN   
 
ORG 0100H 

MAIN:    CLR P1.1          

CLR P1.6   
 
MOV R0,#GREENL 

DXLDL:   ACALL YS05S          

DJNZ R0,DXLDL   
 
MOV R0,#GREENS 

DXLDS:   CPL P1.1          

ACALL YS05S    

DJNZ R0,DXLDS    

SETB P1.1 
  
MOV R0,#YELLOWS  

DXHDS:   CPL P1.2          

ACALL YS05S    

DJNZ R0,DXHDS   
 
SETB P1.2 

SETB P1.6

CLR P1.4

CLR P1.3

MOV R0,#GREENL

NBLDL: ACALL YS05S

DJNZ R0,NBLDL

MOV R0,#GREENS

NBLDS: CPL P1.4

ACALL YS05S

DJNZ R0,NBLDS

SETB P1.4

MOV R0,#YELLOWS

NBHDS: CPL P1.5

ACALL YS05S

DJNZ R0,NBHDS

SETB P1.5

SETB P1.3

SJMP MAIN

YS50MS: MOV TMOD,#01H

MOV TH0,#3CH

MOV TL0,#0B0H

SETB TR0 

LOOP:    JBC TF0,NEXT          

SJMP LOOP 

NEXT:  RET  

YS05S:   MOV R1,#10 

LOOP1:   ACALL YS50MS         

 DJNZ R1,LOOP1    

RET    

END 

附:带数字显示的交通灯模拟 

;模拟带数字显示的十字路口红绿灯

GREENL EQU 25

GREENS EQU 3

YELLOWS EQU 2

REDL EQU 30

ORG 0

AJMP MAIN

ORG 0100H

MAIN: MOV DPTR,#TAB

MOV P3,#0

MOV R0,#GREENL

MOV R1,#REDL

CLR P1.1

CLR P1.6

DXLDL: ACALL DISP05S

ACALL DISP05S

DEC R1

DJNZ R0,DXLDL

MOV R0,#GREENS

DXLDS: CPL P1.1

ACALL DISP05S

CPL P1.1

ACALL DISP05S     

DEC R1 
   
DJNZ R0,DXLDS    

SETB P1.1 
  
MOV R0,#YELLOWS 

DXHDS:   CPL P1.2          

ACALL DISP05S   
 
CPL P1.2 
         
ACALL DISP05S     

DEC R1 
   
DJNZ R0,DXHDS    

SETB P1.2   
 
SETB P1.6 
   
MOV R0,#REDL       

MOV R1,#GREENL       

CLR P1.4       

CLR P1.3  
  
NBLDL:   ACALL DISP05S          

ACALL DISP05S    

DEC R0 
  
DJNZ R1,NBLDL  
  
MOV R1,#GREENS 

NBLDS:   CPL P1.4          

ACALL DISP05S   
 
CPL P1.4 
         
ACALL DISP05S     

DEC R0    

DJNZ R1,NBLDS    

SETB P1.4 
  
MOV R1,#YELLOWS 

NBHDS:   CPL P1.5          

ACALL DISP05S   
 
CPL P1.5 
        
ACALL DISP05S     

DEC R0 
   
DJNZ R1,NBHDS    

SETB P1.5    SETB P1.3   

AJMP MAIN 
 
DISP05S: MOV R2,#10 

LOOP:    MOV 20H,R0  
     
ACALL HBCD 

ACALL DXDISP       

MOV 20H,R1       

ACALL HBCD       

ACALL NBDISP    

DJNZ R2,LOOP   
 
RET 
 
HBCD:    MOV A,20H          

MOV B,#10       

DIV AB       

MOV 21H,A       

MOV 22H,B  
     
RET 

;东西路口显示 

DXDISP:  MOV A,21H          

MOVC A,@A+DPTR       

MOV P2,A       

SETB P0.5      

CLR P0.4       

ACALL YS12MS5       

CLR P0.5  
     
MOV A,22H 

MOVC A,@A+DPTR      

MOV P2,A       

SETB P0.4       

CLR P0.5       

ACALL YS12MS5       

CLR P0.4  
     
RET  

;南北路口显示 

NBDISP:  MOV A,21H          

MOVC A,@A+DPTR       

MOV P3,A       

SETB P0.7       

CLR P0.6       

ACALL YS12MS5       

CLR P0.7  
     
MOV A,22H 
         
MOVC A,@A+DPTR       

MOV P3,A       

SETB P0.6       

CLR P0.7       

ACALL YS12MS5  
     
CLR P0.6 

RET            
 
;延时12.5MS 

YS12MS5: MOV TMOD,#01H          

MOV TH0,#0CFH         

MOV TL0,#2CH  
     
SETB TR0 

LOOP1:   JBC TF0,NEXT          

SJMP LOOP1 

NEXT:    RET  

;共阳极0~F的数值 

TAB:   DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H        

DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH  
   
END

来源:互联网

围观 268

页面

订阅 RSS - 编程工具