STM32和emWin必须知道的那些事

这篇具有很好参考价值的文章主要介绍了STM32和emWin必须知道的那些事。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

emWin 是由德国 SEGGER 公司开发,可为图形 LCD 设计提供高级支持,极大简化了 LCD 设计。 为恩智浦ARM 微控制器用户免费提供的 emWin 图形库。

  在国内做嵌入式系统的大部分都使用 emwin, 其简单来说就是一套图形库。

  STemWin是SEGGER公司授权给ST(意法半导体)的。使用ST芯片的用户可以免费使用STemWin。其实不光授权给了ST,还有NXP,Energy Micro等。凡是使用这些芯片厂商生产的处理器都可以免费的使用emWin。但是出于一定的保护措施,使用STemWin的库是不能用在其它芯片厂商的处理器上面的。因为在工程初始化STemWin前要使能CRC校验。如果没有使能,STemWin是启动不起来的。

  STemWin还针对ST的微控制器做了专门的优化,比如在使用ST的F4XX微控制器带FPU的芯片时,STemWin在需要浮点处理的地方专门做了优化。

本文详细介绍了在STM32F1xx开发板上移植STemWin的步骤。

(1)上st.com官网下载STemWin的压缩包:

打开浏览器,输入地址 https://www.st.com/zh/embedded-software/stemwin.html ,打开STemWin官网界面如下:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

点击界面上的“获取软件”链接,进入软件下载部分:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

点击“Get latest”红色按钮,弹出许可协议按钮:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

点击“接受”蓝色按钮,如果登录了,则直接开始下载,如果没有登录,则需要登录 my.st.com 账号,没有账号,注册一个账号再登录即可下载。

下载得到“en.stemwin.zip”压缩文件,解压后得到“STemWin_Library_V1.2.0”文件夹,包含以下4个文件夹:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档
  • _htmresc //ST的logo图片;

  • Libraries //各种源码库文件,详见下文;

  • Project //各个官方开发板下的程序例程;

  • Utilites //一些工具代码;

  • Release_Notes.html //版本说明连接。

跟移植STemWin有关的是Libraries文件夹。Libraries文件夹打开后如下:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档
  • CMSIS //存放符合CMSIS标准的文件,包括STM32启动文件、ARM Cortex内核文件和对应外设头文件stm32fxxx.h;

  • STemWinLibrary532 //EmWin的库文件;

  • STM32FXXX_StdPeriph_Driver //存放STM32外设驱动文件,inc目录用于存放外设的头文件,src目录用于存放外设的源文件。

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

跟移植STemWin有关的是4个文件夹:Config、inc、Lib、和OS。另外Documentation文件夹中有STemWin的参考手册,Simulation文件夹中有关于PC端仿真用到的vs工程文件,Software中有一些工具软件。

(2)拷贝相关的STemWin库文件和文件夹到uVision5的项目目录

要将STemWin库移植到我们自己的STM32程序中,需要将Config、inc、Lib、和OS这4个文件夹拷贝到我们自己的项目文件夹下,例如,在项目根目录下建立一个STemWin目录,然后,将这4个文件夹拷贝进去:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

在Lib文件夹中,包含了所有STM32芯片的ARM核的库文件,库文件的命名方式是“STemWin版本_ARM核_是否带OS_开发编译环境.a/lib”。

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

需要根据自己项目的芯片的ARM核选择不同的,不属于自己项目的芯片的ARM核的库文件可以直接删除。例如,我下面的例子是在STM32F103(CM3核)芯片的板子上,用uVision5(Keil),不带OS的环境下,将STemWin移植到我自己的项目中,所以,我只保留了STemWin532_CM3_Keil.lib文件,其它文件都删除了:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

至此,移植需要的STemWin的相关文件都已经拷贝到项目所在目录下,下一步是将需要添加到项目和需要修改的文件添加进项目。

我们可以在项目下建立一个Group,例如,我建立的Group是STemWin,然后,在STemWin中添加库中的6个文件如下:

Config\GUIConf.h

Config\GUIConf.c

Config\GUIDRV_Template.c

Config\LCDConf_FlexColor_Template.c

