前言:
SPI是最常见的串行通讯之一,其通信速率比较高,适合需要传输大量数据的应用。常见的有SPI FLASH,无线模块等。这里IIC的具体原理讲解就不做介绍,不清楚的朋友可移步up主的个人专栏 ---- “串行通讯原理”中的“串行通讯 -- SPI通讯原理”,此专栏会有针对SPI的工作原理的详细介绍。
CSIH 寄存器基地址
Base Address Name | Base Address |
<CSIH0_base> | FFD8 0000H |
<CSIH1_base> | FFD8 2000H |
<CSIH2_base> | FFD8 4000H |
<CSIH3_base> | FFD8 6000H |
CSIH 时钟源选择
Unit Name | Unit Clock Name | Supply Clock Name | Description |
CSIHn | PCLK | CKSCLK_ICSI | 通讯时钟 |
寄存器访问时钟 | CPUCLK2 | 总线时钟 | |
寄存器访问时钟 | CKSCLK_ICSI | 总线时钟 |
CSIH 功能描述
1、三线串行同步数据传输
2、可选择主模式或从模式
3、有8个可配置的芯片选择输出信号,可实现多个从机配置和RCB(广播的隐性配置)
可用从选择输入信号(CSIHTSSI)
4、内置波特率发生器
5、发送时钟频率在主机模式下可调,而它是由从机控制模式下的输入时钟决定的。
6、最大传输时钟频率:
-主模式:10.0 MHz(然而,它必须等于或低于PCLK/4)
-从模式:5.0 MHz(然而,它必须等于或低于PCLK/16)
7、时钟相位和数据相位是可选的
8、可选择MSB优先或LSB优先进行数据传输
RIIC 接口框图
1.1、CSIHnCTL0 — CSIHn控制寄存器0
Bit position | Bit Name | Function |
7 | CSIHnPWR | 控制操作时钟。 0:停止运行时钟。 1:开始运行时钟。 清除CSIHnPWR来复位内部电路,停止操作并设置 CSIH进入待机状态,内部电路的时钟供应停止。 如果通信过程中CSIHnPWR被清除,则正在进行的通信立即中止。在这种情况下,通信设置必须重新配置。 |
6 | CSIHnTXE | 启用/禁用发送。 0:禁止发送。 1:开启发送。 |
5 | CSIHnRXE | 启用/禁用接收。 0:禁用接收。 1:开启接收。 |
1 | CSIHnJOBE | 在当前作业结束时停止通信(如果data通信结束当CSIHnTX0W.CSIHnEOJ = 1。 0:允许通信。 1:停止通信。 |
0 | CSIHnMBS | 为传输/接收数据绕过内存。 0:内存模式 CSIH存储器用于传输/接收数据。 1:直接接入方式 CSIH内存被绕过。 |
1.2、CSIHnCTL1 — CSIHn控制寄存器1
Bit position | Bit Name | Function |
24 | CSIHnSLRS | 设置接收数据同步时间。 0: PCLK的上升边缘 1: PCLK的下降边缘 |
18 | CSIHnPHE | 设置cpu控制的优先级通信功能。 0:关闭cpu高优先级通信功能。 1:开启cpu高优先级通信功能。 |
17 | CSIHnCKR | 时钟反转函数 0: CSIHTSCK默认级别为高 1: CSIHTSCK默认级别为低 |
16 | CSIHnSLIT | 选择中断INTCSIHTIC的时间。 0:正常中断定时(传输后产生中断) 1:一旦CSIHnTX0W/H寄存器的内容被转移到移位寄存器,产生一个中断(此函数仅在直接访问模式/仅发送缓冲模式)。 |
15 - 8 | CSIHnCSLx | 选择芯片选择信号x (CSIHTCSSx)的有效输出电平。 0:芯片选择处于低激活状态。 1:芯片选择处于高激活状态。 |
7 | CSIHnEDLE | 启用/禁用扩展数据长度(EDL)模式。 0:禁用扩展数据长度模式。 1:启用扩展数据长度模式。 |
6 | CSIHnJE | 启用/禁用作业模式。 0:禁用作业模式。 1:启用作业模式。 |
5 | CSIHnDCS | 启用/禁用数据一致性检查功能。 0:禁用数据一致性检查。 1:表示开启数据一致性检查。 |
4 | CSIHnCSRI | 定义最后一次数据传输后的芯片选择信号行为。 0:芯片选择信号保持激活电平。 1:芯片选择信号返回到非激活状态。 |
3 | CSIHnLBM | 控制回环模式(LBM)。 0:关闭回环模式。 1:开启回环模式。 |
2 | CSIHnSIT | 选择中断延迟模式。 0:表示不产生时延。 1:所有中断都产生半时钟延迟。 |
1 | CSIHnHSE | 启用/禁用握手功能。 0:关闭握手功能。 1:开启握手功能。 |
0 | CSIHnSSE | 启用/禁用从选功能。 0:关闭输入信号CSIHTSSI。 1:识别输入信号CSIHTSSI |
1.3、CSIHnCTL2 — CSIHn控制寄存器2
Bit position | Bit Name | Function | ||||
15 - 13 | CSIHnPRS | 这些位选择操作模式和参考时钟值 | ||||
CSIHnPRS2 | CSIHnPRS1 | CSIHnPRS0 | 选择参考时钟 | |||
0 | 0 | 0 | PCLK(主模式) | |||
0 | 0 | 1 | PCLK/2(主模式) | |||
0 | 1 | 0 | PCLK/4(主模式) | |||
0 | 1 | 1 | PCLK/8(主模式) | |||
1 | 0 | 0 | PCLK/16(主模式) | |||
1 | 0 | 1 | PCLK/32(主模式) | |||
1 | 1 | 0 | PCLK/64(主模式) | |||
1 | 1 | 1 | 通过外部时钟CSIHTSCK(in) |
1.4、CSIHnCFGx — CSIHn 配置寄存器x
Bit position | Bit Name | Function | ||||
31 - 30 | CSIHnBRSSx | 这些位选择波特率设置寄存器(CSIHnBRSy) | ||||
CSIHn BRSSx1 | CSIHn BRSSx0 | 波特率设置寄存器选择 | ||||
0 | 0 | 传输时钟频率由CSIHnBRS0设置 | ||||
0 | 1 | 传输时钟频率由CSIHnBRS1设置 | ||||
1 | 0 | 传输时钟频率由CSIHnBRS2设置 | ||||
1 | 1 | 传输时钟频率由CSIHnBRS3设置 | ||||
29 - 28 | CSIHnPSx | 选择发送或接收芯片选择信号x的奇偶校验 | ||||
CSIHn PSx1 | CSIHn PSx0 | 发送 | 接收 | |||
0 | 0 | 不发送任何奇偶校验位 | 不接收任何奇偶校验位 | |||
0 | 1 | 添加一个固定为0的奇偶校验位 | 等待奇偶校验位接收但不计算 | |||
1 | 0 | 添加奇偶校验位 | 等待奇偶校验位 | |||
1 | 1 | 添加偶校验位 | 等待偶校验位 | |||
27 - 24 | CSIHnDLSx | 选择芯片选择信号x的数据长度 | ||||
CSIHnDLSx | 数据长度 | |||||
0000B | 16 bits | |||||
0001B | 1bits | |||||
0010B | 2bits | |||||
... | ... | |||||
1111B | 15bits | |||||
19 | CSIHnRCBx | 为芯片选择信号x广播的隐性配置。 0:占优(优先级更高) 1:隐性(低优先级) | ||||
18 | CSIHnDIRx | 选择芯片选择信号x的串行数据方向 0:先通过MSB发送/接收数据 1:先通过LSB发送/接收数据 | ||||
17 | CSIHnCKPx | CSIHnCKPx:时钟相位选择位 | ||||
16 | CSIHnDAPx | CSIHnDAPx:时钟相位选择位 | ||||
15 | CSIHnIDLx | 为芯片选择信号x选择空闲配置 0: 设置CSIHnTX0W..CSIHnCSx 为两个不同的连续传输,在两次传输之间插入一个空闲状态。如果CSIHnTX0W..CSIHnCSx两个连续传输的CSIHnTX0W..CSIHnCSx设置是相同的,在两个传输之间不插入空闲状态。 1: 不考虑CSIHnTX0W..CSIHnCSx设置两个连续的传输,在两个传输之间插入一个空闲状态。 | ||||
14 - 12 | CSIHnIDx | 选择芯片选择信号x的空闲时间 | ||||
11 - 8 | CSIHnHDx | 指定在传输时钟周期中芯片选择信号x的保持时间 | ||||
7 - 4 | CSIHnINx | 指定传输时钟周期中芯片选择信号x的数据间时间 | ||||
3 - 0 | CSIHnSPx | 指定传输时钟周期中芯片选择信号x的设置时间 |
例程:
/******************************************************************************
** Function: R_CSIH3_Init
** Description: This function initializes the CSIH3 module.
** Parameter: None
** Return: None
******************************************************************************/
void spi_CSIH3_Init (void)
{
unsigned int tmp_port;
/* Disable CSIH3 operation */
CSIH3.CTL0 = _CSIH_OPERATION_CLOCK_STOP;
/* Disable INTCSIH3IC operation and clear request */
INTC2.ICCSIH3IC.BIT.MKCSIH3IC = _INT_PROCESSING_DISABLED;
INTC2.ICCSIH3IC.BIT.RFCSIH3IC = _INT_REQUEST_NOT_OCCUR;
/* Disable INTCSIH3IR operation and clear request */
INTC2.ICCSIH3IR.BIT.MKCSIH3IR = _INT_PROCESSING_DISABLED;
INTC2.ICCSIH3IR.BIT.RFCSIH3IR = _INT_REQUEST_NOT_OCCUR;
/* Disable INTCSIH3IRE operation and clear request */
INTC2.ICCSIH3IRE.BIT.MKCSIH3IRE = _INT_PROCESSING_DISABLED;
INTC2.ICCSIH3IRE.BIT.RFCSIH3IRE = _INT_REQUEST_NOT_OCCUR;
/* Set CSIH3 interrupt(INTCSIH3IC) setting */
INTC2.ICCSIH3IC.BIT.TBCSIH3IC = _INT_TABLE_VECTOR;
INTC2.ICCSIH3IC.UINT16 &= _INT_PRIORITY_LOWEST;
/* Set CSIH3 interrupt(INTCSIH3IR) setting */
INTC2.ICCSIH3IR.BIT.TBCSIH3IR = _INT_TABLE_VECTOR;
INTC2.ICCSIH3IR.UINT16 &= _INT_PRIORITY_LOWEST;
/* Set CSIH3 interrupt(INTCSIH3IRE) setting */
INTC2.ICCSIH3IRE.BIT.TBCSIH3IRE = _INT_TABLE_VECTOR;
INTC2.ICCSIH3IRE.UINT16 &= _INT_PRIORITY_LOWEST;
/* Set CSIH3 control setting */
CSIH3.CTL1 = _CSIH_CLOCK_INVERTING_LOW | _CSIH_INTERRUPT_TIMING_NORMAL | _CSIH_DATA_CONSISTENCY_CHECK_DISABLE |
_CSIH_CHIPSELECT_SIGNAL_HOLD_ACTIVE | _CSIH_HANDSHAKE_DISABLE | _CSIH_SLAVE_SELECT_DISABLE;
CSIH3.CTL2 = _CSIH3_SELECT_BASIC_CLOCK;
/* Set CSIH3 configuration setting */
CSIH3.CFG0 = _CSIH_PARITY_NO | _CSIH_DATA_LENGTH_8 | _CSIH_DATA_DIRECTION_MSB | _CSIHn_SLAVE_PHASE_SELECTION_TYPE4;
/* Synchronization processing */
g_cg_sync_read = CSIH3.CTL1;
__SYNCP();
/* Set CSIH3SC pin */
PORT.PIBC11 &= _PORT_CLEAR_BIT7;
PORT.PBDC11 &= _PORT_CLEAR_BIT7;
PORT.PM11 |= _PORT_SET_BIT7;
PORT.PMC11 &= _PORT_CLEAR_BIT7;
PORT.PIPC11 &= _PORT_CLEAR_BIT7;
tmp_port = PORT.PDSC11;
PORT.PPCMD11 = _WRITE_PROTECT_COMMAND;
PORT.PDSC11 = (tmp_port | _PORT_SET_BIT7);
PORT.PDSC11 = (unsigned int) ~(tmp_port | _PORT_SET_BIT7);
PORT.PDSC11 = (tmp_port | _PORT_SET_BIT7);
PORT.PFC11 &= _PORT_CLEAR_BIT7;
PORT.PFCE11 |= _PORT_SET_BIT7;
PORT.PIPC11 |= _PORT_SET_BIT7;
PORT.PMC11 |= _PORT_SET_BIT7;
/* Set CSIH3SO pin */
PORT.PIBC11 &= _PORT_CLEAR_BIT6;
PORT.PBDC11 &= _PORT_CLEAR_BIT6;
PORT.PM11 |= _PORT_SET_BIT6;
PORT.PMC11 &= _PORT_CLEAR_BIT6;
PORT.PIPC11 &= _PORT_CLEAR_BIT6;
tmp_port = PORT.PDSC11;
PORT.PPCMD11 = _WRITE_PROTECT_COMMAND;
PORT.PDSC11 = (tmp_port | _PORT_SET_BIT6);
PORT.PDSC11 = (unsigned int) ~(tmp_port | _PORT_SET_BIT6);
PORT.PDSC11 = (tmp_port | _PORT_SET_BIT6);
PORT.PFC11 &= _PORT_CLEAR_BIT6;
PORT.PFCE11 |= _PORT_SET_BIT6;
PORT.PFCAE11 &= _PORT_CLEAR_BIT6;
PORT.PIPC11 |= _PORT_SET_BIT6;
PORT.PMC11 |= _PORT_SET_BIT6;
/* Set CSIH3SI pin */
PORT.PIBC11 &= _PORT_CLEAR_BIT5;
PORT.PBDC11 &= _PORT_CLEAR_BIT5;
PORT.PM11 |= _PORT_SET_BIT5;
PORT.PMC11 &= _PORT_CLEAR_BIT5;
PORT.PFC11 &= _PORT_CLEAR_BIT5;
PORT.PFCE11 |= _PORT_SET_BIT5;
PORT.PFCAE11 &= _PORT_CLEAR_BIT5;
PORT.PMC11 |= _PORT_SET_BIT5;
}
/******************************************************************************
** Function: R_CSIH3_Start
** Description: Start the CSIH3.
** Parameter: None
** Return: None
******************************************************************************/
void R_CSIH3_Start(void)
{
/* Enable CSIH3 operation */
CSIH3.CTL0 = _CSIH_OPERATION_CLOCK_PROVIDE | _CSIH_TRANSMISSION_PERMIT | _CSIH_RECEPTION_PERMIT |
_CSIH_DIRECTACCESS;
/* Clear CSIH3 interrupt request and enable operation */
INTC2.ICCSIH3IC.BIT.RFCSIH3IC = _INT_REQUEST_NOT_OCCUR;
INTC2.ICCSIH3IR.BIT.RFCSIH3IR = _INT_REQUEST_NOT_OCCUR;
INTC2.ICCSIH3IRE.BIT.RFCSIH3IRE = _INT_REQUEST_NOT_OCCUR;
INTC2.ICCSIH3IR.BIT.MKCSIH3IR = _INT_PROCESSING_ENABLED;
}
/******************************************************************************
** Function: spi_CSIH3_TransmitData
** Description: Transmits a single data frame with CSIH3.
** Parameter: spi_TxData - Transmission Data
** Return: None
******************************************************************************/
void spi_CSIH3_TransmitData(unsigned int spi_TxData)
{
while(CSIH3STR0 & (1<<7)); /* Wait until transmission finished */
CSIH3TX0H = spi_TxData;
while(CSIH3STR0 & (1<<7)); /* Wait until transmission finished */
}