STM32/STM8资源节约主义设计方式

2023-12-18 08:33:47

STM32/STM8资源节约主义设计方式

在小资源芯片进行代码设计时,如STM32C0系列,STM8系列,因为官方库本身要包含各种场景应用特征的支持,所以会有一些冗余的代码占用更多FLASH空间。当需要实现资源占用最简化设计方式时,可以采用如下方式:

  1. 启动一个1ms周期定时器,每个中断进行32位计数值的累加计数
  2. 实现指令方式微秒延时函数,原理参考《STM32 HAL us delay(微秒延时)的指令延时实现方式及优化》,此方法适用于所有MCU的指令方式微秒延时实现,不限于STM32/STM8。
  3. 关闭1ms周期定时器。
  4. 用微秒延时函数进行各种接口GPIO时序模拟,如I2C, SPI等等。从而不需要用到官方接口库,实现最简化代码设计。一旦实现了微秒延时函数,用微秒延时函数设计实现的STM32接口协议函数,可以移过来用于STM8。
  5. 当需要实现某种更准确的时序要求时,可以将一个或多个TIM启动,配合微秒延时函数实现各种时序设计。

这里以STM8S103F3P6为例,介绍
*模拟UART TX发送的代码,不用到TIM资源
*模拟UART TX/RX环回测试代码,使用TIM资源

STM8S103F3P6 UART TX ONLY模拟协议代码

基于微秒延时函数不采用定时器的UART时序模拟原理介绍参考:《STM32 GPIO模拟UART串口:最简延时方式》,这里的逻辑为:

  1. 用TIM4实现1ms周期计数
  2. 实现微秒延时函数
  3. 关闭TIM4
  4. 用微秒延时函数实现9600波特率UART的TX发送功能,循环发送出增加的数值
  5. 这个代码在微秒延时函数实现后关闭了1ms周期计数的TIM4,因此后续运行没有用到任何TIM,也没有用到其它接口库。
    完整的实现代码在两个文件内。这里PB5为LED管脚,PC7为UART TX管脚。
    stm8s_it.c里的代码,主要是实现1ms周期中断的计数功能:
/**
  ******************************************************************************
  * @file     stm8s_it.c
  * @author   MCD Application Team
  * @version  V2.1.0
  * @date     18-November-2011
  * @brief    Main Interrupt Service Routines.
  *           This file provides template for all peripherals interrupt service 
  *           routine.
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm8s_it.h"
extern uint8_t i;
/** @addtogroup Template_Project
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

#ifdef _COSMIC_
/**
  * @brief Dummy Interrupt routine
  * @par Parameters:
  * None
  * @retval
  * None
*/
INTERRUPT_HANDLER(NonHandledInterrupt, 25)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}
#endif /*_COSMIC_*/

/**
  * @brief TRAP Interrupt routine
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER_TRAP(TRAP_IRQHandler)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Top Level Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TLI_IRQHandler, 0)

{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Auto Wake Up Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(AWU_IRQHandler, 1)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Clock Controller Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(CLK_IRQHandler, 2)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTA Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTB Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTC Interrupt routine.
  * @param  None
  * @retval None
  */


INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
   
}

/**
  * @brief External Interrupt PORTD Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTE Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTE_IRQHandler, 7)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

#ifdef STM8S903
/**
  * @brief External Interrupt PORTF Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(EXTI_PORTF_IRQHandler, 8)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S903*/

#if defined (STM8S208) || defined (STM8AF52Ax)
/**
  * @brief CAN RX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(CAN_RX_IRQHandler, 8)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

/**
  * @brief CAN TX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(CAN_TX_IRQHandler, 9)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S208 || STM8AF52Ax */

/**
  * @brief SPI Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(SPI_IRQHandler, 10)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Timer1 Update/Overflow/Trigger/Break Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Timer1 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

#ifdef STM8S903
/**
  * @brief Timer5 Update/Overflow/Break/Trigger Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM5_UPD_OVF_BRK_TRG_IRQHandler, 13)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
 
/**
  * @brief Timer5 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM5_CAP_COM_IRQHandler, 14)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

#else /*STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF62Ax or STM8AF52Ax or STM8AF626x */
/**
  * @brief Timer2 Update/Overflow/Break Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

/**
  * @brief Timer2 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, 14)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S903*/

#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \
    defined(STM8S005) ||  defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8AF626x)
