CC2530基础实验:(7)随机数的产生

目录

        前言

        一、实验相关电路图

        二、实验相关理论与寄存器

        1.线性反馈移位寄存器

        2.CC2530随机数发生器简介

        3.CC2530随机数发生器的运行

        4.实验相关寄存器

        三、源码分析

        四、实验结果


前言

继上一节,本实验用于学习CC2530芯片:随机数的产生
本实验主要介绍LFSR,CC2530产生随机数的过程

本实验目的:产生随机电压后通过串口发给上位机显示

一、实验相关电路图

由于发光二级管单向导电特性, 即只有在正向电压(二极管的正极接正,负极接负)下才能导通发光。P1.0 引脚接发光二极管D1的负极,所以 P1.0 引脚输出低电平 D1 亮, P1.0 引脚输出亮电平 D1 熄灭。

二、实验相关理论与寄存器

1.线性反馈移位寄存器

        线性反馈移位寄存器(linear feedback shift register, LFSR)是指,给定前一状态的输出,将该输出的线性函数再用作输入的移位寄存器。异或运算是最常见的单比特线性函数:对寄存器的某些位进行异或操作后作为输入,再对寄存器中的各比特进行整体移位。
        赋给LFSR的初始值叫做“种子”,随机种子的选择决定了输出的伪随机序列的不同,因为线性反馈移位寄存器的运算是确定性的,所以,由寄存器所生成的数据流完全取决于寄存器当前或之前的状态,并且由于寄存器的状态是有限的,其最终肯定是一个重复的循环。但通过其本原多项式,LFSR可以生成看起来是随机的且循环周期非常长的序列,其是由n个D触发器和若干个异或门组成,n个D触发器最多可以提供2^n-1个状态,如下图为例:

在这里插入图片描述

         上图为3阶线性反馈移位寄存器,假设给定初值SEED = (R2, R1, R0) = (1, 0, 1),那么第一个阶段:R2=R1=0,R1=R0=1,R0=R1⊕R2=1......其工作过程为:

阶段R2(=R1)R1(=R0)R0(=R1⊕R2)
0101
1011
2111
3110
4100
5001
6010
7101

        由上可得出:周期为2^3-1=7,其多项式对应为:G(x)=g_{3}x^{3}+g_{2}x^{2}+g_{1}x^{1}+g_{0}x^{0}=x^{3}+x^{2}+1

2.CC2530随机数发生器简介

        CC2530的随机数发生器,可以产生伪随机字节,可以被CPU读取,或由命令选通处理器直接使用;计算写入到RNDH的CRC16字节;由写入到RNDL的值播种。
        线性反馈移位寄存器(Linear Feedback Shift Register,LFSR)和循环冗余码(Cyclic Redundancy Check,CRC)是微控制器中常用的底层原理。LFSR用于生成伪随机数,后者用于生成检错码。他们的数学原理都是一样的。
        CC2530随机数发生器是一个 16 位的线性反馈移位寄存器 LFSR,带有多项式X^{16}+X^{15}+X^{2}+1(即 CRC16),显然该多项式产生的随机数最大为:2^16-1。根据执行的操作,它使用不同级别的展开值。基本的形式(不展开)如下图所示。当 ADCCON1.RCTRL=11 时,随机数发生器就关闭。


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

3.CC2530随机数发生器的运行

        随机数发生器的运行是由 ADCCON1.RCTRL 位控制的。LFSR 的 16 位移位寄存器的当前值可以从 RNDH 和 RNDL 寄存器中读取。
