初级会员
- 积分
- 65
- 金钱
- 65
- 注册时间
- 2018-5-2
- 在线时间
- 16 小时
|
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;
}
}
附电路图:
|
|