历史上的今天
返回首页

历史上的今天

今天是:2025年08月16日(星期六)

正在发生

2019年08月16日 | HAL库之485+DMA通信(STM32F746)

2019-08-16 来源:eefocus

1.首先一定要保证硬件正确,包括接线,工具正常;


2.其次基本配置一定要正确,例如此次配置485的时候,可以实现DMA发送,却不能实现接收。而同样的串口参数配置使用中断方式和232接口都能实现发送接收,个人判断是是接收DMA部分配置有问题,结果卡了很久才发现是基本的管脚配置有误。485的三根引脚要配置成推挽输出,复用,复用模式。


3.最后,还是要多总结经验,多看看源代码。


硬件如下:

其实本质上还是串口通信,只不过多了一个开关控制(485-DIR),用来控制是发送数据还是接收数据,因此是半双工模式。


配置流程:时钟使能,引脚配置,串口配置(波特率,校验位等),DMA配置(需要配置串口中断)。


void USART2_UART_Init(uint32_t bound)

{

  __HAL_RCC_GPIOD_CLK_ENABLE();

  __HAL_RCC_USART2_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_Init2;

  GPIO_Init2.Pin = GPIO_PIN_4;              //485_RTS

  GPIO_Init2.Mode =GPIO_MODE_OUTPUT_PP;

  GPIO_Init2.Pull = GPIO_NOPULL;

  GPIO_Init2.Speed = GPIO_SPEED_FREQ_HIGH;

  GPIO_Init2.Alternate = GPIO_AF7_USART2;

  HAL_GPIO_Init(GPIOD,&GPIO_Init2);

 

  GPIO_Init2.Pin = GPIO_PIN_5;              //485 TX config

  GPIO_Init2.Mode = GPIO_MODE_AF_PP;

  GPIO_Init2.Pull = GPIO_NOPULL;

  GPIO_Init2.Speed = GPIO_SPEED_FREQ_HIGH;

  GPIO_Init2.Alternate = GPIO_AF7_USART2;

  HAL_GPIO_Init(GPIOD,&GPIO_Init2);

 

  GPIO_Init2.Pin = GPIO_PIN_6;            //485 RX config

  GPIO_Init2.Mode = GPIO_MODE_AF_PP;

  GPIO_Init2.Pull = GPIO_NOPULL;

  GPIO_Init2.Speed = GPIO_SPEED_FREQ_HIGH;

  GPIO_Init2.Alternate = GPIO_AF7_USART2;

  HAL_GPIO_Init(GPIOD,&GPIO_Init2);        //USART2_GPIO配置

  __HAL_RCC_DMA1_CLK_ENABLE();

  huart2_dma_rx.Instance=DMA1_Stream5;  //USART2RX_ DMA1数据流5,通道4

  huart2_dma_rx.Init.Channel=DMA_CHANNEL_4;

  huart2_dma_rx.Init.Direction=DMA_PERIPH_TO_MEMORY;

  huart2_dma_rx.Init.PeriphInc=DMA_PINC_DISABLE;

  huart2_dma_rx.Init.MemInc=DMA_MINC_ENABLE;

  huart2_dma_rx.Init.MemDataAlignment= DMA_MDATAALIGN_BYTE;

  huart2_dma_rx.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;

  huart2_dma_rx.Init.Mode=DMA_NORMAL;

  huart2_dma_rx.Init.Priority=DMA_PRIORITY_LOW;

  huart2_dma_rx.Init.FIFOMode=DMA_FIFOMODE_DISABLE;

  HAL_DMA_Init(&huart2_dma_rx);

       huart2_dma_tx.Instance=DMA1_Stream6;            //USART2TX_ DMA1数据流6,通道4

huart2_dma_tx.Init.Channel=DMA_CHANNEL_4;

huart2_dma_tx.Init.Direction=DMA_MEMORY_TO_PERIPH;

huart2_dma_tx.Init.PeriphInc=DMA_PINC_DISABLE;

huart2_dma_tx.Init.MemInc=DMA_MINC_ENABLE;

huart2_dma_tx.Init.MemDataAlignment= DMA_MDATAALIGN_BYTE;

huart2_dma_tx.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;

huart2_dma_tx.Init.Mode=DMA_NORMAL;

huart2_dma_tx.Init.Priority=DMA_PRIORITY_HIGH;

huart2_dma_tx.Init.FIFOMode=DMA_FIFOMODE_DISABLE;

HAL_DMA_Init(&huart2_dma_tx);

   __HAL_LINKDMA(&huart2,hdmarx,huart2_dma_rx); //关联USART2和DMA

   __HAL_LINKDMA(&huart2,hdmatx,huart2_dma_tx);  

  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn,1,1);  //配置DMA通道的中断并使能

  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);

  HAL_NVIC_SetPriority(DMA1_Stream6_IRQn,1,1); 

  HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);

 

  huart2.Instance =USART2; 

  huart2.Init.BaudRate =bound;

  huart2.Init.WordLength =UART_WORDLENGTH_8B;

  huart2.Init.StopBits =UART_STOPBITS_1;

  huart2.Init.Parity =UART_PARITY_NONE;

  huart2.Init.Mode = UART_MODE_TX_RX;

  huart2.Init.HwFlowCtl=UART_HWCONTROL_NONE;

  huart2.Init.OverSampling = UART_OVERSAMPLING_16;

  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; 

  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  HAL_UART_Init(&huart2);    //串口2配置

  HAL_NVIC_SetPriority(USART2_IRQn,1,1);            //配置USART2的中断并使能

  HAL_NVIC_EnableIRQ(USART2_IRQn);               

