分享一个官方没有的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 );
}
}
哈哈 以后会用上,现在先顶起,爪印!!~~~
代码今天更新了一下,以前的工程目录结构太难看,调整了!新版下载:
官方没有么?我怎么就在找到了 bygreencn 发表于 2014-6-2 22:19
官方没有么?我怎么就在找到了
嘿嘿,看看我这个是不是比官方的好得多咧??? bygreencn 发表于 2014-6-2 22:19
官方没有么?我怎么就在找到了
不过官方确实没有!!!差点被你迷惑了!!! caizhiwei 发表于 2014-7-2 10:08
不过官方确实没有!!!差点被你迷惑了!!!
你真聪明,没人迷惑得了你!!!!!!!
MDK 添加RETARGET.C,自己写完fputc和fgetc另外两三个函数就出来了,不追求效率用不着连库一起写,对吧
咋样,迷惑不 bygreencn 发表于 2014-7-3 12:46
你真聪明,没人迷惑得了你!!!!!!!
MDK 添加RETARGET.C,自己写完fputc和fgetc另外两三个函数就出 ...
知道你牛逼,对你没用!但是我也贡献了代码,造福其他网友!你就别在这里说风凉话了,滚一边去~~~ 本帖最后由 bygreencn 于 2014-7-3 22:59 编辑
caizhiwei 发表于 2014-7-3 22:50
知道你牛逼,对你没用!但是我也贡献了代码,造福其他网友!你就别在这里说风凉话了,滚一边去~~~ ...
你就一SB,一瓶子不满,半瓶子咣当 bygreencn 发表于 2014-7-3 22:55
你就一SB,一瓶子不满,半瓶子咣当
别骂人好不好?试问一下你分享过代码吗?自私的家伙!我分享有错吗?小心amo帮你号封掉~~
caizhiwei 发表于 2014-7-3 23:08
别骂人好不好?试问一下你分享过代码吗?自私的家伙!我分享有错吗?小心amo帮你号封掉~~
...
滚犊子,丫先满口损人话,这会儿跑来教训我,你丫什么玩意,扯JB蛋,滚远点。 bygreencn 发表于 2014-7-4 13:48
滚犊子,丫先满口损人话,这会儿跑来教训我,你丫什么玩意,扯JB蛋,滚远点。 ...
哎,和气生财,不想和你争了,就此打住吧,注意你研究生的素质! 淡定 和楼主一样的问题 但是这个库里面没有USART_SendData(USARTx, c);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); 这些函数呀? 本帖最后由 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.
zcan 发表于 2014-7-21 23:35
下载了你传的程序 你用的库和你说的HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint ...
工程用的是 普通库,不是cube里自带的库哦 caizhiwei 发表于 2014-7-22 12:08
工程用的是 普通库,不是cube里自带的库哦
嗯 普通库我也有 但是年份太久 用新库安心点{:titter:} 感谢楼主,请问原来开发板上没有串口(只是预留了UART IO),楼主是在另外接了串口外设吗?
页:
[1]