OS\GUI_X.c //GUI_X.c用于没有使用OS的程序的移植,如果使用了OS,需要改成OS\GUI_X_OS.c

Lib\STemWin532_CM3_Keil.lib

另外,还需要建立2个文件:

一个是空内容的文件LCDConf.h,这个文件放置在代码可以引用的位置,STemWin库会引用该文件,因此,必须创建一个该文件,其内容可以是空;

另一个文件是GUI_X_Touch_Analog.c,这个文件用于STemWin实现触摸屏操控。

至此,创建的Group结构如下:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

到这里,要移植的库文件已经全了,后面会说明如何修改这些文件。

(3)测试验证显示屏和触摸屏的驱动函数是否有效

要在STM32嵌入式系统上显示STemWin的界面,除了需要STemWin的库文件,还需要有显示屏的驱动文件和触摸屏的驱动文件。

STM32的显示屏的驱动有2种方式,一种是通过读写寄存器的方式实现LCD显示屏的显示,另一种是通过STM32的DMA2D图形加速功能的LTDC驱动程序实现LCD显示屏的显示。

移植STemWin时,要搞清楚板子的LCD屏使用的是那种驱动方式。不管LCD使用哪种驱动方式,都最好使用统一的接口,方便以后的代码复用。

STemWin种LCD的显示,主要调用2个函数,一个是LCD显示某个点的颜色的函数,一个是读取LCD某个点的颜色值的函数,另外,针对填充色块(FillRect)和显示位图(DrawBitLineXBPP)不同显示屏可能有些不同的优化函数,移植时,可以让STemWin调用这些优化函数。测试显示屏的显示某个点的颜色和读取某个点的颜色的驱动函数是否有效,以及填充色块和显示位图的驱动优化函数(如果有的话)是否有效。

STemWin对触摸屏的驱动函数的调用,只有4个:GUI_TOUCH_X_ActivateX、GUI_TOUCH_X_ActivateY、GUI_TOUCH_X_MeasureX、GUI_TOUCH_X_MeasureY,前2个函数是用于使能触摸屏的轴线,后面2个函数是用于获取触摸点在触摸屏上的轴坐标。测试触摸屏的驱动函数是否可以获取到触摸点在触摸屏上的横纵坐标。

显示屏的显示驱动函数和触摸驱动函数验证通过后,就可以修改拷贝过来的STemWin的库文件了。

(4)修改拷贝过来的STemWin的库文件

(4.1)GUIConf.h文件修改:

//这个文件主要配置一些功能开关,如下:

#define GUI_NUM_LAYERS        1      //UI层数,每层都可设置指定API
#define GUI_OS                (0)    //是否有OS
#define GUI_SUPPORT_TOUCH     (1)   //是否带触摸屏
#define GUI_DEFAULT_FONT      &GUI_Font6x8
#define GUI_SUPPORT_MOUSE     (1)    /* Support a mouse */
#define GUI_WINSUPPORT        (1)    /* Use window manager */
#define GUI_SUPPORT_MEMDEV    (1)    /* Memory device package available */
#define GUI_SUPPORT_DEVICES   (1)    /* Enable use of device pointers */

(4.2)GUIConf.c文件修改:

//本文件定义了GUI_X_Config函数,该函数会被STemWin的GUI_Init()函数调用,我们需要在该函数内为STemWin分配内存:

#define GUI_NUMBYTES    (20 * 1024) //20k内存很小,一般建议使用2M内存以上
//#define GUI_NUMBYTES    (2 * 1024 * 1024) __attribute__((at(0XC0000000))); //如果要在外部SDRAM上申请内存,可以通过at指定内存起始位置
#define GUI_BLOCKSIZE 0X80
U32 aMemory[GUI_NUMBYTES / 4];

void GUI_X_Config(void) {

  U32* aMemory2 = &aMemory[0];

  GUI_ALLOC_AssignMemory((U32*)aMemory2, GUI_NUMBYTES);
  GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);

  GUI_SetDefaultFont(GUI_FONT_6X8);    
}

(4.3)GUIDRV_Template.c文件修改:

//该文件内定义了STemWin调用显示驱动函数在显示屏上显示的函数,必须修改的函数有2个(_SetPixelIndex和_GetPixelIndex),其他FillRect和DrawBitLineXBPP函数按驱动函数规范修改:

