caizhiwei 发表于 2014-5-15 21:26:12

分享一个官方没有的stm32f4-Discovery的串口例程

(固件库V1.0.0+串口( printf重定向,格式输出)+LED+Kill.bat)
   对于我心爱的stm32f4-dicovery,一直没有时间来折腾你,这会有时间了,跑跑程序玩玩。
   首先,打开官方下载的固件库,打开project,居然没有串口的例程,汗,然后自己自琢磨着移植一个。一开始打算搞串口1,结果发现被占用,所以就先调试串口2了,嘿嘿!
这里吐槽一下,今天下午第一次尝试用STM32Cube,发现STM32Cube生成的代码并不怎么好,官方的串口例程也折腾了一下,发现各种宏定义各种封装,而且代码不好用,比如一个简单的串口发送函数搞的如此复杂:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
所以STM32Cube软件只是用来看看引脚分配,非常直观效率高,还有生成的初始化代码也值得参考哦~~嘻嘻
      先给大家扫盲一下:
STM32F407xx内嵌四个通用同步/异步接收器(USART1,USART2,USART3 和USART6)和两个通用异步收发器(UART4和UART5)。这6个接口提供异步通信的IrDASIR ENDEC支持,多机通信模式,单线半双工通信模式LIN主/从功能。 USART1和USART6接口能够速度高达10.5 Mbit / s的通信其他可用的接口通信高达5.25bit/s。USART1,USART2,USART3和USART6还提供硬件管理的CTS,RTS信号,智能卡的模式(ISO7816兼容)和类似的SPI通信能力。所有接口都可以通过DMA控制器。
    硬件环境:STM32F4-Discovery
    软件环境:MDK510,STM32Cube
其他部分就不用介绍了吧,上个mdk的工程源代码:
(固件库V1.0.0+串口( printf重定向,格式输出)+LED+Kill.bat)
特别注意:在keil option 选项卡中,要选中Use MircoLib,否则编译后的代码将会很大,我试过差不多是原来的3倍。

/**********************************************************************************************
*函数名:USART_SentChar
* 参 数:USART_TypeDef* USARTx,unsigned char c
* 返回值:void
* 功能:向某个串口发送一个字符
**********************************************************************************************/
void USART_SentChar(USART_TypeDef* USARTx,unsigned char c)
{
    USART_SendData(USARTx, c);
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
}

/***********************************************************************************************
*函数名:USART_SendString()
* 参数:USART_TypeDef* USARTx 所要发送到的串口的指针,u8 *str 指向发送的字符串的指针
* 返回值:void
* 功能:向某个串口发送一个字符串
************************************************************************************************/
void USART_SendString(USART_TypeDef* USARTx,u8 *str)
{
while(*str)
{
       USART_SendData(USARTx,*str);                                                                                                           //将*str从USARTx发送出去
           while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);       //等待发送完毕
           str++;        //str的地址增加1,到下一个字符
}
}

/**********************************************************************************************
** 函数名   : fputc()
** 功能   :重定向C库函数printf到USART:重新定义stdio.h中的fputc()函数,使printf()输出到USART
** 输入   :int ch,FILE *f
** 输出   :int ch
** 使用说明 :
**          Example:printf("i=%d,ch=%c\n",i,ch);
                        printf("\r\n LCD驱动IC为:%x \r\n",0x55);
%d:按10进制有符号整数实际长度输出
        %u:按10进制无符号整数实际长度输出
        %o:按8进制数据实际长度输出
        %x:按16进制数据实际长度输出
        %c:输出一个字符
        %s:输出一个字符串
************************************************************************************************/
int fputc(int ch,FILE *f)
{
USART_SendData(USART2,(u8)ch);                             //将ch从USART1发送出去
while (!(USART2->SR & USART_FLAG_TXE));                                     //等待发送完毕                                                                          
return ch;                                                                                                                                                 //返回 ch
}       

