我参考usart例程中的DMA收发方式,修改成了DMA只收数据,然后用作finsh的通信端口USART1,完全正常,然后我又使能了一个USART4做为485收发,参考UART1的代码拷贝了一个,关键代码如下:
#define USART4_CH (M4_USART4)
#define USART4_BAUDRATE (115200ul)
#define USART4_RX_PORT (PortB)
#define USART4_RX_PIN (Pin04)
#define USART4_RX_FUNC (Func_Usart4_Rx)
#define USART4_TX_PORT (PortB)
#define USART4_TX_PIN (Pin05)
#define USART4_TX_FUNC (Func_Usart4_Tx)
#define USART4_EI_NUM (INT_USART4_EI)
#define USART4_EI_IRQn (Int003_IRQn)
extern uint8_t Uart4_Rx; //串口4接收缓存
extern uint8_t Uart4_Buffer[]; //串口4接收到的数据
extern uint8_t Uart4_Count;
void Uart4_Init(void)
{
en_result_t enRet = Ok;
stc_irq_regi_conf_t stcIrqRegiCfg;
uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \
PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;
/* Enable peripheral clock */
PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable);
const stc_usart_uart_init_t stcInitCfg = {
UsartIntClkCkNoOutput,
UsartClkDiv_1,
UsartDataBits8,
UsartDataLsbFirst,
UsartOneStopBit,
UsartParityNone,
UsartSamleBit8,
UsartStartBitFallEdge,
UsartRtsEnable,
};
/* Initialize USART IO */
PORT_SetFunc(USART4_RX_PORT, USART4_RX_PIN, USART4_RX_FUNC, Disable);
PORT_SetFunc(USART4_TX_PORT, USART4_TX_PIN, USART4_TX_FUNC, Disable);
/* Initialize USART */
enRet = USART_UART_Init(USART4_CH, &stcInitCfg);
if (enRet != Ok)
{
while (1)
{
}
}
else
{
}
/* Set baudrate */
enRet = USART_SetBaudrate(USART4_CH, USART4_BAUDRATE);
if (enRet != Ok)
{
while (1)
{
}
}
else
{
}
/* Set USART RX error IRQ */
MEM_ZERO_STRUCT(stcIrqRegiCfg);
stcIrqRegiCfg.enIRQn = USART4_EI_IRQn;
stcIrqRegiCfg.pfnCallback = &Usart4ErrIrqCallback;
stcIrqRegiCfg.enIntSrc = USART4_EI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/*Enable TX && RX && RX interrupt function*/
USART_FuncCmd(USART4_CH, UsartTx, Enable);
USART_FuncCmd(USART4_CH, UsartRx, Enable);
USART_FuncCmd(USART4_CH, UsartRxInt, Enable);
}
下面是DMA初始化函数
/* DMAC */
#define DMA1CH1_UNIT (M4_DMA1)
#define DMA1_CH1 (DmaCh1)
#define DMA1CH1_TRG_SEL (EVT_USART4_RI)
/* DMA block transfer complete interrupt */
#define DMA1CH1_BTC_INT_NUM (INT_DMA1_BTC1)
#define DMA1CH1_BTC_INT_IRQn (Int004_IRQn)
void Dma1Ch1Init(void)
{
stc_dma_config_t stcDmaInit;
stc_irq_regi_conf_t stcIrqRegiCfg;
MEM_ZERO_STRUCT(stcDmaInit);
/* Enable peripheral clock */
PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1 | PWC_FCG0_PERIPH_DMA2,Enable);
/* Enable DMA. */
DMA_Cmd(DMA1CH1_UNIT,Enable);
/* Initialize DMA. */
MEM_ZERO_STRUCT(stcDmaInit);
stcDmaInit.u16BlockSize = 1u; /* 1 block */
stcDmaInit.u32SrcAddr = ((uint32_t)(&USART4_CH->DR)+2ul); /* Set source address. */
stcDmaInit.u32DesAddr = (uint32_t)(&Uart4_Rx); /* Set destination address. */
stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix; /* Set source address mode. */
stcDmaInit.stcDmaChCfg.enDesInc = AddressFix; /* Set destination address mode. */
stcDmaInit.stcDmaChCfg.enIntEn = Enable; /* Enable interrupt. */
stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit; /* Set data width 8bit. */
DMA_InitChannel(DMA1CH1_UNIT, DMA1_CH1, &stcDmaInit);
/* Enable the specified DMA channel. */
DMA_ChannelCmd(DMA1CH1_UNIT, DMA1_CH1, Enable);
/* Clear DMA flag. */
DMA_ClearIrqFlag(DMA1CH1_UNIT, DMA1_CH1, TrnCpltIrq);
/* Enable peripheral circuit trigger function. */
PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);
;
/* Set DMA trigger source. */
DMA_SetTriggerSrc(DMA1CH1_UNIT, DMA1_CH1, DMA1CH1_TRG_SEL);
/* Set DMA block transfer complete IRQ */
MEM_ZERO_STRUCT(stcIrqRegiCfg);
stcIrqRegiCfg.enIRQn = DMA1CH1_BTC_INT_IRQn;
stcIrqRegiCfg.pfnCallback = &Dma1ch1BtcIrqCallback;
stcIrqRegiCfg.enIntSrc = DMA1CH1_BTC_INT_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
}
static void Dma1ch1BtcIrqCallback(void)
{
RS485CS(1); //准备发送
DMA_ClearIrqFlag(DMA1CH1_UNIT, DMA1_CH1, BlkTrnCpltIrq);
Uart4_Buffer[Uart4_Count++] = Uart4_Rx;
USART_SendData(USART4_CH,(uint16_t)Uart4_Rx);
while (Reset == USART_GetStatus(USART4_CH, UsartTxComplete));
RS485CS(0); //准备发送
/* if(Uart4_Count >= 10)
{
RS485CS(1); //准备发送
for(int i = 0 ; i < 10 ; i += 1)
{
USART_SendData(USART4_CH,(uint16_t)Uart4_Buffer[i]);
while (Reset == USART_GetStatus(USART4_CH, UsartTxComplete));
}
Uart4_Count = 0 ;
RS485CS(0); //准备发送
}*/
}
串口1使用的Int001_IRQn
DMA1CH0使用的Int002_IRQn
串口4使用的Int003_IRQn
DMA1CH1使用的Int004_IRQn
USART1,用在finsh就完全正常的,可以正常收发;
USART4,就是无法收到电脑发送的数据,没有进入中断,但是单片机发数据电脑能收到。
我是从STM32转到华大MCU的,这是第一次使用华大MCU做的板子,也是第一次使用rt-thread,这是公司第一次使用国产的芯片和rt-thread,这次公司的测量项目,我直接从,芯片选型,全部转为国产,到ORCAD画图,allegro画PCB,打样,自己做SMT,经历了1个多月,现在板子终于出成品了,就开始了漫长的代码移植,STM32我是一直在MAC上开发的,遗憾的是华大没有官方的GCC移植代码,我发现IAR里面有GCC,的S和linker,我自己就手动写了,makefile,直到编译,解决了无数个坑,最后编译终于没有问题了,可是华大的没有openocd的cfg文件,我用仿真器下载不上去,由于项目没有时间了,暂时放弃了linux和MAC下的编译了,回到Keil了,如果论坛里有人要我GCC makefile文件,留言,我把源码发给你,可以一直研究openocd 怎么把编译后的文件下载到MCU。
项目完成后,我会把我STM32转向华大的MCU,做的教学视频,从ORCAD画原理图,到allegro布线,到打样,到做钢网,到贴片。到移植官方的代码,到移植rt-thread,最后在到移植finsh.
现在就是遇到了,单片机收不到电脑数据,可能是我不熟悉华大MCU的原因,还希望论坛大佬,能指点我一下。谢谢大家
|
|