PIC单片机实现冒泡排序算法

来源:互联网 发布:linux nano 行号 编辑:程序博客网 时间:2024/04/29 03:40
  • 编写子程序paixu,实现1Byte数的顺序排列。待排序的10个二进制数(自定义数据大小)存放在内存空间内。
  • 编写宏定义实现大小比较和换位,入口参数为待比较的两个数据地址。
  • 注意排序过程中需要使用间接寻址方式,即利用FSR和INDF两个特殊功能寄存器实现寻址操作。
  • 编写子程序,调用宏定义,使用冒泡排序算法实现排序。

1、冒泡排序算法

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

冒泡排序算法的运作如下:

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

2、编写宏定义实现大小比较与换位

程序框图PIC冒泡排序算法-比较与交换

;*****************宏定义*********************************************************compare_swap  macro  DATAI,DATAJ,TEMP   BCF      STATUS,C                ; 标志位清零MOVF     DATAJ,WSUBWF    DATAI,W                 ; 比较大小BTFSC    STATUS,C                ; TEMP1>TEMP2? GOTO     NEXT1GOTO     NEXT2     NEXT1              swap     DATAI,DATAJ,TEMP        ; 是,则交换两者的值NEXT2nop                              ; 否则,不做操作endmswap   macro   DATAI,DATAJ,TEMP    MOVF     DATAI,WMOVWF    TEMPMOVF     DATAJ,WMOVWF    DATAIMOVF     TEMP,WMOVWF    DATAJendm

进行宏指令嵌套时,要十分注意宏指令调用与子程序调用的区别,否则很容易产生错误。例如下面这段代码:

BTFSC    STATUS,C                ; TEMP1>TEMP2? GOTO     NEXT1GOTO     NEXT2     NEXT1              swap     DATAI,DATAJ,TEMP        ; 是,则交换两者的值NEXT2nop    

如不慎写作:

BTFSC    STATUS,C                ; TEMP1>TEMP2?               swap     DATAI,DATAJ,TEMP        ; 是,则交换两者的值nop                              ; 否则,不做操作

就会发生错误。

3、编写子程序,调用宏定义实现排序

子程序框图:PIC冒泡排序

;*************************子程序************************** ********************    ORG    0x0100paixuLOOP1    MOVLW  0x20    MOVWF  FSR                   ; FSR=0x20,起始位置    CLRF   COUNT2LOOP2       MOVF   INDF,W    MOVWF  DATAI    INCF   FSR,F    MOVF   INDF,W    MOVWF  DATAJ    compare_swap   DATAI,DATAJ,TEMP     MOVF   DATAJ,W               ; 数据还原    MOVWF  INDF    DECF   FSR,F    MOVF   DATAI,W    MOVWF  INDF    INCF   FSR,F    INCF   COUNT2,F              ; COUNT2++,COUNT2<9-COUNT1?    MOVF   COUNT1,W    SUBWF  SIZE,W     BSF    STATUS,C    SUBWF  COUNT2,W    BTFSS  STATUS,C       GOTO   LOOP2    INCF   COUNT1,F              ; COUNT1++,COUNT1<9?                   BSF    STATUS,C    MOVF   SIZE,W    SUBWF  COUNT1,W    BTFSS  STATUS,C    GOTO   LOOP1    NOP    RETURN;*****************************************************************************

完整程序:

list        p=16f877A            ;标明所用的处理器类型#include    <p16f877A.inc>       ;调用头文件 __CONFIG    _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF;*****************宏定义*********************************************************compare_swap  macro  DATAI,DATAJ,TEMP   BCF      STATUS,C                ; 标志位清零MOVF     DATAJ,WSUBWF    DATAI,W                 ; 比较大小BTFSC    STATUS,C                ; TEMP1>TEMP2? GOTO     NEXT1GOTO     NEXT2     NEXT1              swap     DATAI,DATAJ,TEMP        ; 是,则交换两者的值NEXT2nop                              ; 否则,不做操作endmswap   macro   DATAI,DATAJ,TEMP    MOVF     DATAI,WMOVWF    TEMPMOVF     DATAJ,WMOVWF    DATAIMOVF     TEMP,WMOVWF    DATAJendm;*****************变量定义*******************************************************DATA1    EQU    0x20             ; 待排序的数据DATA2    EQU    0x21             DATA3    EQU    0x22          DATA4    EQU    0x23             DATA5    EQU    0x24             DATA6    EQU    0x25 DATA7    EQU    0x26DATA8    EQU    0x27DATA9    EQU    0x28DATA10   EQU    0x29 SIZE     EQU    0x30             ; 待排序数据个数-1COUNT1   EQU    0x31             ; 循环变量COUNT2   EQU    0x32 TEMP     EQU    0x33             ; 临时变量 DATAI    EQU    0x34DATAJ    EQU    0x35                               ;*******************************************************************************    ORG         0x0000           ; 复位入口地址    nop                          ; 兼容ICD调试工具,必须加nop    goto        Main             ; 跳转至Main函数;*************************Main 函数的代码***************************************Main                                                   MOVLW  0x34                  ; 数据初始化    MOVWF  DATA1                    MOVLW  0x53                     MOVWF  DATA2    MOVLW  0xb5                      MOVWF  DATA3    MOVLW  0x33    MOVWF  DATA4    MOVLW  0xA1    MOVWF  DATA5    MOVLW  0x42    MOVWF  DATA6    MOVLW  0x11    MOVWF  DATA7    MOVLW  0x86    MOVWF  DATA8    MOVLW  0x65    MOVWF  DATA9    MOVLW  0x76    MOVWF  DATA10    MOVLW  .9    MOVWF  SIZE                               CLRF   COUNT1                ; 初始化循环变量    CLRF   COUNT2       CLRF   TEMP                  ; 初始化临时变量    CLRF   DATAI    CLRF   DATAJ        CALL   paixu                 ; 调用子程序排序    nop    goto   $                     ; 停机;*************************子程序************************** ********************    ORG    0x0100paixuLOOP1    MOVLW  0x20    MOVWF  FSR                   ; FSR=0x20,起始位置    CLRF   COUNT2LOOP2       MOVF   INDF,W    MOVWF  DATAI    INCF   FSR,F    MOVF   INDF,W    MOVWF  DATAJ    compare_swap   DATAI,DATAJ,TEMP     MOVF   DATAJ,W               ; 数据还原    MOVWF  INDF    DECF   FSR,F    MOVF   DATAI,W    MOVWF  INDF    INCF   FSR,F    INCF   COUNT2,F              ; COUNT2++,COUNT2<9-COUNT1?    MOVF   COUNT1,W    SUBWF  SIZE,W     BSF    STATUS,C    SUBWF  COUNT2,W    BTFSS  STATUS,C       GOTO   LOOP2    INCF   COUNT1,F              ; COUNT1++,COUNT1<9?                   BSF    STATUS,C    MOVF   SIZE,W    SUBWF  COUNT1,W    BTFSS  STATUS,C    GOTO   LOOP1    NOP    RETURN;*****************************************************************************END                              ; 程序结束
0 0