coocox学习笔记-串口
来源:互联网 发布:淘宝贷款利息是多少 编辑:程序博客网 时间:2024/06/13 07:44
CoIDE版本:CoIDE-V2Beta
编译器版本:gcc-arm-none-eabi-5_2-2015q4
目标板:STM32F030C8T6
之前一直使用MDK开发STM32应用程序,近日想尝试下gcc编译STM32,享受下开源的果实,于是乎在网上了解到了coocox,它有一个CoIDE用来编辑代码,是简版的eclipse,目前最新版为V2Beta,之前用eclipse生成注释很方便,所以就想试试CoIDE是否也可以,但尝试了半天也没搞定,始终无法自动生成注释。。。
coocox使用的STM32库代码是cube库而不是std标准库,看来是紧跟ST的步伐那,还好之前也使用过cube库,更加方便了coocox的上手,在CoIDE上设置好编译器路径,这个在coocox的官网上有介绍,很简单。
创建好一个STM32F030C8T6的工程,在Repository页面上添加cmsis_core、STM32F030x8_CUBELIB组件,使用coocox必须要了解的一个概念是Components(组件),它把库,驱动,OS,启动代码等抽象为组件,使用时直接添加即可,同时在组件中也配有示例代码,本例创建了一个USART的工程,添加完组件后会在工程目录下产生一个components的目录,里面存放我们添加的组件文件,目前该工程为空工程,添加两个文件uart.c、uart.h文件,工程组织如下:
uart.c和uart.h文件是从之前学习cube库时使用的直接拷贝过来稍作修改即可,uart.c代码如下:
#include "UART.h"#include "stm32f0xx_hal_def.h"UART_HandleTypeDef uartHandle;uint8_t aRxBuffer[BUFFSIZE];uint8_t aTxBuffer[BUFFSIZE];struct uart uart_rev;void HAL_UART_MspInit(UART_HandleTypeDef *huart){ GPIO_InitTypeDef GPIO_InitStruct;/*##-1- Enable peripherals and GPIO Clocks #################################*//* Enable GPIO TX/RX clock */USARTx_TX_GPIO_CLK_ENABLE();USARTx_RX_GPIO_CLK_ENABLE();/* Enable USART2 clock */USARTx_CLK_ENABLE(); /*##-2- Configure peripheral GPIO ##########################################*/ /* UART TX GPIO pin configuration */GPIO_InitStruct.Pin = USARTx_TX_PIN;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;GPIO_InitStruct.Alternate = USARTx_TX_AF;HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);/* UART RX GPIO pin configuration */GPIO_InitStruct.Pin = USARTx_RX_PIN;GPIO_InitStruct.Alternate = USARTx_RX_AF;HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);/*##-3- Configure the NVIC for UART ########################################*//* NVIC for USART2 */HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);HAL_NVIC_EnableIRQ(USARTx_IRQn);}/** * @brief UART MSP De-Initialization * This function frees the hardware resources used in this example: * - Disable the Peripheral's clock * - Revert GPIO and NVIC configuration to their default state * @param huart: UART handle pointer * @retval None */void HAL_UART_MspDeInit(UART_HandleTypeDef *huart){/*##-1- Reset peripherals ##################################################*/USARTx_FORCE_RESET();USARTx_RELEASE_RESET();/*##-2- Disable peripherals and GPIO Clocks #################################*//* Configure UART Tx as alternate function */HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);/* Configure UART Rx as alternate function */HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);/*##-3- Disable the NVIC for UART ##########################################*/HAL_NVIC_DisableIRQ(USARTx_IRQn);}/**********************************************************************函数:uart_init()函数作用:串口初始化参数:uint32_t BaudRate=========================串口波特率返回值:无上一版本:无当前版本:1.0作者:最后修改时间:2015-04-02说明: **********************************************************************/void uart_init(uint32_t BaudRate){ uartHandle.Instance = USARTx; uartHandle.Init.BaudRate = BaudRate; uartHandle.Init.WordLength = UART_WORDLENGTH_8B; uartHandle.Init.StopBits = UART_STOPBITS_1; uartHandle.Init.Parity = UART_PARITY_NONE; uartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; uartHandle.Init.Mode = UART_MODE_TX_RX; if(HAL_UART_Init(&uartHandle) != HAL_OK) { Error_Handler(); }uart_rev.front = aRxBuffer;uart_rev.rear = aRxBuffer;//两个指针指向相同的地址空间if(HAL_UART_Receive_IT(&uartHandle,(uint8_t*)aRxBuffer,1) != HAL_OK){Error_Handler();}}void Error_Handler(void){ while(1) { }}/**********************************************************************函数:uart_read()函数作用:从接收缓冲区中读取数据参数:uint8_t *fmt--------------------------------接收到的数据uint16_t time_out---------------------------超时时间返回值:0:读取到数据-1:没有读取到数据上一版本:无当前版本:1.0作者:最后修改时间:2015-04-08说明: **********************************************************************/int8_t uart_read(uint8_t *fmt, uint16_t time_out){while(time_out){if(uart_rev.front != uart_rev.rear){//如果队首指针和队尾指针不同表明缓冲区中有数据还未收取*fmt=*uart_rev.front;uart_rev.front++;if (uart_rev.front >= (aRxBuffer+BUFFSIZE))uart_rev.front = aRxBuffer;return 0;}time_out--;}return (int8_t)-1;}/**********************************************************************函数:uart_char()函数作用:发送一个字节数据参数:uint8_t *fmt--------------------------------接收到的数据返回值:上一版本:无当前版本:1.0作者:最后修改时间:2015-04-08说明: **********************************************************************/void uart_char(uint8_t fmt){uartHandle.Instance->TDR = fmt;while(!(uartHandle.Instance->ISR & USART_ISR_TXE));}void uart_send(uint8_t *fmt, uint16_t len){while(len){uart_char(*fmt);fmt++;len--;}return ;}/***********************************************************************************函数:fputc(int ch, FILE *f)功能:重载标准函数里面的输入输出函数参数:无版本:V0.0.0作者:备注:************************************************************************************/#if defined(UART_DEBUG)int fputc(int ch, FILE *f){USARTx->TDR = ch;while(!(USARTx->ISR & USART_ISR_TXE));return ch;}#endif/** * @brief UART error callbacks * @param UartHandle: UART handle * @note This example shows a simple way to report transfer error, and you can * add your own implementation. * @retval None */void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart){}/** * @brief Tx Transfer completed callback * @param UartHandle: UART handle. * @note This example shows a simple way to report end of IT Tx transfer, and * you can add your own implementation. * @retval None */void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart){}/** * @brief Rx Transfer completed callback * @param UartHandle: UART handle * @note This example shows a simple way to report end of IT Rx transfer, and * you can add your own implementation. * @retval None */void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){/* Set transmission flag: trasfer complete*/uart_rev.rear++;//更新rear指针if(uart_rev.rear >= (aRxBuffer + BUFFSIZE))uart_rev.rear = aRxBuffer;HAL_UART_Receive_IT(huart,uart_rev.rear,1);}/******************************************************************************//* STM32L0xx Peripherals Interrupt Handlers *//* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the *//* available peripheral interrupt handler's name please refer to the startup *//* file (startup_stm32l0xx.s). *//******************************************************************************//** * @brief This function handles UART interrupt request. * @param None * @retval None * @Note This function is redefined in "main.h" and related to DMA stream * used for USART data transmission */void USARTx_IRQHandler(void){ HAL_UART_IRQHandler(& uartHandle);}uart.h代码如下:
#ifndef __UART_H__#define __UART_H__#include "stm32f0xx_hal.h"#include "stm32f0xx_hal_def.h"#include "stm32f0xx_hal_uart.h"#define UART_DEBUG//#undef UART_DEBUG#ifdef UART_DEBUG#include <stdio.h>#include <stdarg.h>#endifstruct uart{uint8_t *rear;//在中断函数中更改uint8_t *front;//在主循环中更改};#define USARTx USART1#define USARTx_CLK_ENABLE() __USART1_CLK_ENABLE()#define USARTx_RX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()#define USARTx_TX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() #define USARTx_FORCE_RESET() __USART1_FORCE_RESET()#define USARTx_RELEASE_RESET() __USART1_RELEASE_RESET()/* Definition for USARTx Pins */#define USARTx_TX_PIN GPIO_PIN_9#define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_AF GPIO_AF1_USART1#define USARTx_RX_PIN GPIO_PIN_10#define USARTx_RX_GPIO_PORT GPIOA #define USARTx_RX_AF GPIO_AF1_USART1/* Definition for USARTx's NVIC */#define USARTx_IRQn USART1_IRQn#define USARTx_IRQHandler USART1_IRQHandler#define BUFFSIZE 500void HAL_UART_MspInit(UART_HandleTypeDef * huart);void HAL_UART_MspDeInit(UART_HandleTypeDef * huart);void uart_init(uint32_t BaudRate);int8_t uart_read(uint8_t *fmt, uint16_t time_out);void uart_char(uint8_t fmt);void uart_send(uint8_t *fmt, uint16_t len);void Error_Handler(void);void USARTx_IRQHandler(void);#endif</span>主函数稍作修改即可,由于在uart中已经定义了Error_Handler()方法,因此把main.c中的删掉并添加uart的初始化代码,如下
<span style="font-size:14px;">/* Add your application code here*/uart_init(115200);/* Infinite loop */while (1){uart_send("1234567890\r\n",12);HAL_Delay(500);}编译并下载代码到目标板运行,结果如下:
运行正常。
串口正常以后,就在想在coocox中如何使用printf函数呢,即把printf函数重定向到串口上,刚好在coocox的组件中有一个组件为Retarget_printf,添加该组件到工程中,该组件中有一个printf.c文件,用户需要去实现PrintChar(char c)函数,我们把在uart.c文件中的fputc函数替换成PrintChar(char c)函数,如下:
#if defined(UART_DEBUG)void PrintChar(char c){USARTx->TDR = c;while(!(USARTx->ISR & USART_ISR_TXE));return;}#endif在主函数中使用printf来打印信息,编译后发现一个错误,提示impure_ptr重复定义,在coocox官网中也有人遇到说是因为使用了标准的系统启动文件,在配置选项中勾选不使用标准的系统启动文件,如下:
再次编译提示位定义_init,在main.c文件中添加一个空的_init()函数,编译通过,下载运行,发现没有换行,如下:
0x0A字符没有输出,不得不说printf.c文件实现还是有些小问题的,解决办法是把"\r\n"放在最前面即可
while (1){printf("\r\n1234567890");HAL_Delay(500);}此时输出的信息是正常的,同时我们也可以格式化输出字符或整型值,但目前printf.c文件不支持浮点型数据输出,可以查看printf.c文件如下:
这个问题,coocox官网上有说不使用printf.c文件而是使用C库实现。我想修改下printf.c文件应该也是可以的。输出整型值如下:
浮点数支持的话,自己动手修改printf.c文件貌似比较费时间,还是用C库吧,毕竟之前MDK都是用的C库也,在工程中移除Retarget_printf组件,添加C_library组件,里面有一个syscalls.c文件,提供给用户一个_write接口,由于在CoIDE中所有组件文件都是上锁的,因此我们在外部用文本编辑器修改syscalls.c文件的_write函数,把宏打开,如下
/*Low layer write(output) function*/__attribute__ ((used))int _write(int file, char *ptr, int len){#if 1 //user code example int i; (void)file; for(i = 0; i < len; i++) { // UART_PutChar is user's basic output function UART_PutChar(*ptr++); }#endif return len;}用户需要实现UART_PutChar()方法,把之前uart.c文件中的PutChar()方法换个名字就行了。由于使用到了C库,因此在配置选项的Link页面勾选使用Nano C库,如下:
还要使能Print float选项,由于不再使用Retarget_printf组件,所以这里使用了标准的系统启动文件,同时把main.c文件中的_init()方法删掉了。
编辑主函数测试代码:
while (1){printf("\r\n1234567890");printf("\r\nvalue=%d,%X",100,100);printf("\r\nabc:%f",123.56);HAL_Delay(500);}下载到目标板,运行,测试正常
至此,可以很方便地调试代码啦!
- coocox学习笔记-串口
- 串口学习笔记(一)
- 串口通讯学习笔记
- STM32学习笔记-串口
- 串口学习笔记
- s3c2440学习笔记 串口
- ARM学习笔记---串口
- STM32-串口实验学习笔记
- 串口学习笔记源码 VS2010
- C#串口学习笔记【1】
- C# 串口通信 学习笔记
- LPC11E68串口USART1学习笔记
- stm8s串口奇偶校验学习笔记
- qt串口通信学习笔记
- STM8学习笔记---串口uart1
- MFC学习笔记-串口通信
- STM32入门学习之USART(STM32F030F4P6基于CooCox IDE)
- STM32入门学习之ADC(STM32F030F4P6基于CooCox IDE)
- php文字替换表情
- CodeForces 368A Sereja and Coat Rack
- android shape的使用
- 2.6锁对象的改变
- SpringMVC基础Demo—创建RESTService
- coocox学习笔记-串口
- 在windows下用浏览器无法访问虚拟机中Linux的hadoop管理页面
- Android EditText 自定义控件 带消除功能
- MYSQL基础速成: 下载,安装,配置,远程登陆, 建数据库,建表
- AlertDialog的样式修改
- Remix OS For Pc 桌面版
- Dialog dismiss 和 cancel的区别
- ffmpeg综合应用示例(四)——摄像头直播的视音频同步
- leveldb代码阅读(9)——levedb的快照