打印
[STM32F0]

STM32F0开启8个以上通道进入死EOC死等待

[复制链接]
763|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2023-10-16 10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在使用STM32F0做一个AVR控制简单逻辑,比较奇怪的是,只开启前8个通道一切正常,大于8个以上会进入死EOC死等待,读取AD使用同一个函数,具体如下:

void STM32_RCC_Init(void)
{

        RCC->CR |= RCC_CR_HSION;
        while((RCC->CR&RCC_CR_HSIRDY)== 0);
//        RCC->CFGR |= RCC_CFGR_SWS_PLL;
//        RCC->CFGR |= RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV2;
        RCC->CFGR |= RCC_CFGR_PLLSRC_HSI_DIV2;
        RCC->CFGR |= RCC_CFGR_SW_PLL;
        RCC->CFGR |= RCC_CFGR_PLLMUL12;
        RCC->CR |= RCC_CR_PLLON;
        while((RCC->CR&RCC_CR_PLLRDY) == 0);
//        RCC->APB2RSTR |= RCC_APB2RSTR_tiM16RST;
//        RCC->APB2RSTR |= RCC_APB2RSTR_TIM1RST;
//        RCC->APB2RSTR |= RCC_APB2RSTR_ADCRST;
        
        RCC->AHBENR = RCC->AHBENR|RCC_AHBENR_GPIOAEN|RCC_AHBENR_GPIOBEN
                      |RCC_AHBENR_GPIOCEN|RCC_AHBENR_GPIODEN;
        RCC->APB2ENR = RCC->APB2ENR|RCC_APB2ENR_SYSCFGCOMPEN
                      |RCC_APB2ENR_ADCEN|RCC_APB2ENR_TIM16EN|RCC_APB2ENR_TIM1EN;
        
        RCC->CR2 |= RCC_CR2_HSI14ON;
        
        while(RCC_CR2_HSI14RDY == 0);        
}


void STM32_GPIO_Init(void)
{
        GPIOA->MODER = 0x6955ffff;
//        GPIOA->MODER = 0x2800ffff;
        GPIOB->MODER = 0x55565557;
        GPIOB->AFR[1] = 0x02;
        
        GPIOC->MODER = 0x00115fff;
        
        GPIOD->MODER = 0x00000010;
        
}


void STM32_ADC_Init(void)
{
        ADC1->SMPR |= ADC_SMPR_SMP_2|ADC_SMPR_SMP_0;
        ADC1->CR |= ADC_CR_ADCAL;
        while(((ADC1->CR)&ADC_CR_ADCAL) != 0);
        ADC1->CFGR1 |=  ADC_CFGR1_OVRMOD;
        ADC1->CR |= ADC_CR_ADEN;
        while(((ADC1->ISR)&ADC_ISR_ADRDY) == 0);
}



//读取AD值函数
unsigned short ADConvertValues(unsigned char ADChanel)
{
        unsigned char ADC_DelayCNT = 0;
        while(((ADC1->ISR)&ADC_ISR_ADRDY) == 0);
        ADC1->CHSELR = (1<<adchanel);
         ADC1->CR |= ADC_CR_ADSTART;
        while (!((ADC1->ISR) & ADC_ISR_EOC));
        /*
        {
                ADC_DelayCNT++;
                if(ADC_DelayCNT>250)
                {
                        return ADC1->DR;
                }
        }
        */
        return ADC1->DR;
}


