STM32嵌入式开发学习指南

因为有过嵌入式开发的基础,所以多少还是了解一些,比方JTAG调试、串口下载等等概念,但也奈何长时间不接触这方面的项目,渐渐也就生疏了!


嵌入式开发相对来说需要有硬件和软件的基础知识,相对来说综合技能要求高,所以,在硬件方面没有模拟电路或者数字电路基础,软件没有C语言基础的同学建议把这三个课程补一补,然后开始嵌入式开发学习;


【公开课程】推荐大家先学习开放课程:电子科技大学,漆强老师主讲的 基于STM32CubeMX和HAL驱动库的嵌入式系统设计 !


硬件准备,需要一定的投入:

1、ARM开发板,主流的是STM32f1/STM32f4系列开发板,STM32F1系列的开发板相对要便宜很多,建议入门可以先选F1系列开发板, 可以在淘宝搜索STM32 nucleo开发板,或者正点原子的STM32开发板等等,他们提供的配套学习资料还是非常丰富的;



2、J-Link 仿真器或者ST-Link V2调试器、USB-TTL、简单万用表(用来量个电压什么的),各种排线,烙铁等等;


3、软件

Keil 5(单片机集成开发环境)

STM32CubeMX(自动配置stm32编程的相关文件)

如果是j-link仿真器或者是ST-link调试器,则不用串口下载器

FLYMCU(stm32串口下载软件,也可用ST-LINK代替)

XCOM(串口监视器)


4、参考漆强老师的课程,完成包括通用GPIO控制,中断系统,定时器,串口通信几个章节的学习,恭喜你,算是入了嵌入式开发的门了!


----

2021年2月7号更新

实现两个功能:

1、通过定时器,实现LED闪烁;

2、实现printf重定向到串口输出;


教训:

昨天使用外部电源给模块供电,之前这个供电电源已经调好了3.3V输出,所以每次只用接上就好了,这次接上后模块开发板直接冒烟了,第一时间反应肯定是烧了,断开接上没反应,确认是烧了,再一看电源,20V输出,天啦,不烧才怪!而且一次赔了两个模块!粗心大发了!


上代码:

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>
#include "stm32100b_eval.h"

static volatile uint8_t timerFlag = 0; 

//Tout=((arr+1)*(psc+1))/Ft us.
/*
10000 -> 10 1ms
TIM3_Init(9999, 7199); ->1s
1
72e-6 / (7199+1) = 1e-4 (s) -> 0.1ms
*/
void TIM3_Init(uint16_t ms)
{
	/*
	*/ 
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);           //???????
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;           //??IRQ??
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //???????
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //????
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //???IRQ????????
    NVIC_Init(&NVIC_InitStructure);  
	
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 
    TIM_TimeBaseStructure.TIM_Period = ms*10; //???????????????????????????? ???0x0000-0xFFFF
    TIM_TimeBaseStructure.TIM_Prescaler =(7200-1); //??????? TIMx ???????????
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 
    TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_Trigger,ENABLE);//?????? TIM ???,?????1
    TIM_Cmd(TIM3, ENABLE);  
}
 
void ctlLed(){
	uint8_t ledFlag = timerFlag;
	if (ledFlag == 1){ 
			STM_EVAL_LEDOn(LED1);   
	}else{
			STM_EVAL_LEDOff(LED1); 
	}
}


void TIM3_IRQHandler(void)   
{
    static uint8_t flag  = 0;
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //??????
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //?????? 
			if (timerFlag){
				timerFlag = 0;
			}else{
				timerFlag = 1;
			}
			ctlLed(); 
    } 
}


int main(void)
{
    STM_EVAL_LEDInit(LED1);
    TIM3_Init(10);//10ms闪烁一次
    
    while(1){
	deca_sleep(1000);
    }
}


printf函数重定向后,使用printf输出的日志会通过串口输出到终端
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

PUTCHAR_PROTOTYPE
{
    /* Place your implementation of fputc here */ 
    USART_ClearFlag(EVAL_COM1,USART_FLAG_TC);
    /* e.g. write a character to the USART */
    USART_SendData(EVAL_COM1, (uint8_t) ch);
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
    {}
    return ch;
}


呱牛笔记

请先登录后发表评论
  • 最新评论
  • 总共0条评论