百科问答小站 logo
百科问答小站 font logo



为什么网上连开源的stm32 8个串口程序都没有? 第1页

  

user avatar   zhang-hao-72 网友的相关建议: 
      

分享个我的, 任意个串口, 你按你的需求改改就行了. 我已经在N个项目里用过了.

字符中断方式接收, 空闲中断判断帧尾, 阻塞方式发送. 哪位有兴趣了可以试试加上中断方式发送, 这样CPU负担轻一些. 不用DMA是因为串口多了没有那么多DMA通道用, 就算够用, SPI/ADC之类也没得用了.

       // 请添加你自己的头文件  #define MAX_LEN 128  // 帧长度, 按你的需要 #define USART_TOTAL_NUM 4          // 串口个数  typedef struct {     const USART_TypeDef* usartx;     unsigned char msg[MAX_LEN];     unsigned char rxbuf[MAX_LEN];               // 用两个缓冲区, 进入后处理函数后接收缓冲区就可以用于新一轮接收, 只是比较浪费内存     unsigned char* rxptr;     int size, updated; } usartx_t;  static struct {     usartx_t usart[USART_TOTAL_NUM];     void (*parser_f)(const void* msg, int size, int source);           // 后处理函数指针, 用source区分是哪个串口 } g;  void USART_BindParser(void (*parser_f)(const void* msg, int size, int source))    // 初始化串口后用它绑定你自己的回调函数做进一步处理 {     g.parser_f = parser_f; }  void USART_ReConfig(USART_TypeDef* USARTx, unsigned long baudrate) {     USART_InitTypeDef uis; //    USART_DeInit(USARTx);     USART_Cmd(USARTx, DISABLE);     USART_StructInit(&uis);     uis.USART_WordLength = USART_WordLength_8b;     uis.USART_StopBits = USART_StopBits_1;     uis.USART_Parity = USART_Parity_No;     uis.USART_HardwareFlowControl = USART_HardwareFlowControl_None;     uis.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;     uis.USART_BaudRate = baudrate;     USART_Init(USARTx, &uis); //    if(USARTx == USART1) //        USART_SWAPPinCmd(USARTx, ENABLE);              // 根据你的需求, 交换串口的tx/rx脚, 只在f0和f3系列有效     USART_Cmd(USARTx, ENABLE);     USART_ITConfig(USARTx, USART_IT_IDLE, ENABLE);     USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);     USART_ITConfig(USARTx, USART_IT_ORE, ENABLE);     USART_ITConfig(USARTx, USART_IT_FE, ENABLE); }  void USART_Config(void) {     NVIC_InitTypeDef nis;      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); //    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);      nis.NVIC_IRQChannel = USART1_IRQn;     nis.NVIC_IRQChannelPreemptionPriority = 1;     nis.NVIC_IRQChannelSubPriority = 1;     nis.NVIC_IRQChannelCmd = ENABLE;     NVIC_Init(&nis);     nis.NVIC_IRQChannel = UART5_IRQn;     NVIC_Init(&nis);      for(int i = 0; i < USART_TOTAL_NUM; i++) {         g.usart[i].rxptr = g.usart[i].rxbuf;         g.usart[i].size = 0;         g.usart[i].updated = 0;     }     g.usart[0].usartx = USART1;     g.usart[1].usartx = USART2;     g.usart[2].usartx = USART3;     g.usart[3].usartx = UART4; //    g.usart[4].usartx = UART5;      USART_ReConfig(USART1, 500000UL);              // 依次初始化你需要的串口 //    USART_ReConfig(UART5, 500000UL); }  void USART_WriteData(USART_TypeDef* USARTx, const void* data, int num)        // 阻塞方式, 中断方式自己写吧. DMA方式虽然好但是没那么多通道 {     while(num--) {         while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);         USART_SendData(USARTx, *((unsigned char*)data));         data++;     }     while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET); }  void USART_WriteByte(USART_TypeDef* USARTx, unsigned char byte)            // 一般用不到, 有些库可能需要单字节发送函数 {     USART_WriteData(USARTx, &byte, 1); }  void USART_Poll(void)               // 在主循环里调用, 不要放在中断里 {     for(int i = 0; i < USART_TOTAL_NUM; i++) {         usartx_t* p = &(g.usart[i]);         if(p->updated) {             g.parser_f(p->msg, p->size, i);              // 在这里调用你自己的回调函数做进一步处理             p->updated = 0;         }     } }  void USART_RXNE_IRQHandler(USART_TypeDef* USARTx)        // 在RXNE中断里调用 {     for(int i = 0; i < USART_TOTAL_NUM; i++) {         usartx_t* p = &(g.usart[i]);         if(USARTx == p->usartx) {             if(p->rxptr - p->rxbuf >= MAX_LEN)                 break;             *(p->rxptr) = p->usartx->RDR;                 // 在F0和F3是RDR, 在F1是DR             p->rxptr++;             break;         }     } }  void USART_IDLE_IRQHandler(USART_TypeDef* USARTx)            // 在IDLE中断里调用 {     for(int i = 0; i < USART_TOTAL_NUM; i++) {         usartx_t* p = &(g.usart[i]);         if(USARTx == p->usartx) {             p->size = p->rxptr - p->rxbuf;             memcpy(p->msg, p->rxbuf, p->size);             p->rxptr = p->rxbuf;             p->updated = 1;             break;         }     } }     




  

相关话题

  为什么用现代的单片机还是实现不了以前的红白机那么好的游戏效果? 
  寄存器会比用库开发,程序运行更快吗? 
  能求教STM32动态内存分配如何解决内存碎片问题吗? 
  两年嵌入式C语言编程经验,如果有机会做和 Android 相关的 C++、JAVA,还有 Javascript 脚本开发工作,转过去好吗? 
  为什么网上连开源的stm32 8个串口程序都没有? 
  stm32为何在诸多的单片机中脱颖而出? 
  能求教STM32动态内存分配如何解决内存碎片问题吗? 
  微处理器系统结构与嵌入式系统设计教材推荐? 
  Arduino 为什么这么红火?跟其它类似开发板的主要区别是什么? 
  能求教STM32动态内存分配如何解决内存碎片问题吗? 

前一个讨论
好的医学院和差的医学院有什么区别?
下一个讨论
现在大二,攒了 3 万块钱,想配一台电脑,如何说服爸妈?





© 2024-05-19 - tinynew.org. All Rights Reserved.
© 2024-05-19 - tinynew.org. 保留所有权利