打印
[技术问答]

ML51TC0AE,运行了一段自己编的ADC函数后,单片机好像降级成12T运行模式了

[复制链接]
2884|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2020-11-16 17:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
调试程序中对延时时间变长感到疑惑,遂寻找其问题原因所在,最后发现问题是在运行了一个自己编的ADC函数后出现的。我把该函数定义放在官方BSP文件中的ADC.C中,并在adc.h中也有声明。并非系统时钟变慢,我特意添加了一段函数测试异常过程中CLKO输出仍为24MHz。又特意编了个while(1)函数测试IO口输出方波频率,改变while(1)函数中内容,正常和异常时IO口输出频率之比不尽相同,有异常是IO口方波频率是正常时的5倍的,有比率是5.5倍的,正符合12T单片机和1T单片机(当然也不是所有指令都是1T)同频处理指令速度之比。请问这个是新唐ML51系列单片机的BUG吗?

问题补充 : 2019/09/18 15:35
延时函数跟STC单片机时用的差不多:

void delay_ms(unsigned int ms)

{

   unsigned int i;

         do{

              i = 24000000 / 13000;

                          while(--i)          //14T per loop

                                {

                                        ;

                                }

     }while(--ms);

}

正常时同STC一样延时时间很准,出现问题时该延时时间整整变为正常值的7倍。比较符合12T单片机和1T单片机的延时函数时间之比,刚好为整数的。新唐的ML51系列是新推出的单片机吧,感觉还是有些莫名其妙的问题,希望新唐赶紧解决。

问题补充 : 2019/09/18 15:45
引起问题的ADC函数如下:
float Get_ADCResult(unsigned char channel)                //channel = 0~7,VBG
{
  unsigned int ADC_Result;
        unsigned char ozc;
        u8 n;
        u16        adc_value_all = 0;
        float        adc_avg;

        ADC_Open(ADC_SINGLE,channel);

        for ( ozc=0; ozc<3; ozc++ )                //读取并丢弃前3次ADC结果,以获取准确值
        {
                clr_ADCCON0_ADCF;                   //清零ADC转换完成标志位
                set_ADCCON0_ADCS;                   //开始转换
                while(!(ADCCON0&SET_BIT7));           //等待转换结束
        }

        ADCRH = 0; ADCRL = 0;                      //调试用,验证是否真的进行了ADC转换
        clr_ADCCON0_ADCF;
        set_ADCCON0_ADCS;

        for(n=0;n<1;n++)                //对所测ADC通道电压进行10次采样,计算平均值
        {
                set_PCON_IDLE;                          //为提高ADC准确度,ADC时单片机进入IDLE待机状态
                while(!(ADCCON0&SET_BIT7));
                ADC_Result = (ADCRH<<4) + ADCRL;
                adc_value_all += ADC_Result;        //对进行AD转换,并对转换值进行累加
                ADC_Result = 0;
        }
        adc_avg = adc_value_all/1.0+0.0001; //加上0.0001是为了排除5171/10.0被计算成为517.0999的情况
        return        adc_avg;        
}

问题补充 : 2019/09/18 17:51
ML51_BSP_Keil_C51文件中的示例文件(StdDriver目录下的)ADC_Simple,将其代码改为如下,便可出现上述问题。

/*---------------------------------------------------------------------------------------------------------*/

/*                                                                                                         */

/* Copyright(c) 2019 Nuvoton Technology Corp. All rights reserved.                                         */

/*                                                                                                         */

/*---------------------------------------------------------------------------------------------------------*/



//***********************************************************************************************************

//  Website: http://www.nuvoton.com

//  E-Mail : MicroC-8bit@nuvoton.com

//***********************************************************************************************************



//***********************************************************************************************************

//  File Function: ML51 series ADC software trigger on shot demo code

//***********************************************************************************************************

#include "ML51.h"





#define en_MPW_CTR()  P56_PUSHPULL_MODE, SFRS = 0x00,        P5 |= SET_BIT6        //P56脚推挽输出高电平

#define dis_MPW_CTR() P56_PUSHPULL_MODE, SFRS = 0x00,        P5 &= CLR_BIT6        //P56脚推挽输出低电平





void ADC_ISR (void) interrupt 11

{

        ;

//   clr_ADCCON0_ADCF;                //clear ADC interrupt flag

}





void main ()

{

  unsigned int ADCRESULT;



          MFP_P16_UART0_TXD;                //设置P16为串口0输出

          P16_PUSHPULL_MODE;

    UART_Open(24000000,UART0_Timer3,115200);   // Open UART0 use timer1 as baudrate generate and baud rate = 115200

    ENABLE_UART0_PRINTF;

  

                ENABLE_ADC_INTERRUPT;

                ENABLE_GLOBAL_INTERRUPT;



                ADC_Open(ADC_SINGLE,1);                 //Enable ADC_CH4

    ADC_ConvertTime(3,7);

   

                clr_ADCCON0_ADCF;

    set_ADCCON0_ADCS;                       // Software trig adc start

    while((ADCCON0|CLR_BIT7)==CLR_BIT7);    // wait ADCF = 1;

    ADCRESULT = (ADCRH<<4)+ADCRL;

    printf("\n ADC result = 0x%X  ", ADCRESULT);

           Timer0_Delay(24000000,100,1000);

                                            

        while(1)

        {

                en_MPW_CTR();

                dis_MPW_CTR();

        }

               

}



,如果禁止ADC中断则不会出现上述问题。

使用特权

评论回复
沙发
jasontu| | 2020-11-17 07:55 | 只看该作者
把完整专案放上来吧。我跑看看是否是主频改变。

使用特权

评论回复
板凳
wahahaheihei| | 2020-11-17 13:25 | 只看该作者
不应该啊,如果没有修改时钟配置,怎么可能自动降级。

使用特权

评论回复
地板
wangfan8611| | 2020-11-21 16:23 | 只看该作者
wahahaheihei 发表于 2020-11-17 13:25
不应该啊,如果没有修改时钟配置,怎么可能自动降级。

我也出现了类似问题,系统运行过程中,系统时钟降频了,定时器中断的速度变为了原来的一半,通讯波特率也变了,导致通讯不上,求解。

使用特权

评论回复
5
gx_huang| | 2020-11-21 20:34 | 只看该作者
是否内部寄存器太多分区了,初始化寄存器时搞错了

使用特权

评论回复
6
elephant00| | 2021-7-20 10:55 | 只看该作者
可能是SFRS  page切换的问题。主循环中刚刚切换到page1,立马被中断打断了,中断里切换到page0后没有恢复到page1,就导主循环后的执行的语句就不对了。所以在中断有对SFR操作的内容,都需要在中断里备份SFRS的状态才行。

使用特权

评论回复
7
sparrow054| | 2021-8-11 14:18 | 只看该作者
这是什么逆天的问题?
楼主搞定木啊

使用特权

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

本版积分规则

2035

主题

7339

帖子

10

粉丝