OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5301|回复: 5

难缠的ADC_FLAG标志,ADC采样掉坑了。

[复制链接]

3

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2018-5-2
在线时间
16 小时
发表于 2021-9-4 19:20:54 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 wjw7680 于 2021-9-4 19:23 编辑

    做了一个24V电源的AD采集,MCU是STC8G1K08A。单片机其他功能都可以用,比如定时器与PWM。  就是在AD采集程序中ADC_FLAG标志不能读取到,好像是芯片内部硬件不能自动置1。搞了两三天反复阅读芯片规格书,也没找到问题在什么地方。程序一直死在while(!(ADC_CONTR & 0x20)); 这条语句上,读不到转换结束ADC_FLAG标志(以看到LED灯亮为判断读取数据)。由于不能在Keil内进行芯片硬件仿真,问题比较难找。哪位大侠能帮我出出主意,非常感谢!

以下是编写的AD采集程序:
#include        "config.h"
#include        "timer.h"
#include        "GPIO.h"
#include        "adc.h"

#define        POW_19V_ON   P54 //定义电源控制脚
#define Farad_ON  P55            //定义法拉电容供电控制脚
#define PC_OFF    P31           //定义PC断电后的关断信号输出

/*************        GPIO端口功能说明        **************

本例程基于STC8G1K08A-8PIN 为主控芯片的编写测试
1)P3.3的ADC3端采样超级电容充放电电压状态
2)P3.2的ADC2端口采样外部24V失电后下降速率。
3)P5.4使能DC_DC开关电源对PC供电。条件是P3.2失电低于22.8V使能DC_DC开始供电PC。
4)P5.5使能超级电容向外部供电。条件是P3.2采样外部24V电压下降到22.8V。

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

/************************ IO口输出推挽配置 ****************************/
void        GPIO_config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                                //结构定义
        
        GPIO_InitStructure.Pin  = GPIO_Pin_0|GPIO_Pin_1;                                //指定要初始化的IO, GPIO_Pin_0  GPIO_Pin_1
        GPIO_InitStructure.Mode = GPIO_OUT_PP;                        //指定IO推挽的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
        
        GPIO_InitStructure.Pin  = GPIO_Pin_4|GPIO_Pin_5;                                //指定要初始化的IO, GPIO_Pin_4  GPIO_Pin_5
        GPIO_InitStructure.Mode = GPIO_OUT_PP;                        //指定IO推挽的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P5,&GPIO_InitStructure);        //初始化
}


/********************* 配置P3.2与P3.3的ADC端口浮空输入 **************************/

void        GPIO_config_HighZ(void)
{
        
        GPIO_InitTypeDef        GPIO_InitStructure;                                //结构定义
        
        GPIO_InitStructure.Pin  = GPIO_Pin_2|GPIO_Pin_3;                                //指定要初始化的IO, GPIO_Pin_2, GPIO_Pin_3
        GPIO_InitStructure.Mode = GPIO_HighZ;                        //指定IO浮空输入方式
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
        
}


/******************* AD配置函数 *******************/
void        ADC_config(void)
{
        ADC_InitTypeDef                ADC_InitStructure;                //结构定义
        ADC_InitStructure.ADC_SMPduty   = 31;                //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
        ADC_InitStructure.ADC_CsSetup   = 0;                //ADC 通道选择时间控制 0(默认),1
        ADC_InitStructure.ADC_CsHold    = 1;                //ADC 通道选择保持时间控制 0,1(默认),2,3
        ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X16T;                //设置 ADC 工作时钟频率        ADC_SPEED_2X1T~ADC_SPEED_2X16T
        ADC_InitStructure.ADC_Power     = ENABLE;                                //ADC功率允许/关闭        ENABLE,DISABLE
        ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;        //ADC结果调整,右对齐        ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
        ADC_InitStructure.ADC_Polity    = Polity_0;                        //指定中断优先级(低到高) Polity_0,Polity_1,Polity_2,Polity_3
        ADC_InitStructure.ADC_Interrupt = DISABLE;                        //中断允许        ENABLE,DISABLE
        ADC_Inilize(&ADC_InitStructure);                                        //初始化

        
//          ADCCFG = 0x26;    // 转换数据右对齐,设置AD工作时钟频率 SYSclk/2/6
//          P_SW2 |= 0x80;   //打开操作特殊功能寄存器
//          ADCTIM = 0x3f;
//          P_SW2 |= 0x7f;   //关闭操作特殊功能寄存器
}


