打印
[STM8]

STM8L ADC串口输出后,定时短暂不准,附代码和波形求解

[复制链接]
789|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hzocce|  楼主 | 2019-4-19 08:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hzocce 于 2019-4-22 10:50 编辑

#define LED_1_ON 70
#define LED_2_ON 140
#define LED_3_ON 210
#define LED_4_ON 280
#define LED_5_ON 350
#define LED_6_ON 420
#define LED_7_ON 490
#define LED_8_ON 560


void Get_Led_Current(void)
{


  ADC_ChannelCmd(ADC1, ADC_Channel_15, ENABLE);
  Temp1=Read_ADC_Value();
  ADC_ChannelCmd(ADC1, ADC_Channel_15, DISABLE);

//  ADC_ChannelCmd(ADC1, ADC_Channel_16, ENABLE);
//  Temp2=Read_ADC_Value();
//  ADC_ChannelCmd(ADC1, ADC_Channel_16, DISABLE);
//
//  ADC_ChannelCmd(ADC1, ADC_Channel_18, ENABLE);
//  Temp3=Read_ADC_Value();
//  ADC_ChannelCmd(ADC1, ADC_Channel_18, DISABLE);
//
//  ADC_ChannelCmd(ADC1, ADC_Channel_21, ENABLE);
//  Temp4=Read_ADC_Value();
//  ADC_ChannelCmd(ADC1, ADC_Channel_21, DISABLE);

  if(Temp1);if(Temp2);if(Temp3);if(Temp4);

}

void Print_Out(unsigned int VVV)
{

    Uart1_SendString("\r\nADC采样值 = " , 14);
    Uart1_SendData((VVV / 1000) + '0');
    Uart1_SendData((VVV / 100 % 10) + '0');
    Uart1_SendData((VVV % 100 / 10) + '0');
    Uart1_SendData((VVV % 10) + '0');
    Uart1_SendData('\r');
    Uart1_SendData('\n');


}

//--------------------------------------------------------------------------------------------------------------------------------

void main(void)
{

  UART1_Init();
  TIM4_Config();
  ADC1_Config();
  LED_Init();
  Get_Led_Current();
  GPIO_ResetBits(GPIOB, GPIO_Pin_1);
//  GPIO_SetBits(GPIOB, GPIO_Pin_1);
  while (1)
  {
//    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_3))GPIO_ResetBits(GPIOB, GPIO_Pin_1);
    if(Tim4_1mS_mark==0xaa)//1ms定时标志。
    {
      Tim4_1mS_mark=0;
      Flag_do++;//1ms自加一次。
      switch(Flag_do)
      {
      case LED_1_ON:
                    GPIO_SetBits(GPIOB, GPIO_Pin_1);//--1
                    break;
      case LED_2_ON:
//------------------------------------------------------------------------------------------------------------------------------------------------
                    Get_Led_Current();Print_Out(Temp1);Temp1=0;//此段注释掉否的波形如tek0.png和tek1.png,高电平时间多了18ms的时差,是为什么呢?
//-------------------------------------------------------------------------------------------------------------------------------------------------
                    GPIO_ResetBits(GPIOB, GPIO_Pin_1);//--0                     
                    break;
      case LED_3_ON:Flag_do=0;
                    break;
      case LED_4_ON:break;
      case LED_5_ON:break;
      case LED_6_ON:break;
      case LED_7_ON:break;
      default:break;
      }






    }

  }


}

//------------------------------------------------------------------------------
串口,ADC ,定时器配置如下:


void UART1_Init(void)
{
  USART_DeInit(USART1); //将USART1的各个寄存器值恢复为缺省值
  /* 使能USART1时钟外设 */
  CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE);
  /* 映射UART1的IO口:TX-->PA2  RX-->PA3 */
  SYSCFG_REMAPPinConfig(REMAP_Pin_USART1TxRxPortA, ENABLE);
  /* 配置UART1的RX&TX的IO口 */
  GPIO_Init(UART1_RX_PORT, UART1_RX_PINS, GPIO_Mode_In_PU_No_IT);
  GPIO_Init(UART1_TX_PORT, UART1_TX_PINS, GPIO_Mode_Out_PP_High_Slow);  
  GPIO_ExternalPullUpConfig(UART1_RX_PORT, UART1_RX_PINS, ENABLE);
  GPIO_ExternalPullUpConfig(UART1_TX_PORT, UART1_TX_PINS, ENABLE);  
  /* UART1初始化 */
  USART_Init(USART1,
                (uint32_t)9600, //波特率9600
                USART_WordLength_8b,    //数据宽度8位
                USART_StopBits_1,       //一位停止位
                USART_Parity_No,        //无奇偶校验
                (USART_Mode_TypeDef)(USART_Mode_Tx | USART_Mode_Rx));//发送&接收模式
}


void Uart1_SendData(u8  data)
{
    while(USART_GetFlagStatus(USART1 , USART_FLAG_TXE) == RESET);        //判断发送数据寄存器是否为空   
    USART_SendData8(USART1 , (u8)data);                     //向发送寄存器写入数据  
}

