CCS DSP复习

中断

这是一个Cpu_timer_0的中断

void   init_xint1(void)
{
    EALLOW;                                  // This is needed to write to EALLOW protected registers
    PieVectTable.TINT0 = &cpu_timer0_isr;    // Enable CPU INT1 which is connected to CPU-Timer 0
    IER |= M_INT1;                           // Enable TINT0 in the PIE: Group 1 interrupt 7
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;       // Enable INT1.7 TINT0

    EINT;           // Enable Global interrupt INTM
    ERTM;           // Enable Global realtime interrupt DBGM
    EDIS;
}

_interrupt void cpu_timer0_isr(void){
  <这里写CPU相应Cpu_timer_0中断执行的程序>
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  //注意执行完该中断后手动复位Acknowledge位,以使其他中断能够通过。
}

让中断通过:打开中断从外设到Core的各个屏障

3级:CPU, PIE, Peripheral

CPU 12个中断 ,有使能位和标志位,使能位通过操作IER |= M_INTx 改变,这个语句代表了使能M |= M_INTx

PIE 8个子中断,有使能位和标志位,使能位通过操作这个寄存器来实现:PieCtrlRegs.PIEIER1.bit.INTx7 = 1

Peripheral 就是有些外设比较高级,自己提供了控制是否输出中断的使能控制信号。这个CPU_timer0就没有单独设置控制自己使能与否的控制信号。

有了中断执行什么?

通过操作PieVectTable这个结构体中存贮了所有中断执行的程序是什么,那么便有一个问题:怎么确定要执行的程序是什么呀?通过把中断程序的入口地址存到向量表中。那么问题又来了:入口地址是啥
呀?其实就是 &<程序的名字>

解释下上面的例子:
中断后执行的程序是这个:

_interrupt void cpu_timer0_isr(void){
  <这里写CPU相应Cpu_timer_0中断执行的程序>
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  //注意执行完该中断后手动复位Acknowledge位,以使其他中断能够通过。
}

入口地址就这么表示

 &_interrupt void cpu_timer0_isr

SPI 通信

几个寄存器

  • 缓冲寄存器(缓冲器)
    发送缓冲寄存器内存储下一个要发送的字符;接收缓冲寄存器存储下一个接收到的位;
  • 数据寄存器
    这个寄存器比较有趣,本身是一个移位寄存器,那么同时有输入和输出,所以这个是双线通信,无论主机还是从机,时时刻刻都在发送和接收。

操作模式

插播一条基础概念:数据对齐,一张图解决一切。

右对齐right-justified
左对齐left-justified


CCS DSP复习_第1张图片
image.png

SPIBBR决定传输速率。

主从工作模式

发送:将数据写在DAT寄存器中,最高位往外出。
接收:将数据写在DAT寄存器中,最低位往里面写。
所以读写使用的是同一个DAT寄存器,周而复始,生生不息。

前方有坑!!!注意

就因为发送数据是从DAT的MSB发出,接收是DAT的LSB接收,DAT是16位长的,那么如果你发送的数据的二进制形式不够16位长就要向左移位!!
eg.

xxxx xxxx xxxx xxxx   // 我是SpiaRegs.SPIDAT,16位长
// 假设我定义了一个字符 uint8_t char;
uint8_t char;
char='a';
那么发送的时候,通过配置SPICCR.
CCS DSP复习_第2张图片
image.png

一条注意:SPICLK的输入必须 C2000内部时钟频率为 OSC1CLK = 10MHz

CCS数据类型

uint<数字>_t
<数字>代表的这个数据类型所占的内存长度。

字符char 占一个字节,<数字>=8, uint8_t
整数int 占4个字节,<数字>=48=32。 uint16_t
短整形 short int占2个字节 <数字>=2
8=16 uint32_t
长整型 long int 占8个字节 <数字>=8*8=64 uint64_t

整型:

整型在内存中就是以2进制存储,所以寄存器中的数值就是整型对应的二进制值。

运算符

1111<<2 = 1100
1111 >>2 = 0011

存储的二进制数序列左移或右移,溢出的数值舍弃,空缺的数值补零。
0000 |= 1100
result: 1100
1010 |= 1100
result: 1110

老大给任务了,SPIA搞个无线通信

按照进度和问题来展开,进行的计划安排:

血的教训

学习DSP一定先搞懂基本原理,然后看带着目标去看datasheet的结构图(注意图中的寄存器)和数据流流向,然后看例程来搞懂配置寄存器的顺序。

