找回密码
 立即注册
查看: 1228|回复: 17

关于AI8G1K08A-8Pin的ADC采样问题

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-12-02 14:21:39
已绑定手机

1

主题

11

回帖

65

积分

注册会员

积分
65
发表于 2024-11-7 16:14:28 | 显示全部楼层 |阅读模式
本帖最后由 DebugLab 于 2024-11-7 21:16 编辑

用AI8G1K08A-8pin进行对母线高电压与IGBT温度采集

但是不知道为什么偶尔会出现adc采集不到的情况导致传出4096的情况
对电压采集的频率是10KHz,温度采集的频率是1KHz,下面是全部代码,求大佬解答{:5_300:}

#include        "config.h"
#include        "STC8G_H_ADC.h"
#include        "STC8G_H_GPIO.h"
#include        "STC8G_H_Delay.h"
#include        "STC8G_H_UART.h"
#include        "STC8G_H_NVIC.h"
#include        "STC8G_H_Switch.h"
#include         "STC8G_H_Timer.h"
#include        <math.h>

/***************   宏声明        ******************/
#define HVMAX        680

/*************        本地常量声明        **************/
u32 VCC = 5.0;

/*************        本地变量声明        **************/
struct Flag_bit
{
        u8 VoltAcqError : 1;                //电压采集出错
        u8 TempAcqError : 1;                //温度采集出错
        u8 Keep3 : 1;                                //保留位
        u8 Keep4 : 1;                                //保留位
};

union Flag_set
{
        u8 all;
        struct Flag_bit fbit;
};

typedef struct
{
        u8 IGBTTemperature;                        //温度
        u8 BUSVoltage;                                //电压
        union Flag_set Flagbit;                //状态
}PowerUartData;

PowerUartData pwruartdata;

u8 div_01ms = 0;
u8 div_1ms = 0;
u8 div_10ms = 0;
u8 div_100ms = 0;
u8 div_1s = 0;

int vcatch = 0;
int lastvcatch = 0;
/*************        本地函数声明        **************/

/*************  外部函数和变量声明 *****************/

/******************* IO配置函数 *******************/
void GPIO_config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                //结构定义
        //AD口设置为输入口
        GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        GPIO_InitStructure.Mode = GPIO_HighZ;                //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P5,&GPIO_InitStructure);        //初始化
        
        GPIO_InitStructure.Pin  = GPIO_Pin_3;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        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_2;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        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_1;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        GPIO_InitStructure.Mode = GPIO_PullUp;                //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化

        GPIO_InitStructure.Pin  = GPIO_Pin_0;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        GPIO_InitStructure.Mode = GPIO_OUT_PP;                //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
        P33 = 0;
        P32 = 0;
        P30 = 0;
}

/******************* 定时器1配置函数 *******************/
void TIMER0_config(void)
{
        TIM_InitTypeDef                TIM_InitStructure;                                                //结构定义

        //定时器0做16位自动重装, 中断频率为10KHZ
        TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;        //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
        TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T;                        //指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
        TIM_InitStructure.TIM_ClkOut    = DISABLE;                                //是否输出高速脉冲, ENABLE或DISABLE
        TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / 10000UL);                //初值,
        TIM_InitStructure.TIM_Run       = ENABLE;                                //是否初始化后启动定时器, ENABLE或DISABLE
        Timer_Inilize(Timer0,&TIM_InitStructure);                                //初始化Timer0          Timer0,Timer1,Timer2,Timer3,Timer4
        NVIC_Timer0_Init(ENABLE,Priority_1);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}

/******************* 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    = 2;                //ADC 通道选择保持时间控制 0,1(默认),2,3
        ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X16T;                //设置 ADC 工作时钟频率        ADC_SPEED_2X1T~ADC_SPEED_2X16T
        ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;        //ADC结果调整,        ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
        ADC_Inilize(&ADC_InitStructure);                //初始化
        ADC_PowerControl(ENABLE);                                //ADC电源开关, ENABLE或DISABLE
        NVIC_ADC_Init(DISABLE,Priority_0);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}

/***************  串口初始化函数 *****************/
void UART_config(void)
{
        COMx_InitDefine                COMx_InitStructure;                                        //结构定义

        COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;                //模式,   UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
        COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;                        //选择波特率发生器, BRT_Timer1 (注意: 串口2固定使用BRT_Timer2, 所以不用选择)
        COMx_InitStructure.UART_BaudRate  = 9600ul;                                //波特率,     110 ~ 115200
        COMx_InitStructure.UART_RxEnable  = ENABLE;                                //接收允许,   ENABLE或DISABLE
        UART_Configuration(UART1, &COMx_InitStructure);                        //初始化串口1 USART1,USART2,USART3,USART4
        NVIC_UART1_Init(ENABLE,Priority_1);                                                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
        UART1_SW(UART1_SW_P30_P31);                                                                //UART1_SW_P30_P31
}