/*******************************************************************************
**函数名称:void Uart1_SendString(unsigned char *data , unsigned char strlen)
**功能描述:向串口连续发送多个字符
**入口参数:unsigned char *data   ,  unsigned char strlen
**输出:无
*******************************************************************************/
void Uart1_SendString(unsigned char *data , unsigned int strlen)
{
  unsigned int datalen;

  for(datalen = 0 ; datalen < strlen ; datalen++)
  {
    Uart1_SendData(data[datalen]);
  }
}
void TIM4_Config(void)
{
  /*
   - TIM4时钟为系统时钟,也就是HSI/8 = 2MHz,配置每1ms更新一次应如下设置
    2M / (16 * 125) = 1000Hz = 1ms;16为预分频值,125为周期值
  */
  /* 使能 TIM4 C时钟 */
  CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, ENABLE);
  /* Time4基本配置 */
  TIM4_TimeBaseInit(TIM4_Prescaler_16, (125-1));  
  /* 清除TIM4更新标志位 */
  TIM4_ClearFlag(TIM4_FLAG_Update);
  /* 使能更新中断 */
  TIM4_ITConfig(TIM4_IT_Update, ENABLE);
  /* 使能总中断 */
  enableInterrupts();
  /* 使能 TIM4 */
  TIM4_Cmd(ENABLE);
}


void ADC1_Config(void)
{
  //打开ADC1外设的时钟
  CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);

  //配置ADC1的GPIO为浮空输入模式
  GPIO_Init(GPIOB, GPIO_Pin_4, GPIO_Mode_In_FL_No_IT);//ADC_Channel_11
  GPIO_Init(GPIOB, GPIO_Pin_2, GPIO_Mode_In_FL_No_IT);//ADC_Channel_16
  GPIO_Init(GPIOB, GPIO_Pin_0, GPIO_Mode_In_FL_No_IT);//ADC_Channel_18
  GPIO_Init(GPIOD, GPIO_Pin_2, GPIO_Mode_In_FL_No_IT);//ADC_Channel_21

  GPIO_Init(GPIOB, GPIO_Pin_3, GPIO_Mode_In_FL_No_IT);



  //初始化ADC1,单次转换模式,12位分辨率,ADC时钟2分频
//  ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_2);
  ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_1);

  //配置ADC采样时间,384个时钟周期ADC_SamplingTime_4Cycles
//  ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_384Cycles);
  ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_4Cycles);

  //打开ADC1的22通道
  ADC_ChannelCmd(ADC1, ADC_Channel_15, ENABLE);


  //使能ADC1
  ADC_Cmd(ADC1, ENABLE);
  ADC_ChannelCmd(ADC1, ADC_Channel_15, DISABLE);
}

uint16_t Read_ADC_Value(void)
{
  uint16_t temp;

  //启动一次ADC转换
  ADC_SoftwareStartConv(ADC1);

  //等待转换结束
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

  //读取ADC值
  temp = ADC_GetConversionValue(ADC1);   

  //返回ADC值
  return temp;
}



//-------------------------------------------------------------------------
//---------------定时器4的中断如下:
INTERRUPT_HANDLER(TIM4_UPD_OVF_TRG_IRQHandler,25)
{
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
   Counts++;
   Tim4_1mS_mark=0xaa;
  /* 清除中断标志位 */
  TIM4_ClearITPendingBit(TIM4_IT_Update);
}
/**


tek1.png (94.27 KB )

tek1.png

tek0.png (94.33 KB )

tek0.png

使用特权

评论回复
沙发
hzocce|  楼主 | 2019-4-19 08:36 | 只看该作者
本帖最后由 hzocce 于 2019-4-22 10:44 编辑

本来70ms后就应该变成低电平的,为什么多了88ms才变,是什么原因导致了18毫秒的延迟呢?

使用特权

评论回复
板凳
mmuuss586| | 2019-4-19 09:35 | 只看该作者
通过DMA方式就可以了;
可以顺序采样,然后读取数组的值即可

使用特权

评论回复
地板
hzocce|  楼主 | 2019-4-19 09:40 | 只看该作者
mmuuss586 发表于 2019-4-19 09:35
通过DMA方式就可以了;
可以顺序采样,然后读取数组的值即可

DMA 暂时不不会,用最传统的办法,解决问题!

使用特权

评论回复
5
hzocce|  楼主 | 2019-4-22 10:45 | 只看该作者
本帖最后由 hzocce 于 2019-4-22 10:51 编辑

删除掉Print_Out串口输出后,问题解决 !!!!!!!!!!!!!!!
为什么串口会影响到定时呢?

求解~~~~

使用特权

评论回复
6
香水城| | 2019-4-22 11:51 | 只看该作者
你的波形输出是基于什么?定时器中断?

你代码里有哪些中断,注意中断优先级的安排问题。

使用特权

评论回复
7
hzocce|  楼主 | 2019-4-22 13:29 | 只看该作者
香水城 发表于 2019-4-22 11:51
你的波形输出是基于什么?定时器中断?

你代码里有哪些中断,注意中断优先级的安排问题。 ...

示波器波形的高低,就是代码中的IO变化。
增加串口输出后,就慢了18ms的样子。
中断优先级,未做设置。 默认的。

这样的意思,就是串口优先级高于定时器优先级了? 那为什么输出几个字母的时间耗掉了18ms,定时器中断是1ms中断一次。

使用特权

评论回复
8
hzocce|  楼主 | 2019-4-23 10:11 | 只看该作者
浮起来~~

使用特权

评论回复
9
天灵灵地灵灵| | 2019-4-23 22:57 | 只看该作者
print嵌套太多,耗时太长。

使用特权

评论回复
10
磨砂| | 2019-5-10 08:51 | 只看该作者
大概能差多少

使用特权

评论回复
11
晓伍| | 2019-5-10 08:57 | 只看该作者
优先级抢占?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

561

帖子

4

粉丝