static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {
    LCD_DrawPoint(x, y, PixelIndex);
};
static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
  unsigned int PixelIndex;
    PixelIndex = LCD_ReadPoint(x,y);
  return PixelIndex;
}

(4.4)LCDConf_FlexColor_Template.c文件修改:

//该文件内定义了显示屏的尺寸,以及另外一个要修改的函数时LCD_X_Config(),它会被STemWin的GUI_Init()函数调用

#define XSIZE_PHYS  320  // To be adapted to x-screen size
#define YSIZE_PHYS  240  // To be adapted to y-screen size
#ifndef   VXSIZE_PHYS
  #define VXSIZE_PHYS XSIZE_PHYS
#endif
#ifndef   VYSIZE_PHYS
  #define VYSIZE_PHYS YSIZE_PHYS
#endif
void LCD_X_Config(void) {
  int i;
  #if (NUM_BUFFERS > 1)
  for (i = 0; i < GUI_NUM_LAYERS; i++) 
  {
    GUI_MULTIBUF_ConfigEx(i, NUM_BUFFERS);
  }
  #endif

  //注意,该参数必须是&GUIDRV_Template_API和GUICC_M565(不是GUICC_565)   
  GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);

  //设置显示屏尺寸
  LCD_SetSizeEx(0,lcddev.width,lcddev.height);
  LCD_SetVSizeEx(0,lcddev.width,lcddev.height);

  //设置触摸屏横纵轴取值范围
  GUI_TOUCH_Calibrate(GUI_COORD_X,0,lcddev.width,0,lcddev.width-1);   
  GUI_TOUCH_Calibrate(GUI_COORD_Y,0,lcddev.height,0,lcddev.height-1);
    
  //
    // Setting up VRam address and custom functions for CopyBuffer-, CopyRect- and FillRect operations
    //
    for (i = 0; i < GUI_NUM_LAYERS; i++) 
    {
    _aPendingBuffer[i] = -1;
        
    //
    // Set VRAM address
    //
    LCD_SetVRAMAddrEx(i, (void *)(_aAddr[i]));
        
    //
    // Remember color depth for further operations
    //
    _aBytesPerPixels[i] = LCD_GetBitsPerPixelEx(i) >> 3;
        
    //
    // Set custom functions for several operations
    //
    LCD_SetDevFunc(i, LCD_DEVFUNC_COPYBUFFER, (void(*)(void))_LCD_CopyBuffer);
    LCD_SetDevFunc(i, LCD_DEVFUNC_COPYRECT,   (void(*)(void))_LCD_CopyRect);
        
    //
    // Filling via DMA2D does only work with 16bpp or more
    //
    if (_GetPixelformat(i) <= LTDC_Pixelformat_ARGB4444) 
    {
      LCD_SetDevFunc(i, LCD_DEVFUNC_FILLRECT, (void(*)(void))_LCD_FillRect);
      LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_8BPP, (void(*)(void))_LCD_DrawBitmap8bpp); 
    }
        
    //
    // Set up drawing routine for 16bpp bitmap using DMA2D
    //
    if (_GetPixelformat(i) == LTDC_Pixelformat_RGB565) 
    {
      LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_16BPP, (void(*)(void))_LCD_DrawBitmap16bpp);     // Set up drawing routine for 16bpp bitmap using DMA2D. Makes only sense with RGB565
    }

    //
    // Set up drawing routine for 32bpp bitmap using DMA2D
    //
    if (_GetPixelformat(i) == LTDC_Pixelformat_ARGB8888) 
    {
      LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_32BPP, (void(*)(void))_LCD_DrawBitmap32bpp);     // Set up drawing routine for 16bpp bitmap using DMA2D. Makes only sense with RGB565
    }

    //
    // Set up custom color conversion using DMA2D, works only for direct color modes because of missing LUT for DMA2D destination
    //
    GUICC_M1555I_SetCustColorConv(_Color2IndexBulk_M1555I_DMA2D, _Index2ColorBulk_M1555I_DMA2D); // Set up custom bulk color conversion using DMA2D for ARGB1555
    GUICC_M565_SetCustColorConv  (_Color2IndexBulk_M565_DMA2D,   _Index2ColorBulk_M565_DMA2D);   // Set up custom bulk color conversion using DMA2D for RGB565
    GUICC_M4444I_SetCustColorConv(_Color2IndexBulk_M4444I_DMA2D, _Index2ColorBulk_M4444I_DMA2D); // Set up custom bulk color conversion using DMA2D for ARGB4444
    GUICC_M888_SetCustColorConv  (_Color2IndexBulk_M888_DMA2D,   _Index2ColorBulk_M888_DMA2D);   // Set up custom bulk color conversion using DMA2D for RGB888
    GUICC_M8888I_SetCustColorConv(_Color2IndexBulk_M8888I_DMA2D, _Index2ColorBulk_M8888I_DMA2D); // Set up custom bulk color conversion using DMA2D for ARGB8888

    //
    // Set up custom alpha blending function using DMA2D
    //
    GUI_SetFuncAlphaBlending(_DMA_AlphaBlending); 
        
    //
    // Set up custom function for translating a bitmap palette into index values.
    // Required to load a bitmap palette into DMA2D CLUT in case of a 8bpp indexed bitmap
    //
    GUI_SetFuncGetpPalConvTable(_LCD_GetpPalConvTable);
        
    //
    // Set up a custom function for mixing up single colors using DMA2D
    //
    #if emWin_Optimize 
      GUI_SetFuncMixColors(_DMA_MixColors);
    #endif
        
    //
    // Set up a custom function for mixing up arrays of colors using DMA2D
    //
    GUI_SetFuncMixColorsBulk(_LCD_MixColorsBulk);
  }    
}

