|
(固件库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[16];
- 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 );
- }
- }
复制代码 |
|