- 打卡等级:偶尔看看I
- 打卡总天数:10
- 最近打卡:2024-12-02 14:21:39
已绑定手机
注册会员
- 积分
- 65
|
本帖最后由 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;
}
}
}
其他有什么需要了解的都可以问我
|
|