(1)伪随机数列的生成:默认操作(ADCCON1.RCTRL 是 00)是命令选通处理器每次读取随机值,就通知LFSR 一次(不展开的 13x,其中通知不展开的 13x 意味着执行 13 次反馈移位的一个操作等式) 。这保证来自 LFSR 末端的 LSB 一个新的伪随机字节的有效性。更新 LFSR的另一种方式是设置 ADCCON1.RCTRL 为 01。这将每次通知 LFSR(不展开的 13x),且当操作完成时,ADCCON1.RCTRL 位将自动清除。
(2)种子数的产生:LFSR 可以通过写入 RNDL 寄存器两次产生种子数。每次写入 RNDL 寄存器,LFSR 的 8 位 LSB 复制到 8 位 MSB,8 位 LSB 被替换为写入 RNDL 的新的数据字节。当需要一个真正的随机值,LFSR 通过写入 RNDL 产生种子,随机值来自在 RF接收路径的 IF_ADC。要使用这种产生种子的方法,无线电必须首先上电。无线电应处于无限 TX 状态,以避免 RX 状态可能的同步检测。来自 IF_ADC 的随机值从 RF 寄存器 RFRND 中读出。读出的值作为种子值写入 RNDL 寄存器。这可以在为正常任务使用无线电时完成。但当种子值 0x0000 或 0x8003 将总会导致 LFSR 中的值通知之后不改变,因为没有值通过 in_bit 推入,因此,不能用于随机数的产生。
(3)CRC16:LFSR 也可以用于计算一个字节序列的 CRC 值。 写入 RNDH 寄存器的操作将触发一个 CRC 计算。新的字节从 MSB 末端处理,使用一个 8x 的未展开式,此时一个新的字节可以在每个时钟周期写入到 RNDH。而在开始 CRC 计算之前,LFSR 必须通过写 RNDL 正确产生随机数。通常产生的用于 CRC 计算的种子数值应该是 0x0000 或0xFFFF。

4.实验相关寄存器

        下表中加粗部分的字是本实验配置的寄存器方法。        
        寄存器下方标有“(部分)”两字说明:本实验用到该寄存器的部分位,并不表示该寄存器只有这几位。

目的寄存器描述

产生

随机数

RNDL[7:0]

随机值/种子或CRC结果,低字节
当用作随机数产生,写入这个寄存器两次将把随机数播种到发生器。写该寄存器复制LFSR的8LSB到8MSB,并且用写入的数据值取代8LSB。
读时从该寄存器返回LFSR的8LSB。
当用作随机数产生,读这个寄存器返回随机数的8LSB。当用作CRC计算,读这个寄存器返回CRC结果。
RNDH[7:0]随机值或CRC结果/输入数据,高字节
当写的时候,将触发一个CRC16计算,写入数据值的处理开始于MSB位。
读时该寄存器返回LFSR的8MSB。
当用作随机数产生,读这个寄存器返回随机数的8LSB。当用作CRC计算,读这个寄存器返回CRC结果的8LSB。

ADC

ADCCON1(0xB4)—

ADC控制1

(部分)

Bit[3:2] RCTRL[1:0]控制16位随机数发生器。当写01时,当操作完成时设置将自动返回到00。
00:正常运行。(13X型展开)
01:LFSR的时钟一次(没有展开).
10:保留
11:停止。关闭随机数发生器
P1.0作LEDP1SEL(0xF4)

P1.7到P1.0的功能选择
0:通用I/O          1:外设功能

(由于P1.0和P1.1没有上拉/下拉功能,P1INP暂时不需要配置)

P1DIR(0xFE)P1.7 到 P1.0 的 I/O 方向
0: 输入               1: 输出

端口0作外设

PERCFG(0xF1)—

外设控制

(部分)

Bit[0]

U0CFG

USART0的I/O位置

0:备用位置1       1:备用位置2

P0.2与P0.3作

外设

P0SEL(0xF3)–

端口0功能选择

Bit[7:0]

SELP0

P0.7 到 P0.0 的功能选择
0: 通用 I / O       1: 外设功能

异步串行通信

U0CSR(0x86)-

USART0控制和状态

(部分)

Bit[7]

MODE

USART模式选择

0:SPI模式           1:UART模式

波特率

U0GCR (0xC5)–USART0通用控制

(部分)

Bit[4:0] BAUD_E波特率指数值。BAUD_E和BAUD_M决定了UART波特率和SPI的主SCK时钟频率
U0BAUD (0xC2)–
USART 0波特率控制

