STM32
直播中

study875

12年用户 1142经验值
私信 关注
[问答]

STM8S105使用ADC1通道3,5,为什么通道3会随通道5改变呢?

基于 STM8MC-KIT v1.0 库;
问题:使用ADC1通道3,5,测试发现通道5使用正常,通道3随通道5电压改变,示波器测量通道3的电压为固定300mV值;为什么通道3会随通道5改变呢?通道3非悬空状态,实际上是经过电阻分压测量输出电源电压用的。上代码
初始化:

  • void Init_ADC( void )
  • {
  •         u8 value;
  •         u16 ADC_TDR_tmp;

  •         //ADC_Sync_State = ADC_USER_SYNC_INIT;
  •         ADC_Sync_State = ADC_CURRENT_INIT;
  •         ADC_State = ADC_SYNC;

  •         ADC1->CSR = 0;

  •         //select 4MHz clock based on 16MHz fMaster (div4), single mode
  •         //       6MHz clock based on 24MHz fMaster (div4)
  •         ADC1->CR1 = BIT5|BIT6;

  •         //select internal trigger tiM1 TRGO
  •         ADC1->CR2 = 0;

  •         //select phase input
  • //        ADC1->CSR = PHASE_C_BEMF_ADC_CHAN;
  •         ADC1->CSR = ADC_USER_ASYNC_CHANNEL;

  •         ADC_TDR_tmp = 0;
  • //        ADC_TDR_tmp |= (u16)(1) << PHASE_A_BEMF_ADC_CHAN;
  • //        ADC_TDR_tmp |= (u16)(1) << PHASE_B_BEMF_ADC_CHAN;
  • //        ADC_TDR_tmp |= (u16)(1) << PHASE_C_BEMF_ADC_CHAN;

  •         ADC_TDR_tmp |= (u16)(1) << ADC_CURRENT_CHANNEL;
  • //        ADC_TDR_tmp |= (u16)(1) << ADC_USER_SYNC_CHANNEL;

  •         ADC_TDR_tmp |= (u16)(1) << ADC_BUS_CHANNEL;
  • //        ADC_TDR_tmp |= (u16)(1) << ADC_NEUTRAL_POINT_CHANNEL;
  • //        ADC_TDR_tmp |= (u16)(1) << ADC_TEMP_CHANNEL;
  •         ADC_TDR_tmp |= (u16)(1) << ADC_USER_ASYNC_CHANNEL;

  •         ToCMPxH( ADC1->TDRH, ADC_TDR_tmp);
  •         ToCMPxL( ADC1->TDRL, ADC_TDR_tmp);

  •         //enable trigger
  •         ADC1->CR2 |= BIT6;

  •         //enable ADC
  •         ADC1->CR1 |= BIT0;
  •         //allow ADC to stabilize
  •         value=30;
  •         while(value--);
  •         //clear interrupt flag
  •         ADC1->CSR  = (u8)(~BIT7);
  •         ADC1->CSR |= BIT5;
  • }