Come on!

  1. 时钟的频率初始化在哪里,初始化的频率是多少?
    1.1 时钟的初始化在InitSysCtrl()中其中InitPLL(div,divsel)设置了OSCCLK到SYSCLKOUT的关系;其中InitPeripheralClocks()设置了,外设SYSCLKOUT到外设低速时钟LOSPCP的关系。
    1.2 SYSCLK = 60MHz ,外设时钟LOSPCP = SYSCLK / 4 = 15MHz
  2. 设置好了时钟,SPIA怎么初始化?(怎么使能,所使用的GPIO引脚,波特率,主从模式,时钟沿极性和相位,初始化设置FIFO),发送数据怎么发,怎么看接收的数据。
    2.1 例程中先设置了GPIO的复用

2.2 SPIA直接进入FIFO的初始化,里面调用了SPI的初始化程序

void
spi_fifo_init()
{
    //
    // Initialize SPI FIFO registers
    //
    SpiaRegs.SPIFFTX.all=0xC022;      // Enable FIFO's, set TX FIFO level to 2,使能中断
    SpiaRegs.SPIFFRX.all=0x0022;      // Set RX FIFO level to 2,使能中断
    SpiaRegs.SPIFFCT.all=0x00;           // FIFO发送缓冲器到移位寄存器之间的延迟为0

    SpiaRegs.SPIFFTX.bit.TXFIFO=1;                  //使能发送FIFO
    SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;     //使能发送FIFO

    //
    // Initialize core SPI registers
    //
    InitSpi();
}

SPI的初始化程序


2.2 SPIA属于外设,所有的外设都需要主动使能才能使用。

  1. 怎么发送数据?
    写数据的时候遇到了问题:怎么写一个二进制常量到寄存器中呢?C中没有二进制表示常数的形式,只有8进制0开头 eg. 0100 这是八进制 = 18^2 + 08 +0 =64; 和16进制 0x????所以写寄存器的方法是转换成16进制或者8进制,eg.要写二进制的0001就这么写:
xxxxRegs.bit.Div = 0x1;

简单做法,以16位为例来发送,然后接收到的数据进行移位。

无线射频模块AS01-ML01DP5学习记录

第一遍读数据手册

CCS DSP复习_第3张图片
image.png
CCS DSP复习_第4张图片
image.png

有用的参数:

1.9-3.6V DC供电
5V tolerant input

读datasheet

CCS DSP复习_第5张图片
image.png
  • Pin Function
    CE: 数字信号输入,使能RX/TX mode
    CSN: 片选端
    SCK: 时钟
    IRQ: 可屏蔽中断引脚

  • Limiting values 限制值,超了就烧

  • 配置方法
    这个设备非常优秀,写成了杂乱的状态机模式。


    CCS DSP复习_第6张图片
    设备状态控制图

工作模式

CCS DSP复习_第7张图片
配置工作模式

CE维持高电平10us

核心:data and control interface

CCS DSP复习_第8张图片
Interface list

注意:这个是8bit的指令集command set
3级FIFO
10Mbps SPI

有个问题:所有的控制都是有上电之后的寄存器内数值决定的,怎么修改寄存器的数值?

  1. 搞清楚原理
  2. 想法子让SPI实现

! 原理原理原理
SPI


原理

有几点注意
注意1:命令是1字节,MSB->LSB
注意2:Data bytes:可能是多个字节,写在地址位的后面。

写在寄存器P52上:
读寄存器的command
控制位1 byte:000<五位寄存器地址>

写寄存器的command
控制位1 byte:001<五位寄存器地址>

P57 Register Map上面写有寄存器的地址。尽管是Hex 2位数,但是二进制前三位都是0,所以实际上就是5位二进制数字即可。

然后根据http://www.ebyte.com/new-view-info.aspx?id=201网址中的固件编程思路来进行配置外设的寄存器即可。

内容在表格中。

配置方法:

  1. Select RX by setting the PRIM_RX bit in the CONFIG register to high. All data pipes that receive
    data must be enabled (EN_RXADDR register), enable auto acknowledgement for all pipes running
    Enhanced ShockBurst™ (EN_AA register), and set the correct payload widths (RX_PW_Px registers). Set up addresses as described in item 2 in the Enhanced ShockBurst™ transmitting payload example above.
  2. Start Active RX mode by setting CE high.
  3. After 130µs nRF24L01+ monitors the air for incoming communication.
  4. When a valid packet is received (matching address and correct CRC), the payload is stored in the
    RX-FIFO, and the RX_DR bit in STATUS register is set high. The IRQ pin is active when RX_DR is
    high. RX_P_NO in STATUS register indicates what data pipe the payload has been received in.
  5. If auto acknowledgement is enabled, an ACK packet is transmitted back, unless the NO_ACK bit
    is set in the received packet. If there is a payload in the TX_PLD FIFO, this payload is added to
    the ACK packet.
  6. MCU sets the CE pin low to enter standby-I mode (low current mode).
  7. MCU can clock out the payload data at a suitable rate through the SPI.
  8. nRF24L01+ is now ready for entering TX or RX mode or power down mode

你可能感兴趣的:(CCS DSP复习)