Bit[7:0]

BAUD_M

波特率小数部分的值。BAUD_E和BAUD_M决定了UART的波特率和SPI的主SCK时钟频率
通信设置(非必须)

U0UCR(0xC4)–USART0UART控制

(部分)

Bit[7]

FLUSH

清除单元。当设置时,该事件将会立即停止当前操作并且返回单元的空闲状态

Bit[6]

FLOW

UART硬件流使能。用RTS和CTS引脚选择硬件流控制的使用。

0:流控制禁止        1:流控制使能

Bit[4]

BIT9

UART9位数据使能。当该位是1时,使能奇偶校验位传输(即第9位)。如果通过PARITY使能奇偶校验,第9位的内容是通过D9给出的。

0:8位传送             1:9位传送

Bit[3]

PARITY

UART奇偶校验使能。除了为奇偶校验设置该位用于计算,必须使能9位模式。

0:禁用奇偶校验    1:奇偶校验使能

中断设置

UTX0IF

发送中断标志

IRCON2 Bit1

USART 0 TX中断标志

0:无中断未决       1:中断未决

缓存U0DBUFUSART0接收/发送数据缓存
种子数据来源(了解即可)

RFRND(0x61A7)–

随机数据

Bit[7:2]保留。读作0
Bit[1]-QRND接收器Q通道的随机位
Bit[0]-IRND接收器I通道的随机位

        下面为其他寄存器介绍(有点复杂,了解即可,可跳过):
        CSP允许CPU发出命令选通到无线电,从而控制无线电的操作。CSP有两种操作模式,描述如下。
        · 立即执行命令选通。
        · 执行程序
        立即命令选通被写作立即命令选通指令到CSP,立即发给无线电模块。立即命令选通指令也只能用于控制CSP。立即命令选通指令描述在19.14.8节。
        执行程序模式意味着CSP从程序存储器或指令存储器执行一系列的指令,包括一个很短的用户定义的程序。可用的指令来自一个20条指令的集合。指令集定义在19.14.8节。所需的程序首先被CPU加载到CSP中,然后CPU指示CSP开始执行程序。
        程序中不使用立即选通指令(ISxxx)情况:当这些指令写到RFST寄存器,它们被立即执行,但如果CPU已经执行了一个程序,当前指令被延迟,直到立即选通指令执行完毕。3.(2)小节中说道:要使用这种产生种子的方法,无线电必须首先上电。无线电应处于无限 TX 状态,以避免 RX 状态可能的同步检测。所以要一直维持TX状态,禁止其他程序执行。当RFST写入0xE2时,CPU就会执行0xE2对应的指令集中的子指令——ISSTOP,该指令会停止CSP程序执行,且声明IRQ_CSP_STOP中断标志。

寄存器描述

RFST(0xE1)–RFCSMA-CA/选通处理器

Bit[7:0]写入该寄存器的数据被写到CSP指令存储器。读该寄存器返回当前执行的CSP指令。

三、源码分析

/****************************************************************************
* 文 件 名: main.c
* 描    述: 产生10V以内的两位小数的随机电压发送给上位机显示
****************************************************************************/
#include <ioCC2530.h>

#define uchar unsigned char  //宏定义uchar为unsigned char
#define uint unsigned int    //宏定义uint为unsigned int
#define LED P1_0             //宏定义LED为P1_0脚
uint Random=0;
char Rand_data[6]="0.00V ";    //定义串口数组,用来存储自定义发送的电压

