应广单片机实现伪随机数/M序列产生器

m序列是最长线性移位寄存器序列的简称。它是由带线性反馈的移存器产生的周期最长的序列。一般来说,一个n级线性反馈移存器可能产生的最长周期等于(2^n -1)。

m序列是一种典型的伪随机序列。在通信领域有着广泛的应用,如扩频通信、卫星通信的码分多址(CDMA),数字数据中的加密、加扰、同步、误码率测量等领域。

rand函数,C语言中用来产生一个随机数的函数。rand函数界限:stdlib.h头文件中有宏#define RAND_MAX 0x7fff, rand产生一个0-0x7fff的随机数,即最大是32767的一个数。

由于应广这种单片机资源有限,因此不支持这种stdlib.h这种库,但如果又要用到随机数怎么办呢,那就自己实现一个了。也不复杂。

不多说,上代码。

#include"extern.h"

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

#define DEBUG

/*1m 标记*/

bit msFlag;

/*us计数*/

byte ucUsCnt;

/*ms 计数*/

byte ucMsCnt;

WordReload_T16;

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

#ifdef DEBUG

bit US100_OUT :pa.7

bit MS_OUT :pa.6

bit MS10_OUT :pa.0

#endif

/*中断服务程序*/

void Interrupt(void)

{

pushaf;

if(Intrq.T16)

{

STT16Reload_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;

/*设置计数器值*/

STT16Reload_T16;

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

$ T16MIHRC,/1,BIT15;

INTRQ.T16 = 0;

INTEN.T16 = 1;

msFlag=0;

ucUsCnt=0;

}

eword ueMregInit;

byte ucFb;

#if 0

/*级数20-4000011*/

/*0b000_000_000_000_000_000_001_001反馈系数*/

#endif

void InitRand(void)

{

ueMregInit=0x012345;/*初始化,种子*/

if(!ueMregInit)

{

ueMregInit=0x012345;

}

}

/*20bit m序列,级数20-4000011*/

void Rand20(void)

{

ucFb=0;

if(ueMregInit$0.0)

{

ucFb++;

}

if(ueMregInit$0.3)

{

ucFb++;

}

ueMregInit>>=1;

if(ucFb.0)

{

ueMregInit$2.3=1;

}

else

{

ueMregInit$2.3=0;

}

}

voidFPPA0 (void)

{

.ADJUST_ICSYSCLK=IHRC/2,IHRC=16MHz,init_ram;

byte ucCnt;

byte ucTmp;

eword ucLpcnt=0;

/*开启看门狗*/

CLKMD.En_WatchDog = 1;

wdreset;

/*初始化T16*/

Timer16_Init();

/*设置一个20bit的种子*/

InitRand();

#ifdef DEBUG

$ US100_OUT out,low;

$ MS_OUT out,low;

$ MS10_OUT out,low;

#endif

Engint;

while (1)

{

/*喂狗*/

wdreset;

/*m序列运算 20bit长度,需要新的值,调用一次就行*/

Rand20();

/*可以打开查看输出指,但是会影响正常时许*/

//.printf("rand=0x%x\n",ueMregInit);

ucLpcnt++;

if(ucLpcnt==1048575)

{

/*一个周期,可以看到数据恢复到inti值*/

ucLpcnt=0;

}

/*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

wdreset;

}

/*1ms task*/

#ifdef DEBUG

if(MS_OUT)

{

MS_OUT=0;

}

else

{

MS_OUT=1;

}

#endif

msFlag=0;

}

}

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值