(4.5)GUI_X.c文件修改:

//该文件内主要定义了2个时间函数,其中的GUI_X_Delay是开发STemWin程序时常用的延迟函数

volatile GUI_TIMER_TIME OS_TimeMS;

/*********************************************************************
*
*      Timing:
*                 GUI_X_GetTime()
*                 GUI_X_Delay(int)

  Some timing dependent routines require a GetTime
  and delay function. Default time unit (tick), normally is
  1 ms.
*/

GUI_TIMER_TIME GUI_X_GetTime(void) { 
  return OS_TimeMS; 
}

void GUI_X_Delay(int ms) { 
  int tEnd = OS_TimeMS + ms;
  while ((tEnd - OS_TimeMS) > 0);
}

(4.6)GUI_X_Touch_Analog.c文件修改:

//该文件内定义了4个用于STemWin触摸屏函数调用的函数:

void GUI_TOUCH_X_ActivateX(void)
{
}

void GUI_TOUCH_X_ActivateY(void)
{
}

int GUI_TOUCH_X_MeasureX(void)
{
    int ret = ...;
    return ret;
}

int yc = 0;
int GUI_TOUCH_X_MeasureY(void)
{
    int ret = ...;    
    return ret;
}

(5)创建一个窗口测试

(5.1)使用GUIBuilder.exe创建windows框架代码

STemWin的框架代码跟VisualStudio的win32窗体应用程序的框架代码几乎一摸一样,如果对VS的win32窗体应用开发熟悉的话,可以手工编写windows框架代码。

STemWin本身提供了一个工具软件GUIBuilder.exe,通过该软件可以创建windows框架代码文件。

前文提到的STemWin压缩包中,位于Software目录下,如图所示:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

双击GUIBuilder.exe后打开界面如下:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

如图,创建一个窗体,然后往窗体上拖一个按钮,保存之后可以得到文件WndMainDLG.c,其内容如下,是不是和win32窗体程序很像,我们只需要在_cbDialog函数中编写相关的消息处理函数就可以了:

/*********************************************************************
*                                                                    *
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                                                                    *
**********************************************************************
*                                                                    *
* C-file generated by:                                               *
*                                                                    *
*        GUI_Builder for emWin version 5.32                          *
*        Compiled Oct  8 2015, 11:59:02                              *
*        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
*                                                                    *
**********************************************************************
*                                                                    *
*        Internet: www.segger.com  Support: support@segger.com       *
*                                                                    *
**********************************************************************
*/

// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x01)


// USER START (Optionally insert additional defines)
// USER END

/*********************************************************************
*
*       Static data
*
**********************************************************************
*/

// USER START (Optionally insert additional static data)
// USER END

/*********************************************************************
*
*       _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 73, 53, 179, 76, 0, 0x0, 0 },
  // USER START (Optionally insert additional widgets)
  // USER END
};

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/

// USER START (Optionally insert additional static code)
// USER END

/*********************************************************************
*
*       _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
  WM_HWIN hItem;
  int     NCode;
  int     Id;
  // USER START (Optionally insert additional variables)
  // USER END

  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
    //
    // Initialization of 'Button'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
    BUTTON_SetText(hItem, "Push Me");
    // USER START (Optionally insert additional code for further widget initialization)
    // USER END
    break;
  case WM_NOTIFY_PARENT:
    Id    = WM_GetId(pMsg->hWinSrc);
    NCode = pMsg->Data.v;
    switch(Id) {
    case ID_BUTTON_0: // Notifications sent by 'Button'
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
        // USER START (Optionally insert code for reacting on notification message)
        // USER END
        break;
      case WM_NOTIFICATION_RELEASED:
        // USER START (Optionally insert code for reacting on notification message)
        // USER END
        break;
      // USER START (Optionally insert additional code for further notification handling)
      // USER END
      }
      break;
    // USER START (Optionally insert additional code for further Ids)
    // USER END
    }
    break;
  // USER START (Optionally insert additional message handling)
  // USER END
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       CreateWindow
*/
WM_HWIN CreateWindow(void);
WM_HWIN CreateWindow(void) {
  WM_HWIN hWin;

  hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  return hWin;
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/

(5.2)将windows框架代码拷贝到uVision5项目

将WndMainDLG.c拷贝到uVision5项目中,并创建Widgets.h文件,如图:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

将创建窗体的函数封装,写到Widgets.h中,以方便统一使用:

#include "DIALOG.h"

WM_HWIN CreateWindow(void);

(5.3)编写代码显示窗体

//10ms定时器,定时刷新触摸屏触摸状态
void set_touch_detect_timer()
{
  //设置中断
  NVIC_InitTypeDef nvic_tim;
  nvic_tim.NVIC_IRQChannel = TIM2_IRQn;
  nvic_tim.NVIC_IRQChannelPreemptionPriority = 1;
  nvic_tim.NVIC_IRQChannelSubPriority = 2;
  nvic_tim.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&nvic_tim);

  //配置Tim
  TIM_TimeBaseInitTypeDef tim_init;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM7时钟,即内部时钟CK_INT=72M(STM32F103RC的芯片)
  TIM_Cmd(TIM2, DISABLE); //配置前,先关闭计数器
  tim_init.TIM_Prescaler = 72 -1;// 预分频器数值,16位; 计数器的时钟频率CK_CNT等于f CK_PSC /(PSC[15:0]+1)。在每一次更新事件时,PSC的数值被传送到实际的预分频寄存器中。
  tim_init.TIM_Period = 10000;// 自动重装载数值,16位; 即多少个脉冲产生一个更新或中断(1周期)。如果自动重装载数值为0,则计数器停止。
  TIM_TimeBaseInit(TIM2, &tim_init); // 初始化定时器
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);// 清除计数器中断标志位
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 开启更新中断(只是开启功能,未工作)
  TIM_Cmd(TIM2, ENABLE);// 是否使能计数器(使能了就会立即开始工作)
}
void TIM2_IRQHandler(void)
{
    GUI_TOUCH_Exec();//必须,10ms刷新一次触摸屏触摸状态
}
int main(void)
{
    Stm32_Clock_Init(360,25,2,8);    //设置时钟,180Mhz
    systick_delay_us(100000);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    //初始化内存、显示屏和触摸屏驱动                  
    SDRAM_Init();
    TFTLCD_Init();
    tp_dev.init();
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
    WM_SetCreateFlags(WM_CF_MEMDEV);    
    GUI_Init();
    GUI_Clear();
    GUI_CURSOR_Show();
    
    //开启定时检测触摸屏的时钟        
    set_touch_detect_timer();

    //创建并显示窗体
    WM_HWIN h = CreateMainWnd();
    while(1) 
    {
        GUI_Exec();//必须,刷新窗体
    }    
}