/***************  电压采集函数 *****************/
/***************  参数:分压比 *****************/
/******************测试完成*********************/
u16        GetVin(u32 rate, u32 adc_value)
{
        u16 vin;
        vin = (VCC * adc_value * rate) >> 10;
        return vin;
}        

/***************  温度采集函数 *****************/
/***********  参数:R1-平衡电阻值***************/
/*****************测试完成**********************/
u8         GetTemp(u16 adc)
{
        //变量定义
        u16 Rntc;                                //热敏电阻值
        u8 Temp = 0;                        //温度
        
        Rntc = 2048000 / adc - 3000;                //(10位ADC)计算热敏电阻值
        //根据热敏电阻计算温度
        if(Rntc > 14000)
        {
                Temp = 0;
                return Temp;
        }
        else if(Rntc >= 10000)                                //0 - 7
        {
                Temp = 24 - Rntc * 7 / 4000;        
                return Temp;               
        }
        else if(Rntc >= 9000)                                //7 - 9
        {
                Temp = 27 - Rntc / 500;
                return Temp;        
        }
        else if(Rntc >= 8000)                                //9 - 12
        {
                Temp = 36 - Rntc * 3 / 1000;
                return Temp;
        }
        else if(Rntc >= 7000)                                //12 - 15
        {
                Temp = 36 - Rntc * 3 / 1000;
                return Temp;
        }
        else if(Rntc >= 6000)                                //15 - 20
        {
                Temp = 50 - Rntc / 200;
                return Temp;
        }
        else if(Rntc >= 5000)                                //20 - 26
        {
                Temp = 56 - Rntc * 3 / 500;
                return Temp;
        }
        else if(Rntc >= 4000)                                //26 - 32
        {
                Temp = 56 - Rntc * 3 / 500;
                return Temp;
        }
        else if(Rntc >= 3000)                                //32 - 40
        {
                Temp = 64 - Rntc / 125;
                return Temp;
        }
        else if(Rntc >= 2000)                                //40 - 52
        {
                Temp = 76 - Rntc * 3 / 250;
                return Temp;
        }
        else if(Rntc >= 1000)                                //52 - 75
        {
                Temp = 98 - Rntc * 23 / 1000;
                return Temp;
        }
        else if(Rntc >= 900)                                        //75 - 80
        {
                Temp = 125 - Rntc / 20;
                return Temp;
        }
        else if(Rntc >= 800)                                        //80 - 82
        {
                Temp = 98 - Rntc / 50;
                return Temp;
        }
        else if(Rntc >= 700)                                        //82 - 87
        {
                Temp = 122 - Rntc / 20;
                return Temp;               
        }
        else if(Rntc >= 600)                                        //87 - 93
        {
                Temp = 129 - Rntc * 3 / 50;
                return Temp;
        }
        else if(Rntc >= 500)                                        //93 - 100
        {
                Temp = 135 - Rntc * 7 / 100;
                return Temp;
        }
        else if(Rntc >= 400)                                        //100 - 107
        {
                Temp = 135 - Rntc * 7 / 100;
                return Temp;
        }        
        else if(Rntc >= 300)                                        //107 - 120
        {
                Temp = 159 - Rntc * 13 / 100;
                return Temp;
        }
        else if(Rntc >= 190)                                        //120 - 140
        {
                Temp = 174 - Rntc * 2 / 11;
                return Temp;
        }
        else
        {
                Temp = 140;
                return Temp;
        }
}

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

/**********************************************/
/*
        发送报文
*/
u8 Send_UpData(void)
{
        u16 relay = 0;
        
        //发送报文头
        SBUF = 0xEF;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        relay = 0;
        
        //发送电压值
        SBUF = pwruartdata.BUSVoltage;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        relay = 0;
        
        //发送温度值
        SBUF = pwruartdata.IGBTTemperature;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        relay = 0;
        
        //发送错误状态
        SBUF = pwruartdata.Flagbit.all;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        relay = 0;
        
        //发送5s内制动时间
        SBUF = pwruartdata.DISCTimes;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        relay = 0;
        
        //发送备用字节
        SBUF = 0xFF;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        relay = 0;
        
        //发送校验码
        SBUF = (0xEF + pwruartdata.BUSVoltage + pwruartdata.IGBTTemperature + pwruartdata.Flagbit.all + pwruartdata.DISCTimes + 0xFF) & 0xFF;
        COM1.B_TX_busy = 1;                //标志忙
        while(COM1.B_TX_busy)
        {
                if(++relay > 39999)
                {
                        return 0;
                }
        }
        
        return 1;
}

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

