您好!
我们的其中一款产品中有一个应用、我们在其中使用带有 DMA 的 UART 与 Telit 的无线电芯片进行通信。 由于这是一个低功耗应用、因此需要将芯片置于睡眠模式、禁用 UART 并将 Rx、Tx 引脚切换至输入模式。 在每小时唤醒一次时,我们再次启用 UART,传输一些数据,并将芯片重新置于睡眠状态。
在初始化时、我们首先初始化 UART、然后初始化 DMA。 当芯片处于睡眠或唤醒状态时、我们不会再次启用/禁用 DMA 外设。 如果我们不这样做,是可以的吗? 如果是、则 DMA 模块如何与 UART 保持同步?
下面 是固件上电和其他情况下的外设初始化代码片段。
微控制器:MSP430FR5969
UART A1与 DMA 通道0和1一起使用。
-
在加电时调用以下函数以进行 UART 和 DMA 初始化
空 Init_ZigBee_Interface (空)
{
PM5CTL0 &=~LOCKLPM5;
EUSCI_A_UART_initParam param ={0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param.clockPrescalar = 8;
param.firstModReg = 0;//过采样无效
param.secondModReg = 0xD6;
param.parity = EUSCI_A_UART_NO_parity;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numerofStopBits = EUSCI_A_UART_Oe_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.oversaming= EUSCI_A_UART_LOW_FREQUENCY BAUDRATE_generation;
EUSCI_A_UART_INIT (EUSCI_A1_BASE、param);
EUSCI_A_UART_ENABLE (EUSCI_A1_BASE);
//DMA Rx
参数1 ={0};
param1.channelSelect = dma_channel_0;
param1.transferModeSelect = dma_transfer_ere重复 单次;
param1.transferSize = M_serial_buffer_LEN;
param1.triggerSourceSelect = dma_TRIGGERSOURCE_16;
param1.transferUnitSelect = dma_size_SRCBYTE_DSTBYTE;
param1.triggerTypeSelect = dma_trigger_RISINGEDGE;
dma_init (¶m1);
//dma_disableTransferDuringReadModifyWrite ();
dma_enableRoundRobinPriority ();
DMA_setSrcAddress (DMA_CHANGE_0、
(uint32_t)&(UCA1RXBUF)、
dma_direction 不变);
DMA_setDstAddress (DMA_CHANGE_0、
(uint32_t)&(ZigBee_dma_RxBuf.buffer[0])、
dma_direction 增量);
dma_enableTransfers (dma_channel_0);
DMA_enableInterrupt (DMA_CHANNEL);
//DMA 发送
param1.channelSelect = dma_channel_1;
param1.transferModeSelect = dma_transfer_BURSTBLOCK;
param1.transferSize = 1;
param1.triggerSourceSelect = dma_TRIGGERSOURCE_17;
param1.transferUnitSelect = dma_size_SRCBYTE_DSTBYTE;
param1.triggerTypeSelect = dma_trigger_high;
dma_init (¶m1);
dma_enableRoundRobinPriority ();
DMA_setSrcAddress (DMA_CHANGE_1、
(uint32_t)&(mZhData.SerialBuffer.TxBuf[1])、 //传输缓冲区
dma_direction 增量);
DMA_setDstAddress (DMA_CHANGE_1、
(uint32_t)&UCA1TXBUF、 //接收缓冲区
dma_direction 不变);
DMA_enableInterrupt (DMA_CHANNEL);
}
2.下面的代码片段在无限循环中调用,使 Telit 模块进入睡眠状态或从睡眠状态唤醒 Telit 模块
/**检查以将 ZigBee 模块置于睡眠模式*/
if (mZhData.StateMachine.bSleping)
{
EUSCI_A_UART_DISABLE (EUSCI_A1_BASE);
if (!ZB_PwrCyclcFlg)
{
GPIO_setOutputHighOnPin (GPIO_PORT_P4、GPIO_PIN0); /** CTS 高*/
}
/**将 ZE61的 TXD、RXD 置于三态*/
GPIO_setAsInputPin (GPIO_PORT_P2、GPIO_PIN6);
GPIO_setAsInputPin (GPIO_PORT_P2、GPIO_PIN5);
LPM_Flag |= LPM_wireless;
}
/**检查以唤醒 ZigBee 模块*/
其他
{
/**为端口2引脚1*/设置 UART 功能 RXD
GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P2、GPIO_PIN6、GPIO_secondary 模块_function);/** ZE61*/的 TXD
/**为端口2引脚0*/设置 UART 功能 TXD
GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_P2、GPIO_PIN5、GPIO_secondary 模块_function);/** ZE61*/的 RXD
GPIO_setOutputLowOnPin (GPIO_PORT_P4、GPIO_PIN0); //CTS 低电平
EUSCI_A_UART_ENABLE (EUSCI_A1_BASE);
}
在升级模式下调用下面的代码片段以更改波特率运行时间
/*!
*@fn void coSetZigBeeUart9600 (void)
*@简短此函数被调用以以9600波特率切换 ZigBee UART
*@返回无
*
void coSetZigBeeUart9600 ()
{
#ifdef ZIGBEEHANDLER_FPFI_H_DEBUG
printf ("\r\naud9600\r\n");
#endif
EUSCI_A_UART_initParam param ={0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
//1MHz 9600
param.clockPrescalar = 6;
param.firstModReg = 8;
param.secondModReg = 0x20;
//1MHz 38400
// param.clockPrescalar = 1;
// param.firstModReg = 10;
// param.secondModReg = 0x00;
// param.clockPrescalar = 26;
// param.firstModReg = 0;
// param.secondModReg = 0xB6;
param.parity = EUSCI_A_UART_NO_parity;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numerofStopBits = EUSCI_A_UART_Oe_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.oversaming= EUSCI_A_UART_oversaming_BAUDRATE_generation;
EUSCI_A_UART_INIT (EUSCI_A1_BASE、param);
// if (!flg_fw_UpgradeUart)
EUSCI_A_UART_ENABLE (EUSCI_A1_BASE);
DMA_clearInterrupt (DMA_CHANNEL);
DMA_enableInterrupt (DMA_CHANNEL);
// EUSCI_A_UART_clearInterrupt (EUSCI_A1_BASE、
// EUSCI_A_UART_receive_interrupt);
//
// ////*启用 USCI_A0 RX 中断*/
// EUSCI_A_UART_enableInterrupt (EUSCI_A1_BASE、
// EUSCI_A_UART_Receive_interrupt);//启用中断
}
/*!
*@fn void coSetZigBeeUart115200 (void)
*@简介调用此函数是为了以115200波特率切换 ZigBee UART
*@返回无
*
void coSetZigBeeUart115200()
{
#ifdef ZIGBEEHANDLER_FPFI_H_DEBUG
printf ("\r\naud115200\r\n");
#endif
EUSCI_A_UART_initParam param1 ={0};
param1.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param1.clockPrescalar = 8;
param1.firstModReg = 0;
param1.secondModReg = 0xD6;
// param.clockPrescalar = 2;
// param.firstModReg = 2;//过采样无效
// param.secondModReg = 0xBB;
param1.param1。param1 = EUSCI_A_UART_NO_parity;
param1.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param1.numerofStopBits = EUSCI_A_UART_Oe_STOP_BIT;
param1.uartMode = EUSCI_A_UART_MODE;
param1.oversam采样= EUSCI_A_UART_LOW_FREQUENCY BAUDRATE_generation;
// param.oversaming= EUSCI_A_UART_oversaming_BAUDRATE_generation;
EUSCI_A_UART_INIT (EUSCI_A1_BASE、¶m1);
// if (!flg_fw_UpgradeUart)
EUSCI_A_UART_ENABLE (EUSCI_A1_BASE);
DMA_clearInterrupt (DMA_CHANNEL);
DMA_enableInterrupt (DMA_CHANNEL);
// EUSCI_A_UART_clearInterrupt (EUSCI_A1_BASE、
// EUSCI_A_UART_receive_interrupt);
//
// ////*启用 USCI_A0 RX 中断*/
// EUSCI_A_UART_enableInterrupt (EUSCI_A1_BASE、
// EUSCI_A_UART_Receive_interrupt);//启用中断
}
此致、
拉曼