中断:

  • #ifdef HALL
  •         @near @interrupt @svlreg void ADC2_IRQHandler (void)
  •         {
  •                 u16 data;

  •                 data = ADC1->DRH;
  •                 data <<= 2;
  •                 data |= (ADC1->DRL   0x03);

  •                 //clear interrupt flag
  •                 ADC1->CSR  = (u8)(~BIT7);
  •                 //ADC_Async_State = ADC_USER_ASYNC_SAMPLE;

  •                 // Manage async sampling
  •                 switch (ADC_Async_State)
  •                 {
  •                         default:
  •                         case ADC_BUS_SAMPLE:
  •                                 ADC_Buffer[ ADC_BUS_INDEX ] = data;
  •                                 //ADC_Async_State = ADC_TEMP_INIT;
  •                                 ADC_Async_State = ADC_USER_ASYNC_INIT;

  •                         break;

  •                         case ADC_TEMP_SAMPLE:
  •                                 ADC_Buffer[ ADC_TEMP_INDEX ] = data;
  •                                 ADC_Async_State = ADC_NEUTRAL_POINT_INIT;
  •                         break;

  •                         case ADC_NEUTRAL_POINT_SAMPLE:
  •                                 ADC_Buffer[ ADC_NEUTRAL_POINT_INDEX ] = data;
  •                                 ADC_Async_State = ADC_USER_ASYNC_INIT;
  •                         break;

  •                         case ADC_USER_ASYNC_SAMPLE:
  •                                 ADC_Buffer[ ADC_USER_ASYNC_INDEX ] = data;
  •                                 ADC_Async_State = ADC_BUS_INIT;
  •                         break;
  •                 }

  •                 // Set the Async sampling channel
  •                 switch (ADC_Async_State)
  •                 {
  •                         default:
  •                         case ADC_BUS_INIT:
  •                                 ADC1->CSR = (ADC_BUS_CHANNEL|BIT5);
  •                                 ADC_Async_State = ADC_BUS_SAMPLE;

  •                         break;

  •                         case ADC_TEMP_INIT:
  •                                 ADC1->CSR = (ADC_TEMP_CHANNEL|BIT5);
  •                                 ADC_Async_State = ADC_TEMP_SAMPLE;
  •                         break;

  •                         case ADC_NEUTRAL_POINT_INIT:
  •                                 ADC1->CSR = (ADC_NEUTRAL_POINT_CHANNEL|BIT5);
  •                                 ADC_Async_State = ADC_NEUTRAL_POINT_SAMPLE;
  •                         break;

  •                         case ADC_USER_ASYNC_INIT:
  •                                 ADC1->CSR = (ADC_USER_ASYNC_CHANNEL|BIT5);
  •                                 ADC_Async_State = ADC_USER_ASYNC_SAMPLE;
  •                         break;
  •                 }

  •                 // Configure syncronous sampling
  •                 #ifdef DEV_CUT_1
  •                         // Enable ext. trigger
  •                         ADC1->CR2 |= BIT6;
  •                         //turn on ADC fix bug on cut1 device
  •                         ADC1->CR1 |= BIT0;
  •                 #else
  •                         // Enable ext. trigger
  •                         ADC1->CR2 |= BIT6;
  •                 #endif
  •         }
  • #endif

回帖(1)

龙献益

2024-5-13 17:59:27
在STM8S105中,使用ADC1通道3和5时,通道3的值可能会随着通道5的值改变。这可能是由于以下几个原因:

1. **通道干扰**:在某些情况下,当两个通道相邻时,它们之间可能会发生干扰。这可能导致通道3的值受到通道5的影响。

2. **电阻分压器设计**:您提到通道3是通过电阻分压器测量输出电源电压的。如果电阻分压器的设计不当,可能会导致通道3的值受到通道5的影响。请检查电阻分压器的设计,确保它能够正确地将电源电压分压到ADC的参考电压范围内。

3. **ADC初始化设置**:请检查您的ADC初始化代码,确保所有相关的寄存器设置正确。以下是一些可能需要检查的设置:

   - 确保ADC1的通道3和5都已正确配置为输入通道。
   - 检查ADC1的参考电压设置,确保它与您的电阻分压器设计相匹配。
   - 检查ADC1的采样时间设置,确保它足够长以获得稳定的读数。

4. **硬件问题**:如果上述方法都不能解决问题,可能是硬件上的问题。请检查STM8S105的引脚连接,确保没有短路或错误的连接。

5. **软件问题**:请检查您的代码逻辑,确保在读取通道3和5的值时没有引入任何错误。

为了解决这个问题,您可以尝试以下步骤:

1. 仔细检查电阻分压器的设计,确保它能够正确地将电源电压分压到ADC的参考电压范围内。

2. 检查ADC初始化代码,确保所有相关的寄存器设置正确。

3. 如果可能,请尝试使用其他通道(例如通道2或4)来测量输出电源电压,以排除通道干扰的可能性。

4. 检查STM8S105的引脚连接,确保没有短路或错误的连接。

5. 如果问题仍然存在,您可能需要寻求硬件制造商或技术支持的帮助,以确定是否存在硬件问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分