Chinaunix首页 | 论坛 | 博客
  • 博客访问: 84617
  • 博文数量: 44
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 582
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-05 15:21
个人简介

读圣人书,明圣人志,遵圣人训。

文章分类

全部博文(44)

文章存档

2017年(23)

2016年(19)

2014年(2)

我的朋友

分类: 嵌入式

2016-11-25 21:24:17

  STM32CubeMX-[01]-UART
                                                               -------- 转载请注明出处
                                                               -------- 更多笔记请访问我的博客:merafour.blog.163.com
                                                               -------- 笔记同步论坛:
                                                                -------- 2016-11-24.冷月追风

                                                                -------- email 


            注:不特别声明的情况下不区分 UART跟 USART,统称 UART。 

        前段时间开发看到别人的代码里边好多 "HAL"开头的函数,后来网上查了才知道原来这是 HAL库,区别于我们之前所使用的标准库。HAL通过使用 STM32CubeMX图形化配置,并且自动生成初始化代码。其对底层的封装是标准库所不能比的。
        当然,封装有好处,但也有坏处。好处是对于底层硬件细节你不必再那么关心,掌握API即可开发。而坏处在于由于对底层进行抽象中间增加了很多代码,效率降低,代码大小增加。如果你需要写一个实时性比较高的程序,那么你还是得跳过 HAL直接操作底层,这个时候我就会通过 HAL来初始化硬件。
        使用 STM32CubeMX的另一个好处是:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
        STM32CubeMX为我们提供了 FreeRTOS,所以当我们需要使用操作系统的时候我们可以很方便地把 FreeRTOS添加到我们的工程,而我们需要做的只是勾选:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
FreeRTOS的 Enabled,后面就可以直接使用 FreeRTOS了。关于 OS我们后面在介绍,今天我们来说说我们的 UART。
        我们都知道,程序开发的第一课都是 "Hello World!",而单片机开发的第一课都是点亮 LED,但是我们先不说这个,可以在 UART中点一下。
        UART是我们做嵌入式开发过程中经常要用到的通讯接口,像现在比较流行的联网功能,通过添加一个 WiFi模块就可以进行互联,而单片机使用 USB的WiFi是吃不消的,这时候串口WiFi就很方便,通过 AT指令就可以操作,并且联网。下面我们就来了解下通过 STM32CubeMX如何使用串口。
         STM32CubeMX 的安装这里就先跳过了。

1. New Project 
        首先我们要通过 STM32CubeMX新建一个工程,根据自己的板子选择芯片:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
我的芯片为 STM32F030C8T6,选择上面的芯片。保存之后我们进入 Project-->Settings进行设置:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
然后我们点击 "Code Generator"标签,勾选:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
这个是个人建议,这样会将如 UART,SPI等单独房子 c源文件中,而且会自动备份相应的源码。保存之后我们先配置时钟:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
实际上我们直接在 HCLK这里直接输入48,然后敲回车就可以自动配置分频。如果大家要使用外部晶振在 RCC中先设置然后就可以在这里配置:
STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
配置好时钟之后就保存。我在使用过程中发现 STM32CubeMX容易闪退,所以修改之后及时保存。

2. 配置 UART 
        接下来我们配置 UART,
 STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
 
当我们使用一个外设的时候会在右侧显示出占用的引脚,这很容易发现端口冲突。另外,UART1默认使用 PA9,PA10,当我把 PA9跟 PA10占用的时候,再使用 UART1会自动映射到 PB7,PB7,即能够自动解决冲突。PC13是我所使用的板子上的一个 LED。PB8是因为我所使用的板子上 UART接了一个外设,需要通过 PB8拉低将外设停止工作便于我们测试UART。
        下面我们来对串口进行配置。
*STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
设置波特率之后我们的UART就可以工作了。
*STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
点击最右边这个按钮生成我们的代码,生成之后我们会看到:
*STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
直接打开工程,会自动调用我们安装好的编译器。
生成工程后打开我们可以看到器工程视图:
*STM32CubeMX-[01]-UART-Poll - 乐山居士 - 有生之年
HAL下面就是我们的 HAL库。main函数为:
 int main(void)
{
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
   
然后我们增加串口测试代码:
 int main(void)
{
uint8_t pData=0;
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
HAL_UART_Transmit(&huart2, "Hello\r\n", 7, 100);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if(HAL_OK == HAL_UART_Receive(&huart2, &pData, 1, 100))
{
//HAL_UART_Transmit(&huart2, &pData, 1, 10);
HAL_UART_Transmit(&huart2, &pData, 1, 0);
}
/* USER CODE BEGIN 3 */
}
}
   
编译之后下载就可以测试了。
        要注意的是,HAL_UART_Transmit的第四个参数Timeout不能随便给,否则很容易挂掉。原因我想跟它的 __HAL_LOCK宏有关:
 #define __HAL_LOCK(__HANDLE__) \
do{ \
if((__HANDLE__)->Lock == HAL_LOCKED) \
{ \
return HAL_BUSY; \
} \
else \
{ \
(__HANDLE__)->Lock = HAL_LOCKED; \
} \
}while (0)

#define __HAL_UNLOCK(__HANDLE__) \
do{ \
(__HANDLE__)->Lock = HAL_UNLOCKED; \
}while (0)
   
虽说轮训的方式接收数据不存在抢占,但发送设置超时确实多接收几个数据就接收不到了。
        如你所看到的,我们值添加了几行代码就使用了串口,这就是使用 MX的便捷。不过凡事都是利弊共存的。
3. LED 
         面我们来增加LED的功能。
        我们只需将主循环改为:
 while (1)
{
/* USER CODE END WHILE */
if(HAL_OK == HAL_UART_Receive(&huart2, &pData, 1, 1))
{
//HAL_UART_Transmit(&huart2, &pData, 1, 10);
HAL_UART_Transmit(&huart2, &pData, 1, 0);
}
flash++;
if(flash>200)
{
flash=0;
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
//HAL_Delay(1);
/* USER CODE BEGIN 3 */
}
   
然后再定义 "uint16_t flash=0;",编译下载就可以看到 LED在闪烁了,而且发数据的时候闪烁频率加快,原因是收到数据 HAL_UART_Receive函数提前返回。

参考:
STM32CubeMX: http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html
STM32cube中文网: http://www.stm32cube.com/
STM32CubeMX介绍、下载与安装: http://blog.csdn.net/ybhuangfugui/article/details/52225736 
在Linux下使用STM32CubeMX开发和调试STM32:
STM32Cube initialization code generator:http://www.st.com/content/ccc/resource/technical/document/user_manual/10/c5/1a/43/3a/70/43/7d/DM00104712.pdf/files/DM00104712.pdf/jcr:content/translations/en.DM00104712.pdf
阅读(2613) | 评论(0) | 转发(0) |
0

上一篇:PX4编译脚本

下一篇:STM32CubeMX-[01]-UART-INT

给主人留下些什么吧!~~