/***********************************************************************************************
* Function Name: int fgetc(FILE *f)
* Description    : Retargets the C library printf function to the USART.fgetc重定向
* Input          : None
* Output         : None
* Return         : 读取到的字符
************************************************************************************************/
int fgetc(FILE *f)
        {
        /* Loop until received a char */
        while(!(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET))
                {
                }       
        /* Read a character from the USART1 and RETURN */
        return (USART_ReceiveData(USART1));
        }

/***********************************************************************************************
* 函数名:itoa
* 描述:将整形数据转换成字符串
* 输入:-radix =10 表示10进制,其他结果为0
*         -value 要转换的整形数
*         -buf 转换后的字符串
*         -radix = 10
* 输出:无
* 返回:无
* 调用:被USART2_printf()调用
************************************************************************************************/
static char *itoa(int value, char *string, int radix)
{
    int   i, d;
    int   flag = 0;
    char    *ptr = string;
    /* This implementation only works for decimal numbers. */
    if (radix != 10)
    {
      *ptr = 0;
      return string;
    }
    if (!value)
    {
      *ptr++ = 0x30;
      *ptr = 0;
      return string;
    }
    /* if this is a negative value insert the minus sign. */
    if (value < 0)
    {
      *ptr++ = '-';
      /* Make the value positive. */
      value *= -1;
    }

    for (i = 10000; i > 0; i /= 10)
    {
      d = value / i;

      if (d || flag)
      {
            *ptr++ = (char)(d + 0x30);
            value -= (d * i);
            flag = 1;
      }
    }

    /* Null terminate the string. */
    *ptr = 0;

    return string;

} /* NCL_Itoa */

/***********************************************************************************************
* 函数名:USART2_printf
* 描述:格式化输出,类似于C库中的printf,但这里没有用到C库
* 输入:-USARTx 串口通道,这里只用到了串口2,即USART2
*                     -Data   要发送到串口的内容的指针
*                           -...    其他参数
* 输出:无
* 返回:无
* 调用:外部调用
*         典型应用USART2_printf( USART2, "\r\n this is a demo \r\n" );
*                           USART2_printf( USART2, "\r\n %d \r\n", i );
*                           USART2_printf( USART2, "\r\n %s \r\n", j );
************************************************************************************************/
void USART2_printf(USART_TypeDef* USARTx, uint8_t *Data,...)
{
        const char *s;
int d;   
char buf;

va_list ap;
va_start(ap, Data);

        while ( *Data != 0)   // 判断是否到达字符串结束符
        {                                                          
                if ( *Data == 0x5c )//'\'
                {                                                                          
                        switch ( *++Data )
                        {
                                case 'r':                                                                //回车符
                                        USART_SendData(USARTx, 0x0d);
                                        Data ++;
                                        break;

                                case 'n':                                                                //换行符
                                        USART_SendData(USARTx, 0x0a);       
                                        Data ++;
                                        break;
                               
                                default:
                                        Data ++;
                                   break;
                        }                       
                }
                else if ( *Data == '%')
                {                                                                          //
                        switch ( *++Data )
                        {                               
                                case 's':                                                                                  //字符串
                                        s = va_arg(ap, const char *);
          for ( ; *s; s++)
                                        {
                                                USART_SendData(USARTx,*s);
                                                while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
          }
                                        Data++;
          break;

      case 'd':                                                                                //十进制
          d = va_arg(ap, int);
          itoa(d, buf, 10);
          for (s = buf; *s; s++)
                                        {
                                                USART_SendData(USARTx,*s);
                                                while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
          }
                                        Data++;
          break;
                               default:
                                                Data++;
                                  break;
                        }               
                } /* end of else if */
                else USART_SendData(USARTx, *Data++);
                while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
        }
}

caizhiwei 发表于 2014-5-15 21:27:51


哈哈

qiqirachel 发表于 2014-5-15 21:31:12

以后会用上,现在先顶起,爪印!!~~~

caizhiwei 发表于 2014-6-2 18:22:07

代码今天更新了一下,以前的工程目录结构太难看,调整了!新版下载:


bygreencn 发表于 2014-6-2 22:19:19

