应广单片机mini-c实现插入排序并加入log打印功能

插入排序法是一种稳定排序法,在数据量不大的情况下用起来还是不错的, 比较直观,类似在打扑克的过程中,按照大小来排列手上的扑克牌。但是因为mini-c的原因,标准算法不能直接应用于应广单片机上,我就稍作修改,然后供大家参考。

在mini-c中,数组功能是弱化的,数组下标不能是变量,在新的ide版本中,我不知道数组功能是否已经可以用,我还是按照老办法,用指针实现数组功能。在排序过程中,我还加入了打印功能,方便分析和查看结果。

关于打印功能,我这里要说一下的就是,只是用来方便调试,实际芯片中是没有这个功能的,而且打印功还会影响仿真实时性,所以使用的时候要注意一下。在没有实时性要求,或是一般的数据处理中可以加入这个功能,方便查看结果。

不多说,上代码,一切尽在代码中。。。

#include "extern.h"

/*调试输出开关,关闭之后测试端口不输出了*/

#define DEBUG

/*1m 标记*/

bit msFlag;

/*us计数*/

byte ucUsCnt;

/*ms 计数*/

byte ucMsCnt;

Word Reload_T16;

/*可以用示波器观察对应端口*/

#ifdef DEBUG

bit US100_OUT :pa.7

bit MS_OUT :pa.6

bit MS10_OUT :pa.0

#endif

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

插入排序法过程,

6 in 5

5,6

5,6 in 3

3,5,6

3,5,6 in 1

1,3,5,6

1,3,5,6 in 8

1,3,5,6,8

1,3,5,6,8 in 7

1,3,5,6,7,8

1,3,5,6,7,8 in 2

1,2,3,5,6,7,8

1,2,3,5,6,7,8 in 4

1,2,3,4,5,6,7,8

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

byte ucDat[8]={6,5,3, 1, 8,7, 2,4 };//从小到大插入排序

void InserstionSort(void)

{

byte i,j;

byte ucGetDat;

byte ucTmp;

word upDat;

/*从第二个位置开始取数据*/

i=1;

while(i<8)

{

/*取得数据*/

upDat=&ucDat[0]+i;

ucGetDat=*upDat;

/*已经排好队的个数*/

j=i-1;

/*遍历已经排序的所有元素*/

do

{

/*取最后面的一个元素*/

upDat=&ucDat[0]+j;

ucTmp=*upDat;

/*如果该元素大于 新进的元素,那么*/

if(ucGetDat<ucTmp)

{

/*该元素往后挪一个位置*/

upDat+=1;

*upDat=ucTmp;

/*指针指向前一个位置,新进元素插入该元素前面*/

upDat--;

}

else

{

/*新进元素最大,在已经排好序元素的最后面*/

upDat+=1;

/*退出当前比较*/

break;

}

}

while(j--);

/*在已经腾挪好之后地方插入新进元素*/

*upDat=ucGetDat;

#if 1/******调试打印,实际应用中关闭即可************/

.printf("In=%d ",ucGetDat);

ucGetDat=0;

do

{ upDat=&ucDat[0]+ucGetDat;

ucTmp=*upDat;

.printf("sort=%d",ucTmp);

ucGetDat++;

}

while(ucGetDat<=i);

.printf("\n");

#endif

/*数据位置更新*/

i++;

}

}

/*中断服务程序*/

void Interrupt(void)

{

pushaf;

if(Intrq.T16)

{

STT16 Reload_T16;

Intrq.T16 = 0;

ucUsCnt++;

if(ucUsCnt>9)

{

ucUsCnt=0;

/*100us*10=1ms*/

msFlag=1;

}

/*100u task,紧急任务放这边,但这里的任务尽量少,

心脏部位,尽量减少干扰,需要保证tick精准*/

#ifdef DEBUG

if(US100_OUT)

{

US100_OUT=0;

}

else

{

US100_OUT=1;

}

#endif

}

popaf;

}

/*T16设置*/

Void Timer16_Init(void)

{

/*向上计数 1600就发生中断 1600/16M=0.0001s=100us,理论设计*/

//Reload_T16 = 32768 - 1600;

/*根据测算(示波器校准),除去误差(约为20个sysclk周期),设置1580这个值可能更准确,

SYSCLK越快,误差越小.从进入中断开始,到重新设置计数器,中间大概需要20个sysclk周期*/

Reload_T16 = 32768 - 1580;

/*设置计数器值*/

STT16 Reload_T16;

/*配置T16 控制寄存器*/

$ T16M IHRC,/1,BIT15;

INTRQ.T16 = 0;

INTEN.T16 = 1;

msFlag=0;

ucUsCnt=0;

}

void FPPA0 (void)

{

/*注意,修改了sysclk,Reload_T16要做细微调整,可以试着改动sysclk,

会发现Reload_T16误差变大*/

.ADJUST_IC SYSCLK=IHRC/2,IHRC=16MHz,init_ram;

/*开启看门狗*/

CLKMD.En_WatchDog = 1;

wdreset;

/*初始化T16*/

Timer16_Init();

#ifdef DEBUG

$ US100_OUT out,low;

$ MS_OUT out,low;

$ MS10_OUT out,low;

#endif

/*排序之前打印*/

.printf("old=%d,%d,%d,%d,%d,%d,%d,%d\n",ucDat[0],ucDat[1],ucDat[2],ucDat[3],ucDat[4],ucDat[5],ucDat[6],ucDat[7]);

InserstionSort();

/*排序之后打印*/

.printf("new=%d,%d,%d,%d,%d,%d,%d,%d\n",ucDat[0],ucDat[1],ucDat[2],ucDat[3],ucDat[4],ucDat[5],ucDat[6],ucDat[7]);

Engint;

while (1)

{

/*喂狗*/

wdreset;

/*1ms标记*/

if(msFlag)

{

ucMsCnt++;

if(ucMsCnt>9)

{

/*1ms*10=10ms*/

ucMsCnt=0;

/*10mstask 放这里*/

#ifdef DEBUG

if(MS10_OUT)

{

MS10_OUT=0;

}

else

{

MS10_OUT=1;

}

#endif

}

/*1ms task*/

#ifdef DEBUG

if(MS_OUT)

{

MS_OUT=0;

}

else

{

MS_OUT=1;

}

#endif

msFlag=0;

}

}

}

/*creat by zhongvv QQ85547259*/

相关推荐
Zer0_on4 小时前
数据结构栈和队列
c语言·开发语言·数据结构
一只小bit4 小时前
数据结构之栈,队列,树
c语言·开发语言·数据结构·c++
马浩同学5 小时前
【GD32】从零开始学GD32单片机 | DAC数模转换器 + 三角波输出例程
c语言·单片机·嵌入式硬件·mcu
一个没有本领的人5 小时前
win11+matlab2021a配置C-COT
c语言·开发语言·matlab·目标跟踪
一只自律的鸡6 小时前
C项目 天天酷跑(下篇)
c语言·开发语言
长安——归故李6 小时前
【C语言】成绩等级制
c语言·开发语言
青い月の魔女7 小时前
数据结构初阶---二叉树
c语言·数据结构·笔记·学习·算法
最后一个bug8 小时前
STM32MP1linux根文件系统目录作用
linux·c语言·arm开发·单片机·嵌入式硬件
FeboReigns8 小时前
C++简明教程(4)(Hello World)
c语言·c++
FeboReigns8 小时前
C++简明教程(10)(初识类)
c语言·开发语言·c++