/**
  * @brief Timer3 Update/Overflow/Break Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM3_UPD_OVF_BRK_IRQHandler, 15)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

/**
  * @brief Timer3 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM3_CAP_COM_IRQHandler, 16)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S208, STM8S207 or STM8S105 or STM8AF62Ax or STM8AF52Ax or STM8AF626x */

#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S103) || \
    defined(STM8S003) ||  defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8S903)
/**
  * @brief UART1 TX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }

/**
  * @brief UART1 RX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /*STM8S208 or STM8S207 or STM8S103 or STM8S903 or STM8AF62Ax or STM8AF52Ax */

/**
  * @brief I2C Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

#if defined(STM8S105) || defined(STM8S005) ||  defined (STM8AF626x)
/**
  * @brief UART2 TX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART2_TX_IRQHandler, 20)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }

/**
  * @brief UART2 RX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /* STM8S105 or STM8AF626x */

#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax)
/**
  * @brief UART3 TX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART3_TX_IRQHandler, 20)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }

/**
  * @brief UART3 RX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART3_RX_IRQHandler, 21)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /*STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax */

#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax)
/**
  * @brief ADC2 interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(ADC2_IRQHandler, 22)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#else /*STM8S105, STM8S103 or STM8S903 or STM8AF626x */
/**
  * @brief ADC1 interrupt routine.
  * @par Parameters:
  * None
  * @retval 
  * None
  */
 INTERRUPT_HANDLER(ADC1_IRQHandler, 22)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /*STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax */

#ifdef STM8S903
/**
  * @brief Timer6 Update/Overflow/Trigger Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TIM6_UPD_OVF_TRG_IRQHandler, 23)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#else /*STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF52Ax or STM8AF62Ax or STM8AF626x */
/**
  * @brief Timer4 Update/Overflow Interrupt routine.
  * @param  None
  * @retval None
  */

 __IO uint32_t uwTick = 0;
 INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 
     uwTick++;   
     
     TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
 }
#endif /*STM8S903*/

/**
  * @brief Eeprom EEC Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EEPROM_EEC_IRQHandler, 24)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

main.c里的代码:

/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    18-November-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
#include "stm8s_clk.h"

/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Init_GPIO(void)
{
	    GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);//LED       
     
        
        GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_HIGH_FAST);//UART_TX
        GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);     //UART_RX    
        GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
	
}
void Init_Timer4(void)
{

	TIM4_TimeBaseInit(TIM4_PRESCALER_128, 125);
    /* Clear TIM4 update flag */
    TIM4_ClearFlag(TIM4_FLAG_UPDATE);
	
	/* Enable update interrupt */
	TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
	TIM4_Cmd(ENABLE);
}

/*Start of Pegasus Segment*/
extern  __IO uint32_t uwTick;

__IO float usDelayBase;
void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = uwTick+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = uwTick;
  PY_Delay_us_t(1000000) ;
  secondms = uwTick;

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}

void PY_Delay_us(uint32_t Delay)
{
  __IO uint32_t delayReg;

  __IO uint32_t msNum = Delay/1000;
  __IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);

  if(msNum>0) HAL_Delay(msNum);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}







#define GPIO_OUTPUT_EXEC_DELAY_us 40

#define BaudRate_us 104 //for 9600bps

#define RD (GPIO_ReadInputPin(GPIOC, GPIO_PIN_6)==GPIO_PIN_6)?1:0
#define TDL GPIO_WriteLow(GPIOC, GPIO_PIN_7)
#define TDH GPIO_WriteHigh(GPIOC, GPIO_PIN_7)

#define buff_len 128
__IO uint8_t tx_status = 0;
__IO uint8_t rx_status = 0;

__IO uint8_t txd[buff_len];
__IO uint8_t rxd[buff_len];

__IO uint32_t txd_index=0;
__IO uint32_t rxd_index=0;


__IO uint8_t bytebit=0;
__IO uint8_t bytebit_s=0;