//前面8通道读取在定时器TIM1里面做的,一切正常。
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
  static unsigned short PowButtonCheckcnt;
  static unsigned short PageDownCheckcnt;
  static unsigned short LcdCnt;
  unsigned short DataTep;
  unsigned short DataTepA;
        unsigned short DataTepB;
        unsigned short DataTepC;
  unsigned long DataComp;
  unsigned char ADCCH;
  TIM1->SR = 0x00;
  McLedBoostOn;        
  for(ADCCH=0;ADCCH<9;ADCCH++)
  {
                DataTep = ADConvertValues(ADCCH);
    if(DataTep >= AdOffSetValue)
    {
       DataTep = DataTep - AdOffSetValue;
    }
    else
    {
       DataTep = AdOffSetValue - DataTep;
    }
    DataComp = DataTep;
    DataComp = DataComp*DataTep;

    switch(ADCCH)
    {
     //InputVoltageRMS/
                        case 0:
        NewInPutAPhaseVoltageBuff = NewInPutAPhaseVoltageBuff+DataComp;
      break;
                        case 1:
        NewInPutBPhaseVoltageBuff = NewInPutBPhaseVoltageBuff+DataComp;
      break;
                        case 2:
        NewInPutCPhaseVoltageBuff = NewInPutCPhaseVoltageBuff+DataComp;
      break;
                        
                        //OutputVoltageRMS/  
                        case 3:
        NewOutPutAPhaseVoltageBuff = NewOutPutAPhaseVoltageBuff+DataComp;
        DataTepA = DataTep;
      break;
                        case 4:
        NewOutPutBPhaseVoltageBuff = NewOutPutBPhaseVoltageBuff+DataComp;
        DataTepB = DataTep;
      break;
                        case 5:
        NewOutPutCPhaseVoltageBuff = NewOutPutCPhaseVoltageBuff+DataComp;
        DataTepC = DataTep;
      break;
                        
                        //OutputVoltageCurrent/
                        case 6:
        NewOutPutAPhaseCurrentBuff = NewOutPutAPhaseCurrentBuff+DataComp;
        DataComp = DataTepA;
        DataComp = DataComp*DataTep;
        NewOutPutAPhaseWatBuff = NewOutPutAPhaseWatBuff+DataComp;
      break;
                        case 7:
        NewOutPutBPhaseCurrentBuff = NewOutPutBPhaseCurrentBuff+DataComp;
        DataComp = DataTepB;
        DataComp = DataComp*DataTep;
        NewOutPutBPhaseWatBuff = NewOutPutBPhaseWatBuff+DataComp;
      break;
                        case 8:
        NewOutPutCPhaseCurrentBuff = NewOutPutCPhaseCurrentBuff+DataComp;
        DataComp = DataTepC;
        DataComp = DataComp*DataTep;
        NewOutPutCPhaseWatBuff = NewOutPutCPhaseWatBuff+DataComp;
      break;
    }
   }
   AD_CONV_CNT++;
         NTC_Check_Funcion();
   if(AD_CONV_CNT == 0x36)
   {
      GPIOA->BRR =  (~(unsigned short)(AVRControl_REG<<8))&0xff00;
   }
   if(AD_CONV_CNT == 0x4a)
   {
     if(New_mode != OutRang_mode)
     {
        GPIOA->BSRR = (unsigned short)(AVRControl_REG<<8)&0xff00;
     }
   }

}

//后面8通道用于NTC采样,只要开启一组就有问题,无论该函数放在中断也好,主函数也好,采取单通道扫描也会出现一样问题。

void NTC_Check_Funcion(void)
{
        switch(NTC_AD_CNT)
        {
                case 9:
                        NTC_RSCR_Ad_Buff = NTC_RSCR_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
                case 10:
                        NTC_SSCR_Ad_Buff = NTC_SSCR_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
                case 11:
                        NTC_TSCR_Ad_Buff = NTC_TSCR_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
                case 12:
                        NTC_RTX_Ad_Buff = NTC_RTX_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
                case 13:
                        NTC_STX_Ad_Buff = NTC_STX_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
                case 14:
                        NTC_TTX_Ad_Buff = NTC_TTX_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
                case 15:
                        NTC_ENV_Ad_Buff = NTC_ENV_Ad_Buff+ADConvertValues(NTC_AD_CNT);
                break;
        }        
        NTC_AD_CNT++;
        if(NTC_AD_CNT == 10)
        {
                NTC_AD_CNT = 9;
                NTC_CheckCnt ++;
        }
  if(NTC_CheckCnt == 16)
  {
    NTC_CheckCnt = 0;
    NTC_RSCR_Ad_Buff = NTC_RSCR_Ad_Buff>>4;
          NTC_SSCR_Ad_Buff = NTC_SSCR_Ad_Buff>>4;
                NTC_TSCR_Ad_Buff = NTC_TSCR_Ad_Buff>>4;
                NTC_RTX_Ad_Buff = NTC_RTX_Ad_Buff>>4;
                NTC_STX_Ad_Buff = NTC_STX_Ad_Buff>>4;
                NTC_TTX_Ad_Buff = NTC_TTX_Ad_Buff>>4;
                NTC_ENV_Ad_Buff = NTC_ENV_Ad_Buff>>4;
               
    NTC_RSCR_Level = NTC_Level_Dect(NTC_RSCR_Ad_Buff);
                NTC_SSCR_Level = NTC_Level_Dect(NTC_SSCR_Ad_Buff);
                NTC_TSCR_Level = NTC_Level_Dect(NTC_TSCR_Ad_Buff);
                        
                NTC_RTX_Level = NTC_Level_Dect(NTC_RTX_Ad_Buff);
                NTC_STX_Level = NTC_Level_Dect(NTC_STX_Ad_Buff);
                NTC_TTX_Level = NTC_Level_Dect(NTC_TTX_Ad_Buff);
                        
                NTC_ENV_Level = NTC_Level_Dect(NTC_ENV_Ad_Buff);
                        
                NTC_RSCR_Ad_Buff = 0;
                NTC_SSCR_Ad_Buff = 0;
                NTC_TSCR_Ad_Buff = 0;
                NTC_RTX_Ad_Buff = 0;
                NTC_STX_Ad_Buff = 0;
                NTC_TTX_Ad_Buff = 0;
                NTC_ENV_Ad_Buff = 0;
               
    if((NTC_RSCR_Level == 0xff)||(NTC_SSCR_Level == 0xff)||(NTC_TSCR_Level == 0xff)
                        ||(NTC_RTX_Level == 0xff)||(NTC_STX_Level == 0xff)||(NTC_TTX_Level == 0xff)
                        ||(NTC_ENV_Level == 0xff))
                {
                        STAT_FLAGE.TepError = 1;
                }
  }   
}</adchanel);