/**********************************************/
/*
        数据采集        
-        电压采集频率:10KHz               
-        温度采集频率:1KHz                        
-        数据获取频率:1KHz
*/
u8 GetVinValue(void)
{
        static u8 cnt = 0;
        static u16 adc = 0;
        static u16 vsum = 0;
        static u16 errcnt = 0;


        
        adc = Get_ADCResult(4);                                                                //获取电压ad值
        
        if(adc == 4096)                                                                                //判断ad值是否合法
        {
                if(++errcnt > 1999)                                                                //连续一秒非法ad值报警
                {
                        pwruartdata.Flagbit.fbit.VoltAcqError = 1;                        //电压采集错误标志置1
                }
                return 0;
        }
        else
        {
                errcnt = 0;
        }
        
        vsum += GetVin(251, adc);                                                        //计算十次电压总和
        if(++cnt > 9)                                                                                //平均滤波
        {
                vcatch = (vsum * 1.05) / cnt;                                        //添加比例增益补偿                2024/9/5
                pwruartdata.BUSVoltage = vcatch / 3;
                cnt = 0;
                vsum = 0;
        }
        
        pwruartdata.Flagbit.fbit.VoltAcqError = 0;
        return 1;
}

u8 GetTempValue(void)
{
        static u16 cnt = 0;
        static u16 adc = 0;
        static u32 tsum = 0;
        static u16 errcnt = 0;


        
        adc = Get_ADCResult(5);                                                                //获取温度ad值
        
        if(adc == 4096)                                                                                //判断ad值是否合法
        {
                if(++errcnt > 999)                                                                //连续一秒非法ad值报警
                {
                        pwruartdata.Flagbit.fbit.TempAcqError = 1;        //温度采集错误标志置1
                }
                return 0;
        }
        else
        {
                errcnt = 0;
        }
        
        tsum += GetTemp(adc);                                                                //计算五百次温度总和
        if(++cnt > 499)                                                                                //平均滤波
        {
                pwruartdata.IGBTTemperature = tsum / cnt;
                cnt = 0;
                tsum = 0;
        }
        
        pwruartdata.Flagbit.fbit.TempAcqError = 0;
        return 1;
}
/**********************************************/

/**********************************************/
/*
        任务分时函数
*/
void TaskDiv(void)
{
        static u8 timer1 = 0,timer2 = 0,timer3 = 0,timer4 = 0;
        div_01ms = 1;
        if(++timer1 > 9)
        {
                timer1 = 0;
                div_1ms = 1;
                if(++timer2 >9)
                {
                        timer2 = 0;
                        div_10ms = 1;
                        if(++timer3 > 9)
                        {
                                timer3 = 0;
                                div_100ms = 1;
                                if(++timer4 > 9)
                                {
                                        timer4 = 0;
                                        div_1s = 1;
                                }
                        }
                }
        }
}

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

void main(void)
{

        EAXSFR();                /* 扩展寄存器访问使能 */
        GPIO_config();
        UART_config();
        ADC_config();
        TIMER0_config();
        EA = 1;
        
        
        pwruartdata.IGBTTemperature = 0;
        pwruartdata.BUSVoltage = 0;
        pwruartdata.Flagbit.all = 0;
        //轮询
        while (1)////////////////////////
        {
               
                if(div_01ms)                                                //0.1ms任务
                {
                        GetVinValue();
                        div_01ms = 0;
                }
                if(div_1ms)                                                        //1ms任务
                {
                        GetTempValue();
                        div_1ms = 0;
                }
                if(div_10ms)                                                //10ms任务
                {
                        Send_UpData();
                        div_10ms = 0;
                }
               
                if(div_100ms)                                                //100ms任务
                {
                        div_100ms = 0;
                }
               
                if(div_1s)                                                        //1s任务
                {
                        div_1s = 0;
                }
        }
}


其他有什么需要了解的都可以问我

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:123
  • 最近打卡:2025-04-19 16:12:35
