stm8 串口模拟接收

我用的是PD4引脚

需要一个引脚中断和一个定时器产生波特率

用的定时器2模拟的波特率

有点小问题,就是第一次的第一个数据会少移动一位,但是后面数据又是正常的 = =

异常数据:84 4D 00 1C 00 0E 00 10 00 15 00 0E 00 10 00 15 09 F9 02 B8 00 3C 00 06 00 04 00 01 71 00 03 85 

正常数据:42 4D 00 1C 00 0E 00 10 00 15 00 0E 00 10 00 15 09 F9 02 B8 00 3C 00 06 00 04 00 01 71 00 03 85 

#define SIMULATION_UART_DATA_SIZE 32

u8 simulationUartData[32];
static u8 tim2_updata_count = 0;
static u8 tim2_data_count = 0;
static volatile u8 uartData = 0;

void simulationUartReceiveInit(void)
{
  TIM2->PSCR=0x04;//16分频,定时器时钟等于系统时钟=1m
  TIM2->ARRH=0x00;//一定要先装高八位,再装低八位
  TIM2->ARRL=0x68;//1ms重装值16000,这是个坑,技术手册里说tim2是向上计数,其实是向下计数的
  TIM2->CNTRH=0x00;
  TIM2->CNTRL=0x00;//有必要清除下计数器
  TIM2->IER = 0x01; // 允许更新中断

  TIM2->CR1 = 0x00; // 计数器使能,暂停计数
}
void uart2Init(void)
{
    UART2_DeInit();
    UART2_Init((u32)9600, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, UART2_PARITY_NO , UART2_SYNCMODE_CLOCK_DISABLE , UART2_MODE_TXRX_ENABLE);
    UART2_Cmd(ENABLE);
 //   UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
    
}

void inerDelay_us(unsigned char n)  //改为延时1US
{
  for(;n>0;n--) 
  { 
      asm("nop");  //在STM8里面,16M晶振,_nop_() 延时了 333ns
      asm("nop");  
      asm("nop");  
      asm("nop");  
  }
}

void main(void)
{
  /*设置内部高速时钟16M为主时钟*/ 
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);  //16M  
  uart2Init();
  simulationUartReceiveInit();
  
  GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_IN_PU_IT);
  
  EXTI_DeInit();
  EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_FALL_ONLY);
  
  enableInterrupts(); 

  for(;;)
  {

  }
}

#pragma vector=8
__interrupt void EXTI_PORTD_IRQHandler(void)
{
  if( 0 ==(GPIO_ReadInputPin(GPIOD,GPIO_PIN_4)) )
  {
    GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_IN_PU_NO_IT);//设置为浮空输入
    uartData = 0;
    tim2_updata_count = 0;
    TIM2->CNTRH=0x00;
    TIM2->CNTRL=0x00;//有必要清除下计数器
    inerDelay_us(60);
    TIM2->CR1 = 0x01; // 计数器使能,
  }
}

#pragma vector=15
__interrupt void TIM2_IRQHandler(void) 
{
  TIM2_ClearFlag( TIM2_FLAG_UPDATE);
  uartData>>=1;
  tim2_updata_count++;
  
  if(GPIO_ReadInputPin(GPIOD,GPIO_PIN_4) == 1 )
  {
    uartData|=0x80;
  }
  
  if(8 == tim2_updata_count)
  {
    UART2_SendData8(uartData);
    simulationUartData[tim2_data_count] = uartData;
    tim2_updata_count = 0;
    GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_IN_PU_IT);
    EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_FALL_ONLY);
    TIM2->CR1 = 0x00; // 计数器使能,暂停计数
    tim2_data_count++;
    if(tim2_data_count == 32)
    {
      tim2_data_count = 0;
    }
    
  }
}

PUTCHAR_PROTOTYPE
{
  /* Write a character to the UART2 */
  UART2_SendData8(c);
  /* Loop until the end of transmission */
  while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET);

  return (c);
}

GETCHAR_PROTOTYPE
{
#ifdef _COSMIC_
  char c = 0;
#else
  int c = 0;
#endif
  /* Loop until the Read data register flag is SET */
  while (UART2_GetFlagStatus(UART2_FLAG_RXNE) == RESET);
    c = UART2_ReceiveData8();
  return (c);
}

  

原文地址:https://www.cnblogs.com/-yjx-/p/9202328.html