使用特权

评论回复
沙发
classroom| | 2023-10-16 11:32 | 只看该作者
STM32F0系列微控制器在硬件上可能有限制,无法同时处理多个通道的ADC(模拟-数字转换器)转换。确保你的设备支持你想要使用的通道数量。

使用特权

评论回复
板凳
laocuo1142| | 2023-10-16 11:32 | 只看该作者
检查你的时序设置是否正确,并确保所有通道都能在预期的时间内完成转换。

使用特权

评论回复
地板
classroom| | 2023-10-16 11:32 | 只看该作者
如果多个通道同时尝试访问相同的资源,例如ADC寄存器或DMA(直接存储器访问)通道,可能会出现冲突。确保为每个通道分配独立的资源,并检查是否有任何资源冲突。

使用特权

评论回复
5
BullTalented| | 2023-10-24 09:46 | 只看该作者
检查一下时序设置是否正确

使用特权

评论回复
6
在曼谷的春| | 2023-11-19 13:42 | 只看该作者
你可以试试模拟开关,就是模拟快速开关,一个ADC可以采集多个通道了

使用特权

评论回复
7
将爱藏于深海| | 2023-11-19 16:00 | 只看该作者
这轮询的方式也不行吗?

使用特权

评论回复
8
白马过平川| | 2023-11-19 18:00 | 只看该作者
你是想一下读取8个通道的ADC数据么?

使用特权

评论回复
9
西洲| | 2023-11-19 20:00 | 只看该作者
正常来说应该是可以的,可以获取八个通道的数据

使用特权

评论回复
10
捧一束彼岸花| | 2023-11-19 22:00 | 只看该作者
你可以参考一下ST的多通道ADC读取操作

使用特权

评论回复
11
月亮一键变蓝| | 2023-11-20 01:00 | 只看该作者
大于八个通道会有问题是么?

使用特权

评论回复
12
温室雏菊| | 2023-11-20 03:00 | 只看该作者
STM32这个芯片好像只支持八通道一起读吧?

使用特权

评论回复
13
一只眠羊| | 2023-11-20 05:00 | 只看该作者
你可以试试把通道数减少点,试试2通道,4通道这种

使用特权

评论回复
14
风凉| | 2023-11-20 09:00 | 只看该作者
看你函数好像没啥问题,但是多通道读取ADC的操作,应该是没问题的才对啊

使用特权

评论回复
15
故意相遇| | 2023-11-20 13:00 | 只看该作者
你试试用cubemx配置一下试试吧,也许会好用了,因为寄存器总是容易出问题的

使用特权

评论回复
16
童雨竹| | 2024-8-11 08:02 | 只看该作者

让PCB顶层和底层一样,将它们通过一些过孔(或通孔)连接

使用特权

评论回复
17
Wordsworth| | 2024-8-11 09:05 | 只看该作者

孔璧里头必须经过电镀

使用特权

评论回复
18
Clyde011| | 2024-8-11 10:08 | 只看该作者

需要将阻焊漆(阻焊油墨)覆盖在最外层的PCB设计布线上

使用特权

评论回复
19
公羊子丹| | 2024-8-11 11:01 | 只看该作者

电源中都有一个交流电压最大的节点

使用特权

评论回复
20
万图| | 2024-8-11 12:04 | 只看该作者

做多层板可将做好的两块双面板用特制的粘合剂“压合”起来

使用特权

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

本版积分规则

2038

主题

7364

帖子

10

粉丝