至此,STemWin移植完毕,可以看到效果如图:

emwin csdn,STM32,stm32,单片机,嵌入式硬件,Powered by 金山文档

您的打赏是我写作的动力!文章来源地址https://www.toymoban.com/news/detail-817519.html

到了这里,关于STM32和emWin必须知道的那些事的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言里面那些你必须知道的常用关键字(详细讲解)

      哈喽,各位铁汁们好啊!✨今天来给大家带来的是C语言中我们常用的静态 static 的详细讲解和 typedef 、 #define 定义常量和宏。   既然是详解想必大家必定是想学一些平常学不到的东西吧!这里博主给大家详细讲解 static 修饰的变量在内存重视如何存储的,顺带给

    2024年02月11日
    浏览(30)
  • STM32单片机(一)STM32简介

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(45)
  • 在stm32中,所需的库函数有那些

    使用库函数中封装的函数来访问外设可以使得stm32开发更加方便,省去了查寄存器位操作,只用查库函数就可以了 但是使用库函数时要记住真正的其本质是获取寄存器的地址然后设置其中的位 库函数一般添加到自己创建的Lib文件夹中 库函数实际上分成了两块,分别是CSMIS和标

    2024年04月26日
    浏览(29)
  • STM32单片机开发-01 STM32介绍

    通过野火开发板学习单片机 从内核上分有Cortex-M0、M3、M4 和M7 F1 代表了基础型,基于Cortex-M3 内核,主频为72MHZ F4 代表了高性能,基于Cortex-M4 内核,主频180M。 数据手册:用于芯片选型和设计原理图 参考手册:用于编程时查阅 Icode总线 – 该总线讲M3内核的指令总线与闪存指令

    2024年01月21日
    浏览(44)
  • STM32单片机(二)STM32环境搭建

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(48)
  • STM32单片机学习3--STM32控制键盘

    单片机型号:STM32F103C8T6 开发环境:Keil5 4种输入模式 上拉输入模式:在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为1,高电平(与Vdd相连的为上拉电阻); 下拉输入模式:在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为0,低电平(与Vss相连的为下拉电

    2024年02月10日
    浏览(41)
  • 【STM32】STM32单片机结构及部件原理

    STM32是目前比较常见并且多功能的单片机,要想学习STM32,首先要去了解它的基本构成部分以及各部分的原理。 单片机型号:正点原子STM32F103ZET6 目录 STM32内部结构总览图: 2.内部结构解析         1.内核 :STM32F103ZET6采用的是 ARM Cortex-M3 处理器,内核可以理解为单片机 处

    2023年04月08日
    浏览(33)
  • STM32单片机学习4--STM32控制八段码

    数码管:实际上是多个LED按照一定顺序排列,并加上遮罩所构成的元件。 八段码一般会引出9个引脚,其中7个引脚显示数字(或某些字母),1个显示小数点,1个作为片选端。 根据连接方式的不同,数码管分为 共阳 和 共阴 。 共阳在这端输出低电平时点亮,高电平时会熄灭

    2024年01月23日
    浏览(37)
  • 【STM32仿真】STM32CubeMX+Keil+Proteus单片机仿真

      博主最近进行单片机的仿真,本篇文章主要利用了STM32CubeMX、Keil和Proteus三个软件,为后期的硬件打下基础。文章主要目的是学习软件的使用和单片机的仿真。   本文是我在学习proteus软件和STM32CubeMX过程当中的心得和学习笔记,在学习时已经有C, C++的基础。文章附上了

    2024年02月16日
    浏览(44)
  • STM32独立看门狗IWDG和休眠(低功耗)共存那些事儿

    1.寄存器写入标志位方法为主要手段 2.看门狗初始化放在标志位判断后方 3.合理利用单片机复位,标志位复位后不会丢失的特点 4.不同系列单片机寄存器不一样 调试进入断点时不管停留多久,都不会触发看门狗 论坛TM32在休眠模式下怎么使用看门狗? 现在你只有2个办法: 1)使

    2024年02月12日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包