本帖最后由 JacksonChen 于 2024-11-7 16:38 编辑
通过串口调试助手可以知道printf函数能够正常输出打印语句,但是中断接收会出现数据乱码情况,使用的是38400时钟频率,波特率为9600,以下是代码:
------------------------------------------------------------------------------------------------------------------------------------
#include "ddl.h" //驱动头文件
#include "lpuart.h" //低功耗串口头文件
#include "bt.h" //中断时钟头文件
#include "lpm.h" //低功耗模式头文件
#include "gpio.h" //IO口头文件
#include "clk.h" //时钟头文件
#include "stdio.h"
extern uint8_t u8RxData[RX_BUFFER_SIZE];
extern uint8_t u8Rx**;
extern uint8_t lpuart_rx_head;
extern uint8_t lpuart_rx_tail;
void RxIntCallback(void)
{
u8Rx** = 1;//接收完整数据标志
// 接收数据
u8RxData[lpuart_rx_head] = M0P_LPUART->SBUF;
// 更新头指针
lpuart_rx_head = (lpuart_rx_head + 1) % RX_BUFFER_SIZE; // 使用模运算防止溢出
// 清中断标志位
LPUart_ClrStatus(LPUartRxFull);
}
void ErrIntCallback(void)
{
LPUart_ClrStatus(LPUartRFRAMEError);//帧错误标记
}
en_result_t My_LPUart_Init(void)
{
stc_lpuart_config_t stcConfig; //串口整体配置结构体
stc_lpuart_irq_cb_t stcLPUartIrqCb; //串口中断回调函数结构体
stc_lpuart_multimode_t stcMulti; //串口多主机模式函数结构体
stc_lpuart_sclk_sel_t stcLpuart_clk; //串口时钟配置结构体
stc_lpuart_mode_t stcRunMode; //低功耗模式配置结构体
// stc_lpuart_baud_config_t stcBaud; //波特率配置结构体
stc_bt_config_t stcBtConfig; //基本定时器配置结构体
stc_lpm_config_t stcLpmCfg; //低功耗配置
lpuart_rx_head = lpuart_rx_tail = 0;
memset(u8RxData , 0 , sizeof(u8RxData));
//清空数据函数
DDL_ZERO_STRUCT(stcConfig);
DDL_ZERO_STRUCT(stcLPUartIrqCb);
DDL_ZERO_STRUCT(stcMulti);
// DDL_ZERO_STRUCT(stcBaud);
DDL_ZERO_STRUCT(stcBtConfig);
DDL_ZERO_STRUCT(stcLpmCfg);
stcLpmCfg.enSLEEPDEEP = SlpDpDisable;//SlpDpEnable;//
stcLpmCfg.enSLEEPONEXIT = SlpExtDisable;//唤醒后不自动进入睡眠
Clk_Enable(ClkRCL, TRUE);
Clk_SetRCLFreq(ClkFreq38_4K);//内部38.4K
//外设时钟使能
Clk_SetPeripheralGate(ClkPeripheralLpUart,TRUE);//使能LPUART时钟
Clk_SetPeripheralGate(ClkPeripheralBt,TRUE);
//通道端口配置
Gpio_InitIOExt(3,3,GpioDirIn,TRUE,FALSE,FALSE,FALSE); //配置33引脚为输入模式RX
Gpio_InitIOExt(3,4,GpioDirOut,TRUE,FALSE,FALSE,FALSE); //配置34引脚为输出模式TX
//拉低BRTS电平
Gpio_InitIOExt(2,5,GpioDirOut,TRUE,FALSE,FALSE,FALSE);
Gpio_SetIO(2,5,0);
Gpio_SetFunc_UART2RX_P33();
Gpio_SetFunc_UART2TX_P34();
//低功耗时钟配置
stcLpuart_clk.enSclk_sel = LPUart_Rcl; //LPUart_Pclk;//时钟源选择
stcLpuart_clk.enSclk_Prs = LPUartDiv1; //分频选择
stcConfig.pstcLpuart_clk = &stcLpuart_clk;
stcRunMode.enLpMode = LPUartLPMode;//LPUartNoLPMode;//非低功耗或低功耗模式选择
stcRunMode.enMode = LPUartMode1;//工作模式选择
stcConfig.pstcRunMode = &stcRunMode;
stcLPUartIrqCb.pfnRxIrqCb = RxIntCallback;
stcLPUartIrqCb.pfnTxIrqCb = NULL;
stcLPUartIrqCb.pfnRxErrIrqCb = NULL;//ErrIntCallback;
stcConfig.pstcIrqCb = &stcLPUartIrqCb;
stcConfig.bTouchNvic = TRUE;
stcMulti.enMulti_mode = LPUartNormal;//mode2/3才有多主机模式
stcConfig.pstcMultiMode = &stcMulti;
LPUart_EnableIrq(LPUartRxIrq);
LPUart_Init(&stcConfig);
Gpio_InitIO(0,3,GpioDirOut);
LPUart_EnableFunc(LPUartRx);
#if 0
while(1 == Gpio_GetIO(T1_PORT,T1_PIN));//注意:此处用户不能屏蔽,否则进入深度休眠模式导致SWD连接不上
Lpm_Config(&stcLpmCfg);
Lpm_GotoLpmMode();
#endif
return Ok;
}
int32_t main(void)
{
char buffer[RX_BUFFER_SIZE + 1];
uint8_t length = 0;
My_LPUart_Init();
printf("Init succeed!\r\n");
while(1)
{
if(lpuart_rx_tail != lpuart_rx_head)
{
//计算可读数据的长度
length = (lpuart_rx_head >= lpuart_rx_tail) ?
(lpuart_rx_head - lpuart_rx_tail) : (RX_BUFFER_SIZE - lpuart_rx_tail + lpuart_rx_head);
//将可读数据复制到临时缓冲区,并添加字符串结束符
memcpy(buffer, &u8RxData[lpuart_rx_tail], length);
buffer[length] = '\0';
//打印接收到的数据
printf("Received data: %s\r\n", buffer);
//更新尾指针
lpuart_rx_tail = (lpuart_rx_tail + length) % RX_BUFFER_SIZE;
}
delay1ms(500);
}
}
|