打印

stm32 固件库之:uart

[复制链接]
233|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
喷水壶|  楼主 | 2018-8-22 10:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1. 简介:自己写此部分的程序即耗时,也不明智,因此,此篇**是关于移植和分析的**



2. 移植 uart 程序:
        参照的程序是 红牛开发板/例程-Example/二、基础例程/ 下的有关 usart 部分

在做uart部分之前,需要参照之前章程搭建固件库和FreeRTOS工程,搭建完成之后,将上边目录下的 driver 中的 driver 中的delay.c、delay.h、USART.c、USART.h拷贝到 PROJ\uart 目录下,部分截图如下:



<img id="aimg_iRr9B"  class="zoom" file="http://img.blog.csdn.net/20161130232329921"  lazyloadthumb="1" border="0" alt="" /><img id="aimg_ftBcb"  class="zoom" file="http://img.blog.csdn.net/20161130232402352"  lazyloadthumb="1" border="0" alt="" />



在iar软件中,将新添加的两个 .c 文件放到usr目录下:



<img id="aimg_JB8Zv"  class="zoom" file="http://img.blog.csdn.net/20161130232507462"  lazyloadthumb="1" border="0" alt="" />



在包含进 .c 后还需要添加他们相应的 .h 文件的搜索路径:...PROJ\uart\driver



<img id="aimg_EZ4FP"  class="zoom" file="http://img.blog.csdn.net/20161130232841865"  lazyloadthumb="1" border="0" alt="" />



在程序中我们用到了 printf ,这个函数需要 Full 版本library 的支持:



<img id="aimg_eD0qW"  class="zoom" file="http://img.blog.csdn.net/20161130233206170"  lazyloadthumb="1" border="0" alt="" />



主函数 main.c



[cpp] view plain copy

print?<img id="aimg_c4xMd"  class="zoom" width="12" height="12" file="https://code.csdn.net/assets/CODE_ico.png" border="0" alt="" /><img id="aimg_eE8SR"  class="zoom" width="12" height="12" file="https://code.csdn.net/assets/ico_fork.svg" border="0" alt="" />



#include <stdio.h>    #include "misc.h"    /* Scheduler includes. */  #include "FreeRTOS.h"  #include "task.h"  #include "queue.h"  #include "USART.h"  #include "delay.h"    #define LED_D1_ON() GPIO_ResetBits(GPIOF, GPIO_Pin_6)  #define LED_D1_OFF() GPIO_SetBits(GPIOF, GPIO_Pin_6)    static void LED_Init(void);  static void LED_D1_Task(void *pvParameters);  static void UART1_Task(void *pvParameters);    int main(void)  {      LED_Init(); // 初始化 LED 引脚      USART1_Init();      Delay_Init();        Delay_ms(10);            SendMessage();      printf("write by lip!\n\r");                xTaskCreate(LED_D1_Task, "LED_D1", 1000, NULL, 3, NULL);      xTaskCreate(UART1_Task, "UART1", 1000, NULL, tskIDLE_PRIORITY + 3, NULL);            /* 启动调度器 */      vTaskStartScheduler();      while(1);        return 0;  }    void LED_Init(void)  {      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE); // 使能 GPIOF 的时钟         GPIO_InitTypeDef GPIO_InitStructure;      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;      GPIO_Init(GPIOF, &GPIO_InitStructure);  }    void LED_D1_Task(void *pvParameters)  {      while ( 1 )      {          LED_D1_ON();          vTaskDelay(500 / portTICK_RATE_MS);          LED_D1_OFF();          vTaskDelay(500 / portTICK_RATE_MS);              }  }    void UART1_Task(void *pvParameters)  {      while(1)      {          vTaskDelay(100 / portTICK_RATE_MS);            if(data_length)          {              USART1_SendString(rx_buffer, data_length);                 data_length = 0;          }      }  }  





我们还需要在 usr 目录下 stm32f10x_it.c 中实现一下 usart 的中断入口,以便支持用户的输入:

在 void NMI_Handler(void) 函数上边添加:



[cpp] view plain copy

print?<img id="aimg_W7UU8"  class="zoom" width="12" height="12" file="https://code.csdn.net/assets/CODE_ico.png" border="0" alt="" /><img id="aimg_x5EEE"  class="zoom" width="12" height="12" file="https://code.csdn.net/assets/ico_fork.svg" border="0" alt="" />



void USART1_IRQHandler(void)  {      u8 res;           if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 接收到数据      {                 res = USART_ReceiveData(USART1); // 读取接收到的数据USART1->DR          if(data_length < DATA_BUF_SIZE)          {              rx_buffer[data_length] = res; // 记录接收到的值              data_length++;          }      }  }  





当然 .h 中的声明不要忘记:



<img id="aimg_hnlCE"  class="zoom" file="http://img.blog.csdn.net/20161130233817735"  lazyloadthumb="1" border="0" alt="" />




至此,可以 make、下载了,用串口助手连接上串口一,在开机的瞬间会看到打印一串的数据,并等待用户输入,当用户输入时,会原封不动的打印出来。





<img id="aimg_TmXjC"  class="zoom" file="http://img.blog.csdn.net/20161204192356334"  lazyloadthumb="1" border="0" alt="" />



【1】为了尊重源作者,打印信息并没有大范围改动





3. 分析固件库中的 delay 延时:
        delay 函数的实现应用的是 m3 核的 systick,是一个硬件部分,一个 24 位的倒计数定时器,当倒计时到0值时会从LOAD寄存器装载新值,还有一点的是当enable不清零的情况,他的运作就不会停息

涉及到固件库中的结构体如下:



[cpp] view plain copy

print?<img id="aimg_Frq56"  class="zoom" width="12" height="12" file="https://code.csdn.net/assets/CODE_ico.png" border="0" alt="" /><img id="aimg_UtNYQ"  class="zoom" width="12" height="12" file="https://code.csdn.net/assets/ico_fork.svg" border="0" alt="" />



#define __IO volatile  typedef struct  {    __IO uint32_t CTRL;  /* Offset: 0x00  SysTick Control and Status Register */    __IO uint32_t LOAD;  /* Offset: 0x04  SysTick Reload Value Register       */    __IO uint32_t VAL;   /* Offset: 0x08  SysTick Current Value Register      */    __I  uint32_t CALIB; /* Offset: 0x0C  SysTick Calibration Register        */  } SysTick_Type;  



用于将首地址强制转化成此结构体,方便用户使用

SysTick寄存器说明如下:

【1】控制和状态寄存器 CTRL :



位段

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

433

主题

437

帖子

0

粉丝