RS485_R;

}

 

 

void delay485(uint32_t num)

{

while(num--);

}

 

void RS485_Send_data(uint8_t *pdata,uint16_t data_size)

{

RS485_T;

delay485(4);

while(HAL_UART_GetState(&huart2)!=HAL_UART_STATE_READY);

HAL_UART_Transmit_DMA(&huart2,pdata,data_size);

while(HAL_UART_GetState(&huart2)!=HAL_UART_STATE_READY);

RS485_R;

delay485(4);

}

 

void RS485_Receive_data(uint8_t *pdata,uint16_t data_size)

{

while(HAL_UART_GetState(&huart2)!=HAL_UART_STATE_READY);

HAL_UART_Receive_DMA(&huart2,pdata,data_size);

}

主程序测试:


int main(void)    

{

  HAL_Init();

  Sysclk_config();

USART2_UART_Init(38400);

RS485_Send_data(buffer1,data_length);

HAL_UART_Receive_DMA(&huart2,buffer2,data_length); //打开DMA接收

  while(1)

  { 

   if(flag==1)

  {

HAL_Delay(200);

   RS485_Send_data(buffer2,data_length);

flag=0;

HAL_UART_Receive_DMA(&huart2,buffer2,data_length);//打开DMA接收 

  }

 }

}

 

 

void USART2_IRQHandler(void)

{

HAL_UART_IRQHandler(&huart2);

}

 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

if(huart==&huart2)

{

  flag=1;

}

}

 

void DMA1_Stream6_IRQHandler(void)

{

  HAL_DMA_IRQHandler(&huart2_dma_tx);

}

 

 

void DMA1_Stream5_IRQHandler(void)

{

  HAL_DMA_IRQHandler(&huart2_dma_rx);

}


推荐阅读

史海拾趣

DFRobot公司的发展小趣事

随着市场的不断扩大,DFRobot意识到单一的产品代理无法满足客户的需求。于是,公司开始加大研发投入,自主研发机器人和开源硬件产品。同时,为了保证产品的质量和生产效率,DFRobot在成都和北京设立了生产基地,引进先进的生产设备和技术。这种研发与生产一体化的模式,使DFRobot能够更快速地响应市场变化,推出符合客户需求的新产品。

Astro Tool Corp公司的发展小趣事

