【ZIGBEE(CC2530)学习】12-CC2530基础实验——随机序列发生器配置


在这里插入图片描述

一、实验介绍

  简单来说,随机数就是一个数列,这个数列可能满足一定的概率分布,也许其满足的分布并不为我们所知。
  随机数发生器有如下功能:

  1. 产生伪随机字节,可以被 CPU 读取,或由命令选通处理器直接使用。
  2. 计算写入到 RNDH 的 CRC16 字节。
  3. 由写入到 RNDL 的值播种。

二、实验目的

  1. 通过本实验了解CC2530 的随机数发生器配置;
  2. 通过本实验了解CC2530的随机数发生器功能的运用。

三、实验设备

3.1、硬件设备

  1. ZIGBEE开发板
  2. SmartRF04EB仿真器
  3. Micro-USB线

3.2、软件环境

  1. IAR Embedded Workbench for 8051集成开发环境
  2. 串口调试助手

四、实验原理

4.1、随机发生器

  随机发生器是一个16位的LFSR(线性反馈移位寄存器),带有多项式(即CRC16)。根据执行的操作,它使用不同级别的展开值。
在这里插入图片描述
  当ADCCON1.RCTRL位置11时,关闭随机发生器。

4.2、随机发生器的运行

  随机发生器的运行由ADCCON1.RCTRL控制,LFSR的16位移位寄存器的当前值可以从RNDH和RNDL寄存器中读取。

4.2.1、伪随机序列的生成

  ADCCON1.RCTRL置00为默认操作,是命令选通处理器每次读取随机值就会通知一次LFSR。将ADCCON1.RCTRL置01也可以更新LFSR,将每次通知LFSR,当操作完成时该位自动清除。

4.2.2、种子值的产生

  计算机使用随机算法计算前需要给算法一个初始值,即种子值,算法通过对该值的运算获取随机数。
  LFSR可以通过两次写入RNDL寄存器产生种子值,每次写入,LFSR的低8位复制到高8位,低8位替换为新写入的数据。
  当需要一个真正的随机值,LFSR 应通过写入 RNDL 产生种子,随机值来自在 RF 接收路径的 IF_ADC。要使用这种产生种子的方法,无线电必须首先上电。无线电应处于无限 TX 状态,以避免 RX 状态可能的同步检测。来自 IF_ADC 的随机值从 RF 寄存器 RFRND 中读出。读出的值作为种子值写入 RNDL 寄存器,如上所述,注意这可以在为正常任务使用无线电时完成。
  种子值为0x0000或0x8003将会导致LFSR中的值通知之后不会改变,因此不能产生随机数。

4.2.3、CRC16

  计算一个字节序列的CRC(循环冗余校验)值可以用LFSR,写入RNDH寄存器将触发一个CRC计算。
  在计算CRC计算前,LFSR必须通过写入RNDL产生一个随机数,产生用于CRC计算的种子数通常为0x0000或0xFFFF。

4.3、相关寄存器

  RNDL和RNDH寄存器存放的是随机值或CRC值的结果,读取随机数时,RNDH的低8位为随机数的高8位,RNDL的低8位为随机数的低8位。
在这里插入图片描述

五、实验演示

  现在演示的是,给定一个种子值,生成随机数并在串口显示。
  首先创建rnd.c和rnd.h文件,在rnd.c文件内初始化也就是给定一个种子值,对应存入RNDH和RNDL寄存器,生成对应的随机数:

#include "headfile.h"

void rnd_init(uint16_t seed)
{
    RNDH = seed >>8;                //将种子值的高8位写入RNDH
    RNDL = seed;                    //将种子值写入RNDL
}

uint16_t getrandomnum(void)
{
    ADCCON1 |= 0x04;                //0000 0100 使能随机发生器
    uint16_t rand;
    rand = RNDH;                    //将RNDH的数据写入rand的高8位
    rand <<= 8;
    rand |= RNDL;                   //将RNDL的数据写入rand的低8位
    return rand;
}

  在main.c内调用这两个函数生成随机数,取这个数的低3位,并在串口显示该值,记得要切换时钟源为32MHz:

#include "iocc2530.h"
#include "headfile.h"

char buf[20];
void main(void)
{
    clk32m_init();
    uart0_init();
    rnd_init(0x2000);                       //给定种子值为0x2000
    //注意种子值不可为0x0000和0x8003
    uint16_t rand = getrandomnum();         //获取随机数
    buf[2] = (rand)%10 + '0';               //获取个位数
    buf[1] = (rand/10)%10 + '0';            //获取十位数
    buf[0] = (rand/100)%10 + '0';           //获取百位数
    //将整数转换为对应的字符型,只需加上'0'
    uartsendstring(buf,3);
    uartsendstring("\r\n",2);
    while(1);
}

  打开串口助手,观察现象:
在这里插入图片描述
  接下来利用无线电随机生成种子数:

void rnd_init(void)
{
    RFRND = 0x04;                   //无线电上电
    while(RFRND & 0x10);            //等待上电完毕
    RFST = 0xE2;                    //让无线电处于无限TX状态
    ADCCON1 &= ~0x0C;               //正常运行发生器
    RNDH = ADCTEST2;
    ADCCON1 |= 0x04;                //使能随机发生器
}

  每次按下按键1使能外部中断,生成一个随机数,对随机数的个位数进行对3取余并实现以下功能:
  余数为0时LED1亮,LED2灭,LED3灭;
  余数为1时LED1灭,LED2亮,LED3灭;
  余数为2时LED1灭,LED2灭,LED3亮。
  外部中断配置参考实验“4-CC2530 外部中断配置”
  通过以下程序实现:

#include "iocc2530.h"
#include "headfile.h"

char buf[20];
uint16_t rand;
void main(void)
{
    clk32m_init();
    uart0_init();
    rnd_init();
    key_init();
    led_init();
    while(1)
    {
        switch((rand%10)%3)                         //对随机数的个位数进行3取余
        {
        case 0:led_proc(1,1);led_proc(2,0);led_proc(3,0);break;
        case 1:led_proc(1,0);led_proc(2,1);led_proc(3,0);break;
        case 2:led_proc(1,0);led_proc(2,0);led_proc(3,1);break;
        default:break;
        }
    }
}

#pragma vector = P0INT_VECTOR
__interrupt void P0_int(void)
{
    if(P0IFG & 0x01)
    {
        uint8_t state=0;
        delayms(10);
        rand = getrandomnum();                      //获取随机数
        state++;
        while(KEY1 == 0);
        delayms(10);
        if(state)
        {
            buf[2] = (rand)%10 + '0';               //获取个位数
            buf[1] = (rand/10)%10 + '0';            //获取十位数
            buf[0] = (rand/100)%10 + '0';           //获取百位数
            uartsendstring(buf,3);
            uartsendstring("\r\n",2);
        }
    }
    P0IFG = 0;
    P0IF = 0;
}

  有疑问可以加入QQ群交流:324611467

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值