官方没有么?我怎么就在找到了

caizhiwei 发表于 2014-7-2 10:01:18

bygreencn 发表于 2014-6-2 22:19
官方没有么?我怎么就在找到了

嘿嘿,看看我这个是不是比官方的好得多咧???

caizhiwei 发表于 2014-7-2 10:08:10

bygreencn 发表于 2014-6-2 22:19
官方没有么?我怎么就在找到了

不过官方确实没有!!!差点被你迷惑了!!!

bygreencn 发表于 2014-7-3 12:46:45

caizhiwei 发表于 2014-7-2 10:08
不过官方确实没有!!!差点被你迷惑了!!!

你真聪明,没人迷惑得了你!!!!!!!

MDK 添加RETARGET.C,自己写完fputc和fgetc另外两三个函数就出来了,不追求效率用不着连库一起写,对吧

咋样,迷惑不

caizhiwei 发表于 2014-7-3 22:50:12

bygreencn 发表于 2014-7-3 12:46
你真聪明,没人迷惑得了你!!!!!!!

MDK 添加RETARGET.C,自己写完fputc和fgetc另外两三个函数就出 ...

知道你牛逼,对你没用!但是我也贡献了代码,造福其他网友!你就别在这里说风凉话了,滚一边去~~~

bygreencn 发表于 2014-7-3 22:55:59

本帖最后由 bygreencn 于 2014-7-3 22:59 编辑

caizhiwei 发表于 2014-7-3 22:50
知道你牛逼,对你没用!但是我也贡献了代码,造福其他网友!你就别在这里说风凉话了,滚一边去~~~ ...

你就一SB,一瓶子不满,半瓶子咣当

caizhiwei 发表于 2014-7-3 23:08:59

bygreencn 发表于 2014-7-3 22:55
你就一SB,一瓶子不满,半瓶子咣当

别骂人好不好?试问一下你分享过代码吗?自私的家伙!我分享有错吗?小心amo帮你号封掉~~

bygreencn 发表于 2014-7-4 13:48:03

caizhiwei 发表于 2014-7-3 23:08
别骂人好不好?试问一下你分享过代码吗?自私的家伙!我分享有错吗?小心amo帮你号封掉~~
...

滚犊子,丫先满口损人话,这会儿跑来教训我,你丫什么玩意,扯JB蛋,滚远点。

caizhiwei 发表于 2014-7-4 16:10:16

bygreencn 发表于 2014-7-4 13:48
滚犊子,丫先满口损人话,这会儿跑来教训我,你丫什么玩意,扯JB蛋,滚远点。 ...

哎,和气生财,不想和你争了,就此打住吧,注意你研究生的素质!

zcan 发表于 2014-7-21 23:32:05

淡定 和楼主一样的问题 但是这个库里面没有USART_SendData(USARTx, c);
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); 这些函数呀?

zcan 发表于 2014-7-21 23:35:47

本帖最后由 zcan 于 2014-7-21 23:37 编辑

下载了你传的程序 你用的库和你说的HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) 所在的库 不是一个版本库的吧我用的是

* @file    stm32f4xx_hal_uart.c
* @authorMCD Application Team
* @version V1.0.0
* @date    18-February-2014
* @brief   UART HAL module driver.

caizhiwei 发表于 2014-7-22 12:08:22

zcan 发表于 2014-7-21 23:35
下载了你传的程序 你用的库和你说的HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint ...

工程用的是 普通库,不是cube里自带的库哦

zcan 发表于 2014-7-23 11:05:11

caizhiwei 发表于 2014-7-22 12:08
工程用的是 普通库,不是cube里自带的库哦

嗯 普通库我也有 但是年份太久 用新库安心点{:titter:}

yixin1851 发表于 2024-1-1 12:33:28

感谢楼主,请问原来开发板上没有串口(只是预留了UART IO),楼主是在另外接了串口外设吗?
页: [1]
查看完整版本: 分享一个官方没有的stm32f4-Discovery的串口例程