__IO uint8_t data=0;
/*Enf of Pegasus Segment*/
void main(void)
{
  
    /* Config internal high speed clock as 16MHz main clock */ 
            //CLK_HSICmd(ENABLE);
            CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
            CLK_HSICmd(ENABLE);
            CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
	        CLK_ClockSwitchCmd(ENABLE);
	    
   
   
        Init_GPIO();
	    Init_Timer4();
	    enableInterrupts();
        
        for(uint32_t j=0; j<0xffff; j++) ;  //for clock stability
        
        PY_usDelayTest();
        PY_usDelayOptimize();  //get us delay function
        
        disableInterrupts();
        TIM4_Cmd(DISABLE);  //no use of TIM4 now
  
  
  while (1)
  {
    
    PY_Delay_us_t(1000000);
    
    GPIO_WriteReverse(GPIOB, GPIO_PIN_5); //Flash LED    
  
          tx_status = 1;
          data++;
          
	  switch(tx_status)
	  {

	  case 1:{//start bit
             bytebit = data;
             TDL;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             tx_status ++;
	         }
	  case 2:{//bit 1
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 3:{//bit 2
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 4:{//bit 3
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 5:{//bit 4
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 6:{//bit 5
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 7:{//bit 6
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 8:{//bit 7
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             bytebit >>= 1;
             tx_status ++;
	         }
	  case 9:{//bit 8
             if((bytebit&0x01)==0) TDL;
             else TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             tx_status ++;
	         }
	  case 10:{//stop bit
             TDH;
             PY_Delay_us_t(BaudRate_us-GPIO_OUTPUT_EXEC_DELAY_us);
             tx_status = 0;
             
             rx_status = 0;
	         }
	  default:break;
	  }

  
  }
  
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/


代码下载后测试效果:
在这里插入图片描述

STM8S103F3P6 UART TX/RX 模拟协议代码及环回测试

基于采用定时器的UART时序模拟介绍参考:《STM32 GPIO模拟UART串口:外部时钟及TIM方式》,注意STM8应用场景主要采用内部时钟模式,所以STM8的内部时钟稳定度尚可,配合对接收时序采样时刻的调整,可以不采用外部时钟而实现9600波特率UART稳定收发。这里的逻辑为:

  1. 用TIM4实现1ms周期计数
  2. 实现微秒延时函数
  3. 关闭TIM4
  4. 重配TIM4和启用为52us周期中断(9600波特率对应104us位宽)
  5. 实现UART接收到发送的环回功能
    完整的实现代码在两个文件内。这里PB5为LED管脚,PC7为UART TX管脚,PC6为RX管脚。

stm8s_it.c里的代码:

/**
  ******************************************************************************
  * @file     stm8s_it.c
  * @author   MCD Application Team
  * @version  V2.1.0
  * @date     18-November-2011
  * @brief    Main Interrupt Service Routines.
  *           This file provides template for all peripherals interrupt service 
  *           routine.
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm8s_it.h"
extern uint8_t i;
/** @addtogroup Template_Project
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

#ifdef _COSMIC_
/**
  * @brief Dummy Interrupt routine
  * @par Parameters:
  * None
  * @retval
  * None
*/
INTERRUPT_HANDLER(NonHandledInterrupt, 25)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}
#endif /*_COSMIC_*/

/**
  * @brief TRAP Interrupt routine
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER_TRAP(TRAP_IRQHandler)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Top Level Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TLI_IRQHandler, 0)

{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Auto Wake Up Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(AWU_IRQHandler, 1)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Clock Controller Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(CLK_IRQHandler, 2)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTA Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTB Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTC Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTD Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief External Interrupt PORTE Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EXTI_PORTE_IRQHandler, 7)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

#ifdef STM8S903
/**
  * @brief External Interrupt PORTF Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(EXTI_PORTF_IRQHandler, 8)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S903*/

#if defined (STM8S208) || defined (STM8AF52Ax)
/**
  * @brief CAN RX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(CAN_RX_IRQHandler, 8)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

/**
  * @brief CAN TX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(CAN_TX_IRQHandler, 9)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S208 || STM8AF52Ax */

/**
  * @brief SPI Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(SPI_IRQHandler, 10)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Timer1 Update/Overflow/Trigger/Break Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @brief Timer1 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

#ifdef STM8S903
/**
  * @brief Timer5 Update/Overflow/Break/Trigger Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM5_UPD_OVF_BRK_TRG_IRQHandler, 13)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
 
/**
  * @brief Timer5 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM5_CAP_COM_IRQHandler, 14)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

#else /*STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF62Ax or STM8AF52Ax or STM8AF626x */
/**
  * @brief Timer2 Update/Overflow/Break Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

/**
  * @brief Timer2 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, 14)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S903*/

#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \
    defined(STM8S005) ||  defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8AF626x)
/**
  * @brief Timer3 Update/Overflow/Break Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM3_UPD_OVF_BRK_IRQHandler, 15)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }

/**
  * @brief Timer3 Capture/Compare Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(TIM3_CAP_COM_IRQHandler, 16)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#endif /*STM8S208, STM8S207 or STM8S105 or STM8AF62Ax or STM8AF52Ax or STM8AF626x */

#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S103) || \
    defined(STM8S003) ||  defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8S903)
/**
  * @brief UART1 TX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }

/**
  * @brief UART1 RX Interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /*STM8S208 or STM8S207 or STM8S103 or STM8S903 or STM8AF62Ax or STM8AF52Ax */

/**
  * @brief I2C Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

#if defined(STM8S105) || defined(STM8S005) ||  defined (STM8AF626x)
/**
  * @brief UART2 TX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART2_TX_IRQHandler, 20)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }

/**
  * @brief UART2 RX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /* STM8S105 or STM8AF626x */

#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax)
/**
  * @brief UART3 TX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART3_TX_IRQHandler, 20)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }

/**
  * @brief UART3 RX interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART3_RX_IRQHandler, 21)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /*STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax */

#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax)
/**
  * @brief ADC2 interrupt routine.
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(ADC2_IRQHandler, 22)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#else /*STM8S105, STM8S103 or STM8S903 or STM8AF626x */
/**
  * @brief ADC1 interrupt routine.
  * @par Parameters:
  * None
  * @retval 
  * None
  */
 INTERRUPT_HANDLER(ADC1_IRQHandler, 22)
 {
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
 }
#endif /*STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax */

#ifdef STM8S903
/**
  * @brief Timer6 Update/Overflow/Trigger Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(TIM6_UPD_OVF_TRG_IRQHandler, 23)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
 }
#else /*STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF52Ax or STM8AF62Ax or STM8AF626x */
/**
  * @brief Timer4 Update/Overflow Interrupt routine.
  * @param  None
  * @retval None
  */

 __IO uint32_t uwTick = 0;
extern __IO uint8_t Int_Type;


#define TDL GPIO_WriteLow(GPIOC, GPIO_PIN_7)
#define TDH GPIO_WriteHigh(GPIOC, GPIO_PIN_7)
#define RBIT (GPIO_ReadInputPin(GPIOC, GPIO_PIN_6)==GPIO_PIN_6)?1:0;


#define buff_len 128

uint8_t txd[buff_len];
uint8_t rxd[buff_len];

uint32_t txd_index=0;
uint32_t rxd_index=0;

#define sampling_timing_opt_us 1

uint8_t half_period_ctl = 0;
 INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
extern uint8_t bytebit;
extern uint8_t bytebit_s;
extern uint8_t tx_status;
extern uint8_t rx_status;


   if(Int_Type == 0)
   { 
     uwTick++;   
   }
   else
   {

 		  switch(rx_status)
		  {
		  case 0:{
                    	      bytebit = RBIT;
			      if(bytebit==0)
			      {
                                if(half_period_ctl==0) half_period_ctl = 1;
                                else 
                                {
                                  half_period_ctl = 0;
                                  rx_status = 1;
                                }
			    	  
			      }
				  break;
			     }
		  case 1:{//start bit
			      rx_status ++;
			      rxd[rxd_index] = 0;
			      break;
		         }
		  case 2:{//bit 1
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 4:{//bit 2
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 6:{//bit 3
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 8:{//bit 4
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 10:{//bit 5
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 12:{//bit 6
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 14:{//bit 7
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 16:{//bit 8
			     //PY_Delay_us_t(sampling_timing_opt_us);
	             bytebit = RBIT;
	             (bytebit==0)?(rxd[rxd_index]>>=1):(rxd[rxd_index]=(rxd[rxd_index]>>1)|0x80);
	             rx_status ++;
	             break;
		         }
		  case 18:{//stop bit
			     //PY_Delay_us_t(sampling_timing_opt_us);
			     bytebit = RBIT;
	             if(bytebit==1)
	             {
	            	 bytebit_s = rxd[rxd_index];
	                 tx_status = 1; //Sending enable for loop-back test

	            	 if(rxd_index==(buff_len-1)) rxd_index=0;
	            	 else rxd_index++;
	             }
	             rx_status = 0;
			     break;
		         }
		  default: {
			     rx_status++;
			     break;
		         }
		  }

		  switch(tx_status)
		  {
		  case 0:{
			      TDH;
			      break;
		          }
		  case 2:{//start bit
	              TDL;
	              tx_status ++;
			      break;
		         }
		  case 4:{//bit 1
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 6:{//bit 2
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 8:{//bit 3
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 10:{//bit 4
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 12:{//bit 5
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 14:{//bit 6
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 16:{//bit 7
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 18:{//bit 8
	             if((bytebit_s&0x01)==0) TDL;
	             else TDH;
	             bytebit_s >>= 1;
	             tx_status ++;
			      break;
		         }
		  case 20:{//stop bit
			      TDH;
			      tx_status ++;
			      break;
		         }
		  case 22:{//stop
			      tx_status = 0;
			      break;
		         }
		  default: {
			     tx_status++;
			     break;
		         }
		  } 
     
     
     
   }

	TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
 }
#endif /*STM8S903*/

/**
  * @brief Eeprom EEC Interrupt routine.
  * @param  None
  * @retval None
  */
INTERRUPT_HANDLER(EEPROM_EEC_IRQHandler, 24)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
}

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

main.c代码:

/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    18-November-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
#include "stm8s_clk.h"

/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Init_GPIO(void)
{
	    GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);//LED        

        
        GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);     //UART_RX
        GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_HIGH_FAST);//UART_TX
        GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
	
}
void Init_Timer4(void)  //1ms period counter
{
	TIM4_TimeBaseInit(TIM4_PRESCALER_128, 125);
    /* Clear TIM4 update flag */
    TIM4_ClearFlag(TIM4_FLAG_UPDATE);
	
	/* Enable update interrupt */
	TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
	TIM4_Cmd(ENABLE);
}


void Init_Timer4_plus(void) //for UART with BDS 9600
{
	TIM4_TimeBaseInit(TIM4_PRESCALER_16, 51);
    /* Clear TIM4 update flag */
    TIM4_ClearFlag(TIM4_FLAG_UPDATE);
	
	/* Enable update interrupt */
	TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
	TIM4_Cmd(ENABLE);
}
/*Start of Pegasus Segment*/
extern  __IO uint32_t uwTick;

__IO float usDelayBase;
void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = uwTick+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = uwTick;
  PY_Delay_us_t(1000000) ;
  secondms = uwTick;

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}



uint8_t bytebit=1;
uint8_t bytebit_s=1;
uint8_t tx_status = 0;
uint8_t rx_status = 0;


__IO uint8_t Int_Type = 0;

uint8_t td=0;

/*Enf of Pegasus Segment*/
void main(void)
{
  
        /* Config internal high speed clock as 16MHz main clock */ 
        //CLK_HSICmd(ENABLE);
        CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
        CLK_HSICmd(ENABLE);
        CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
	    CLK_ClockSwitchCmd(ENABLE);
	    
   
   
        Init_GPIO();
        
	    Init_Timer4();
        Int_Type = 0;                        //1 ms counter mode
	    enableInterrupts();                  
        
        for(uint32_t j=0; j<0xffff; j++) ;  //for clock stability
        
        PY_usDelayTest();
        PY_usDelayOptimize();
        
        disableInterrupts() ;
        TIM4_Cmd(DISABLE);
  
        Int_Type = 1;                       //uart detection mode
        Init_Timer4_plus();        
        enableInterrupts();
  
  while (1)
  {
    
    PY_Delay_us_t(1000000);    
    GPIO_WriteReverse(GPIOB, GPIO_PIN_5);  
 
  }
  
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

代码下载后测试效果:
在这里插入图片描述

总结

实现最简化资源占用代码设计时,如果没有时序要求高的情况,可以用微秒延时函数模拟所有常规接口协议。如果有时序要求高的情况,可以用TIM配合实现所有常规接口协议,只用到TIM这一种官方库代码。如果MCU资源足够,用官方库代码可以减少一些模拟协议代码编程量,所以本篇内容的介绍,多用在资源少的场景。

–End–

文章来源:https://blog.csdn.net/hwytree/article/details/133997768
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。