void Init_LED();             //声明LED 初始化函数
void Init_UART0();           //声明串口0初始化函数
void UR0_SendString(char *str,char len);//声明字符串发送函数
void LED_RUN();              //声明LED闪烁函数
void Delay(uint ms);         //声明延时函数
void Init_RandomGenerator(void);      //声明随机数产生函数
/*======================主程序入口==================*/
void main(void)              
{ 
  uint Data_H,Data_L;
  CLKCONCMD &= ~0x40;               //设置系统时钟源为32MHZ晶振
  while(CLKCONSTA & 0x40);          //等待晶振稳定为32M
  CLKCONCMD &= ~0x47;   
  
  Init_RandomGenerator(); //初始化随机数发生器
  Init_LED();                //LED 初始化
  Init_UART0();              //串口0初始化
  
  while(1)                   //一直执行
  {
    //更新LFSR    
    ADCCON1 |= 0x04;
                
    Data_H=RNDH;  //读相关寄存器
    Data_L=RNDL;
    Random = (((uint)Data_H << 8) | Data_L);//获取随机数,最大为2^16-1=66535
    
    Rand_data[0]=(char)(Random)%10+'0';   //取随机数的个位
    Rand_data[2]=(char)((Random)/10)%10+'0';//取随机数的百位
    Rand_data[3]=(char)((Random)/100)%10+'0';//取随机数的千位
    //下方4行是16进制数转化存储,数组的一位存放2位16进制数字;接收端需支持16进制接收
    //Rand_data[0]=(char)(Random/4096);   
    //Rand_data[1]=(char)((Random%4096)/256);
    //Rand_data[2]=(char)(((Random%4096)%256)/16);
    //Rand_data[3]=(char)(((Random%4096)%256)%16);
    UR0_SendString(Rand_data,6);//将结果通过串口发送给上位机
    LED_RUN();//发送完一次LED状态改变一次
    Delay(1000);//延时一段时间
  }
}

void Delay(uint ms)             //ms级延时函数
{
  uint i,j;
  for(i=0; i<ms; i++)
    for(j=0; j<535;j++);
}
void Init_LED()            //初始化LED 
{
  P1SEL &= ~0x01;          //LED P1.0为普通IO口
  P1DIR |= 0x01;           //LED P1.0为输出
  LED = 0;                 //LED P1.0 置低
}
void LED_RUN()
{
  LED ^=1;//LED状态改变
}
void Init_UART0()
{
  PERCFG = 0x00;     //选串口0的备用位置1;即(P0.2和P0.3)
  P0SEL |= 0x0c;     //将P0_2和P0_3管脚设置成外设功能
  U0CSR |= 0x80;     //1: UART模式
  U0BAUD |= 216;     //查手册,配置为115200波特率=
  U0GCR |= 11;      
  U0UCR |=0x80;      //禁止流控,无校验,8位数据,1位停止位,清除缓冲器
  UTX0IF = 0;        //串口0发送中断标志位清零
  EA = 1;            //开总中断
}
void UR0_SendString(char *str,char len) //字符串发送
{
  while(len--)
  {
    U0DBUF = *str++;//将要发送的1字节数据写入U0DBUF数据缓冲区
    while(!UTX0IF); //等待数据发送完成
    UTX0IF = 0;     //TX中断标志位清零,以便下一次发送
  }
}
void Init_RandomGenerator(void) //随机数产生
{  
   /*当需要一个真正的随机值,LFSR 应通过写入RNDL 产生种子,
     随机值来自在RF 接收路径的IF_ADC。要
     使用这种产生种子的方法,无线电必须首先上电*/
    RFRND = 0x04;
    
   // 等待上电完毕
    while( RFRND & 0x10 );
    
   //无线电应处于无限TX 状态,以避免RX 状态可能的同步检测
    RFST = 0xE2;
    Delay(1);

    /*RCTRL[1:0]---控制16 位随机数发生器
      [00:] 正常运行。(13X 型展开)*/
    ADCCON1 &= ~0x0C;   

    RNDH = ADCTEST2;

    /*更新LFSR 的一种方式是设置ADCCON1.RCTRL 为01。
      [01:] LFSR 的时钟一次(没有展开).*/
    ADCCON1 |= 0x04;
}

四、实验结果

        如下图所示,CC2530串口发送0—10V以内的两位小数的随机电压,在上位机显示:


 问题:

        关于程序中RFRND=0x04等无线电上电的寄存器配置,是在相关教程中找的,但在技术手册中找不到,所以它的原理不是很清楚,欢迎各位来交流

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值