STM32F103ZET6 使用官方串口IAP 学习记录

选择STM32F10E-EVAL进行编译,添加定时器驱动程序,再在stm3210e_eval.c中添加定时器初始化程序以及串口判断程序,并在stm32f10e_eval.h加入函数声明

/****************************DTJ_ADD_START**************************************/
#include "stm32f10x_tim.h"
#include "common.h"

uint16_t timer_count=0;
void TIMER_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
	
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断	

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器		

	TIM_SetCounter(TIM3, 0);
	TIM_Cmd(TIM3, ENABLE);
}		

volatile uint16_t temp2;

//判断是否有命令,如超时未接收到命令,返回0
uint16_t IsGetKey(void)
{
	uint8_t key = 0;
	uint8_t flag = 0;

  /* Waiting for user input */
	while (timer_count < 50)
	{
		if (SerialKeyPressed((uint8_t*)&key)) 
		{
			if(key == 0x55)
			{
				flag=1;
				break;
			}
		}
	}
	TIM_Cmd(TIM3, DISABLE);
	TIM_SetCounter(TIM3, 0);
	TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
	NVIC_DisableIRQ(TIM3_IRQn);	
	
	return flag;
	
}

void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );   //清除TIMx更新中断标志 
		timer_count++;
	}
}

/****************************DTJ_ADD_EDD****************************************/
  • 修改主函数
int main(void)
{
  /* Flash unlock */
  FLASH_Unlock();

	
	IAP_Init();																						//初始化串口,默认USART1
	SerialPutString("Enter the command 'U' or enter the main program in five seconds\r\n");
	
	//初始化定时器,设为100ms产生一次中断
	TIMER_Init(7200,1000);
	

  /* Test if Key push-button on STM3210X-EVAL Board is pressed */
	if(IsGetKey())
	{ 
    /* If Key is pressed */
    /* Execute the IAP driver in order to re-program the Flash */
    SerialPutString("\r\n======================================================================");
    SerialPutString("\r\n=              (C) COPYRIGHT 2010 STMicroelectronics                 =");
    SerialPutString("\r\n=                                                                    =");
    SerialPutString("\r\n=     In-Application Programming Application  (Version 3.3.0)        =");
    SerialPutString("\r\n=                                                                    =");
    SerialPutString("\r\n=                                   By MCD Application Team          =");
    SerialPutString("\r\n======================================================================");
    SerialPutString("\r\n\r\n");
    Main_Menu ();
  }
  /* Keep the user application running */
  else
  {
    /* Test if user code is programmed starting from address "ApplicationAddress" */
    if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
    { 
      /* Jump to user application */
      JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
      Jump_To_Application = (pFunction) JumpAddress;
      /* Initialize user application's Stack Pointer */
      __set_MSP(*(__IO uint32_t*) ApplicationAddress);
      Jump_To_Application();
    }
  }

  while (1)
  {}
}

修改程序烧录位置

至此IAP程序修改完成,用Jlink/STlink烧录IAP程序。

  • 新建一个APP程序

选择对应的MCU,设置外部晶振,设置时钟树

  • 初始化串口+LED
  • 在main函数起始位置设置中断向量表偏移,在while函数中点灯,同时设置收到指令可以复位
#include "stdio.h"
uint8_t rxdata,rxflag;

int main(void)
{

  /* USER CODE BEGIN 1 */
	
	SCB->VTOR = FLASH_BASE | 0x3000; // 0x1C00 即 BootLoader 大小(偏移量)
	
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

	HAL_UART_Receive_IT(&huart1,&rxdata,1);

	printf("here is APP\r\n");

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_GPIO_TogglePin(LED_RED_GPIO_Port,LED_RED_Pin);
	  HAL_Delay(1000);
	  if(rxflag==1)
	  {
		  rxflag=0;
		  HAL_UART_Receive_IT(&huart1,&rxdata,1);
		  if(rxdata == 0x31)
		  {
			   NVIC_SystemReset();
		  }
	  }
  }
  /* USER CODE END 3 */
}


/* USER CODE BEGIN 4 */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart1)
	{
		rxflag=1;
	}
}

/* USER CODE END 4 */
  • 在usart.c中重定义printf
#include "stdio.h"

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}
  • 修改烧录地址

$K\ARM\ARMCC\bin\fromelf.exe --bin --output=@L.bin !L

至此APP程序编写完成;

  • 用正点原子串口工具连接串口
    SecureCRT有个问题,如果连接的时候复位的话,程序会复位失败(暂时不知道原因);先用正点原子的串口工具连接串口,按下复位键,再输入U,再输入1,此时需要传输程序,断开正点原子串口工具,连接SECURECRT工具

  • 通过SECURECRT下载APP程序

下载成功之后,按下按键3进入APP程序。进入APP程序之后,按下1会进行软复位,此时可重新开始烧录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值