/******************** 主函数**************************/
void main(void)
{
        u16 DC_Data = 0;                   //AD转换数据缓冲
        u16 DC_Data24V = 0;
               

        GPIO_config();
        Timer_config();
        GPIO_config_HighZ();
        ADC_config();
                        
        EA = 1;          //开放所有中断        
        while(1)
        {
               
                ADC_CONTR = 0x82;  //打开AD转换电源,选择AD的第二通道P3.2管脚
                ADC_CONTR |= 0x40;  //启动AD转换
               
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
        
                while(!(ADC_CONTR & 0x20));  //查询转换结束标志
                ADC_CONTR &= (~0x20);          //清除转换标志
               
                DC_Data = ((u16)ADC_RES << 8) | ADC_RESL;        //ADC_RES强制转换成16位,与低八位转换数据逻辑或后生成最终转换数据
               
                DC_Data24V = DC_Data*6;    //24v分压取样比例为6,,真实值为DC_Data的6倍
                      if(DC_Data24V < 24)
                         PC_OFF = 1;              //点亮一个LED
                      else
                         PC_OFF = 0;        
        }
        
}

附电路图:
2{XUG`R77HXZAU7V04B9T.png



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

369

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4241
金钱
4241
注册时间
2020-7-24
在线时间
714 小时
发表于 2021-9-6 12:32:43 | 显示全部楼层
回复

使用道具 举报

0

主题

78

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1590
金钱
1590
注册时间
2018-10-11
在线时间
224 小时
发表于 2021-9-8 08:41:43 | 显示全部楼层
你确定8个_nop_();的时间够AD转换完成了?
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8204
金钱
8204
注册时间
2020-5-11
在线时间
3697 小时
发表于 2021-9-8 15:49:30 | 显示全部楼层
你如何知道它死在了那里?
专治疑难杂症
回复

使用道具 举报

0

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
162
金钱
162
注册时间
2019-7-5
在线时间
39 小时
发表于 2021-9-24 16:39:23 | 显示全部楼层
ADC_CONTR 是哪一位?
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2017-6-29
在线时间
17 小时
发表于 2021-9-28 14:46:23 | 显示全部楼层
我的正常使用,没有你说的问题


//P3.5电压采集
void ADC_Init()
{
        P3M1|=        1<<5;         //10高阻输入
        P3M0&=~(1<<5);

        ADCTIM=0x3F;    //采样时间
        ADCCFG=0x2F;    //数据右对齐,ADC时钟SYSclk/2/(16+1)  1.0368MHZ
        IE&=~(1<<5);          //禁止ADC中断
        ADC_CONTR&=~(1<<5); //清除转换结束标志位
        ADC_CONTR=0x80; //打开ADC电源
}

u16 ADC_START(u8 ADC_CHx)
{
        if(ADC_CHx>15)
                return 0;
       
        ADC_CONTR&=0xF0;
        ADC_CONTR|=ADC_CHx;
       
        ADC_CONTR|=1<<6; //开始转换
        _nop_();
  _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_(); //ADC启动后,必须要延时 33.1776MHZ 10个nop大约是337.7ns

        while((ADC_CONTR&0x20)==0);
        ADC_CONTR&=~(1<<5); //清除转换结束标志位

        return ((u16)ADC_RES<<8)|ADC_RESL;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 02:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表