Astro Tool Corp公司深知产品质量是企业生存和发展的关键。因此,公司始终将质量管理放在首位,建立了完善的质量管理体系和检测机制。通过严格把控原材料采购、生产过程和成品检测等各个环节,公司确保了产品的稳定性和可靠性。同时,公司还注重品牌建设,通过提升产品附加值和服务质量,不断增强客户对公司的信任度和忠诚度。

Centellax Inc公司的发展小趣事

为了确保产品质量和客户满意度,Centellax建立了完善的质量管理体系。公司从原材料采购、生产制造到产品销售等各个环节都严格把控质量,确保产品性能稳定可靠。

同时,Centellax还引入了国际先进的质量管理理念和方法,不断提升员工的质量意识和技能水平。通过持续改进和优化生产流程,降低生产成本,提高产品竞争力。此外,公司还建立了完善的售后服务体系,为客户提供及时、专业的技术支持和解决方案。

General Instrument Optoelectronics公司的发展小趣事
确保电源线没有损坏或接触不良。
H&D Wireless公司的发展小趣事

随着全球化进程的加速,高创也开始了其全球化布局的步伐。除了在以色列和中国设立研发中心外,高创还积极拓展国际市场,与全球多个国家和地区的客户建立了长期合作关系。通过参加国际知名展会如汉诺威工业博览会等,高创不仅展示了其最新技术和产品,还加强了与国际同行的交流与合作,进一步提升了其国际知名度和影响力。

GE Industrial Solutions公司的发展小趣事
由于光耦的CTR随温度变化而变化,可能导致输出信号的非线性失真。解决方法包括选择温度稳定性好的光耦,或在电路中加入温度补偿电路。

问答坊 | AI 解惑

怎么样在这里发帖时添加附件啊

我想上传东西但是不知道怎么添加附件…

查看全部问答>

gooogleman大侠,求助!

就32分了! 请问大侠当时用9650采集图像时采集到的数据格式是什么(rgb,ycbcr?),当时大侠把它转化成图片了吗?是什么格式的?bmp,jpeg? 是怎么做的?谢谢了!…

查看全部问答>

2440 wince5.0 GPS/PDA

最近弄了个GPS,是2440/wince5.0做的,2.8寸的屏,开始的时候只能用别人已经写好了的程序,不能进入wince界面。实在想进wince看看就写了个小程序,哎呀,终于可以进wince界面了,可以看看图片,爽啊!! …

查看全部问答>

图形绘制

请依照如下要求设计 1、设计显示图形:自己的中文名字; 2、设计显示程序; 3、调试通过。 …

查看全部问答>

谁有CUnit方面的资料啊?

要做毕业设计,网上关于CUnit方面的资料挺少的,哪位能否给我一些资料或者建议?…

查看全部问答>

Vxworks支持PPC时钟计数值动态修改吗?

PPC的440EP内部有个递减时钟计数器decrementor,它的计数初值决定了操作系统每个tick的周期。一般情况下它的计数初值都是提前预置好不会改变。比如linux里param.h中的HZ宏定义。 我想知道可不可以动态修改这个计数初值啊?比如来了外部中断后,在I ...…

查看全部问答>

8bit轉32bit的疑問

一個32位的單片機器,是不是說 int32_t c, b, a; c = a + b 和unsigned char c, b, a; c = b + a; 一樣快? 是不是在程序中應該儘量使用32 bit 整數類型。…

查看全部问答>

GC5016

本人最近正在用GC5016做下变频,以前没搞过,用FPGA产生了控制寄存器的写时序,但是当把用cmd5016产生的h文件写入时,只有[A-D]CK能出来,[A-D]FS出不来,也检查了TXT文件,没找到错误,求用过的兄弟姐妹分享一下在使用过程中的经验!…

查看全部问答>

有关于FPGA方面的吗?分享分享

本帖最后由 paulhyde 于 2014-9-15 09:06 编辑 如题  …

查看全部问答>