资讯详情

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

前言

一、实验相关电路图

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

移位寄存器-toc" style="margin-left:40px;">1.线性反馈移位寄存器

2.CC2530随机数发生器简介

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

4.实验相关寄存器

三、源码分析

四、实验结果


前言

本实验用于学习上一节CC2530芯片 本实验的目的产生随机电压后,通过串口发送到上位机显示

一、实验相关电路图

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

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

1.线性反馈移位寄存器

线性反馈移位寄存器(linear feedback shift register, LFSR)是指将输出的线性函数作为输入的移位寄存器,给定前一状态的输出。不同或操作是最常见的单比特线性函数:输入寄存器的某些位置,然后将寄存器中的每个比特整体移位。 赋给LFSR初始值称为随机种子的选择决定了输出不同的是,由于线性反馈移位寄存器的操作是确定的,寄存器生成的数据流完全取决于寄存器的当前或以前的状态,而且由于寄存器的状态有限,它必须是一个重复的循环。但通过它最初的多项式,LFSR它可以生成一个看起来随机的序列,循环周期很长触发器和几个不同的或门组成,nD触发器最多可以提供2^n-一种状态,如下图所示:

假设给定的初始值为3阶线性反馈移位寄存器SEED = (R2, R1, R0) = (1, 0, 1),所以第一阶段:R2=R1=0,R1=R0=1,R0=R1⊕R2=1...其工作流程如下:

0 1 0 1
1 0 1 1
2 1 1 1
3 1 1 0
4 1 0 0
5 0 0 1
6 0 1 0
7 1 0 1

        由上可得出:周期为2^3-1=7,其多项式对应为:

2.CC2530随机数发生器简介

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

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

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

        随机数发生器的运行是由 ADCCON1.RCTRL 位控制的。LFSR 的 16 位移位寄存器的当前值可以从 RNDH 和 RNDL 寄存器中读取。:默认操作(ADCCON1.RCTRL 是 00)是命令选通处理器每次读取随机值,就通知LFSR 一次(不展开的 13x,其中通知不展开的 13x 意味着执行 13 次反馈移位的一个操作等式) 。这保证来自 LFSR 末端的 LSB 一个新的伪随机字节的有效性。更新 LFSR的另一种方式是设置 ADCCON1.RCTRL 为 01。这将每次通知 LFSR(不展开的 13x),且当操作完成时,ADCCON1.RCTRL 位将自动清除。: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 推入,因此,不能用于随机数的产生。:LFSR 也可以用于计算一个字节序列的 CRC 值。 写入 RNDH 寄存器的操作将触发一个 CRC 计算。新的字节从 MSB 末端处理,使用一个 8x 的未展开式,此时一个新的字节可以在每个时钟周期写入到 RNDH。而在开始 CRC 计算之前,LFSR 必须通过写 RNDL 正确产生随机数。通常产生的用于 CRC 计算的种子数值应该是 0x0000 或0xFFFF。

4.实验相关寄存器

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

产生

随机数

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

ADC

ADCCON1(0xB4)—

ADC控制1

(部分)

Bit[3:2] RCTRL[1:0] 控制16位随机数发生器。当写01时,当操作完成时设置将自动返回到00。 10:保留 11:停止。关闭随机数发生器
P1.0作LED P1SEL(0xF4)

P1.7到P1.0的功能选择1:外设功能

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

端口0作外设

PERCFG(0xF1)—

外设控制

(部分)

Bit[0]

U0CFG

USART0的I/O位置

 1:备用位置2

P0.2与P0.3作

外设

P0SEL(0xF3)–

端口0功能选择

Bit[7:0]

SELP0

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

异步串行通信

U0CSR(0x86)-

USART0控制和状态

(部分)

Bit[7]

MODE

USART模式选择

0:SPI模式           

波特率

U0GCR (0xC5)–USART0通用控制

(部分)

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

Bit[7:0]

BAUD_M

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

U0UCR(0xC4)–USART0UART控制

(部分)

Bit[7]

FLUSH

Bit[6]

FLOW

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

        1:流控制使能

Bit[4]

BIT9

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

        1:9位传送

Bit[3]

PARITY

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

    1:奇偶校验使能

中断设置

UTX0IF

发送中断标志

IRCON2 Bit1

USART 0 TX中断标志

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

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

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等无线电上电的寄存器配置,是在相关教程中找的,但在技术手册中找不到,所以它的原理不是很清楚,欢迎各位来交流

标签: jqx一64m继电器2二极管a7

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台