已绑定手机

60

主题

777

回帖

4001

积分

论坛元老

自定义头衔

积分
4001
发表于 2024-11-7 16:31:05 | 显示全部楼层
看起来是 Get_ADCResult 函数返回了4096?不是12位ADC吗,数值范围应该是0~4095。
联系我请点击左下角的【回复】按钮,否则我收不到消息提
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-12-02 14:21:39
已绑定手机

1

主题

11

回帖

65

积分

注册会员

积分
65
发表于 2024-11-7 16:37:33 | 显示全部楼层
VC*** 发表于 2024-11-7 16:31
看起来是 Get_ADCResult 函数返回了4096?不是12位ADC吗,数值范围应该是0~4095。

这个芯片是10位ADC,那个函数是官方示例里的,4096只是错误值
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:417
  • 最近打卡:2025-04-30 21:39:09
已绑定手机

34

主题

2096

回帖

2206

积分

荣誉版主

积分
2206
发表于 2024-11-7 21:25:47 | 显示全部楼层
发现了好多变量类型使用不规范或者不匹配的情况,C语言各种变量的取值范围要看看啊
睁开眼睛做场梦~~~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-12-02 14:21:39
已绑定手机

1

主题

11

回帖

65

积分

注册会员

积分
65
发表于 2024-11-8 08:24:57 | 显示全部楼层
晓*** 发表于 2024-11-7 21:25
发现了好多变量类型使用不规范或者不匹配的情况,C语言各种变量的取值范围要看看啊 ...

可能有些范围会更大,但没有出现不够越界的情况
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-11-18 15:44:50 | 显示全部楼层
Get_ADCResult返回4096的情况有2种
1是输入的通道参数超过15
2是ADC采样时间超时
你可以通过这两个方面排查,先确定是通道参数问题还是采样超时问题。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-12-02 14:21:39
已绑定手机

1

主题

11

回帖

65

积分

注册会员

积分
65
发表于 2024-11-18 15:48:30 | 显示全部楼层
乘风*** 发表于 2024-11-18 15:44
Get_ADCResult返回4096的情况有2种
1是输入的通道参数超过15
2是ADC采样时间超时

之前用过控制寄存器方式采样,就是卡死在ADC采样时间超时了,一直收不到采样成功的标志
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-11-19 09:03:00 | 显示全部楼层
Emmet*** 发表于 2024-11-18 15:48
之前用过控制寄存器方式采样,就是卡死在ADC采样时间超时了,一直收不到采样成功的标志 ...

确认一下你用的芯片8G1K08后面是带“A”的?如果不带A的8PIN芯片是没有ADC功能的。
确定带“A”的话,可以直接烧录附件例子的hex文件到芯片里试试,串口打印ADC采集结果。

16路ADC轮询-每路16次ADC转换取中间8次求平均值-串口1返回结果.zip

10.86 KB, 下载次数: 114

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-12-02 14:21:39
已绑定手机

1

主题

11

回帖

65

积分

注册会员

积分
65
发表于 2024-11-22 09:20:13 | 显示全部楼层
乘风*** 发表于 2024-11-19 09:03
确认一下你用的芯片8G1K08后面是带“A”的?如果不带A的8PIN芯片是没有ADC功能的。
确定带“A”的话,可 ...

[09:17:09.950]接收←ADC00=1023  
[09:17:10.169]接收←ADC01=1023  
[09:17:10.388]接收←ADC02=0018  
[09:17:10.604]接收←ADC03=0034  
[09:17:10.823]接收←ADC04=0000  
[09:17:11.026]接收←ADC05=0261  
[09:17:11.244]接收←ADC06=0000  
[09:17:11.460]接收←ADC07=0000  
                    
[09:17:11.676]接收←ADC08=0000  
[09:17:11.893]接收←ADC09=0000  
[09:17:12.111]接收←ADC10=0000  
[09:17:12.330]接收←ADC11=0000  
[09:17:12.546]接收←ADC12=0000  
[09:17:12.747]接收←ADC13=0000  
[09:17:12.965]接收←ADC14=0000  
[09:17:13.182]接收←Bandgap=0250  
这是打印出来的结果
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-12-02 14:21:39
已绑定手机

1

主题

11

回帖

65

积分

注册会员

积分
65
发表于 2024-11-22 09:23:02 | 显示全部楼层
这是ADC4和5部分的原理图
截图202411220922296802.jpg
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 02:45 , Processed in 0.122220 second(s), 107 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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