ADC转换不成功
CPU采用 STC32G12K328之 46 腿 P03 输入 2.5V;VREF = 5V
void ADC_Isr() interrupt 5
{
ADC_FLAG = 0; // 清零ADC中断标志
adc_result = ADC_RES*256 + ADC_RESL; // 读取ADC转换结果
ADC_START = 1; // 启动ADC转换
adc_i = adc_i + 1 ;
}
void ADC_Config()
{
P0M1 = 0x08;P0M0 = 0x00; // P0.3设置为高阻输入模式
ADC_CONTR &= 0xF0;
ADC_CONTR |= 0x0B; // 设置ADC通道为P0.3
// ADCTIM = 0x3F; // ADC时序设置:通道选择时间:1个时钟,通道保持时间:4个时钟,采样时间:32个时钟
// ADCCFG = 0x0F; // ADC频率设置:系统时钟/2/16,数据左对齐
// ADCCFG = 0x2F; // ADC频率设置:系统时钟/2/16,数据右对齐
ADCCFG &= ~0x0f;
ADCCFG |= 0x02; //SPEED(2)
ADCTIM = 0x35; //CSSETUP(0), CSHOLD(1), SMPDUTY(21)
ADC_POWER = 1; // 使能ADC
EADC = 1; // 使能ADC中断
}
//=================================================================
delay_ms(1000);
rs1_tx(0x55);
rs1_tx(0x55);
rs1_tx(0x55);
rs1_tx(0x55);
nn = adc_result ;
iii = adc_i ;
adc_i = 0 ;
rs1_tx((iii >> 8 >> 8 >> 8)&0xff);
rs1_tx((iii >> 8 >> 8)&0xff );
rs1_tx((iii >> 8 )&0xff );
rs1_tx(iii&0xff);
rs1_tx((nn >> 8 )&0xff );
rs1_tx(nn&0xff);
结果显示全是0
深圳国芯人工智能有限公司-库函数
adc_i有没有增加?把采样速率再大幅降低试试呢 没有增加,全是0 采用速率已经是最低了 ADCCFG |= 0x02; //ADC时钟 = FOSC/2/3
ADCTIM = 0x35; // SETUP = 1, CSHOLD = 2, SMPDUTY = 22,12为ADC转换时间固定为12
你的初始化ADC时钟为FOSC/6,ADC转换时间为(1+2+22+12)=37个ADC时钟,你没有提供主频,假设你使用24MHz,则ADC时钟为4MHz,ADC时间为37/4=9.25us。加上中断响应总时间大约为10~12us。
没看到你第一次在哪里启动ADC转换的?
假设你在别的地方启动了第一次ADC转换,则ADC中断里重复启动ADC转换,转换时间大约为10~12us,这么快的速度串口没法实时上传的。
请先用官方例子测试。 梁工 发表于 2025-2-16 13:51
ADCCFG |= 0x02; //ADC时钟 = FOSC/2/3
ADCTIM = 0x35; // SETUP = 1, CSHOLD = 2, SMPDUTY = 22 ...
梁工你好,说明书上公式如下,同你估算的有些不一样,你估算的没加1,speed也没算进去,正常情况需按下面的公式来套对吗?
sysclk
_________________________________________________
2*(speed+1)*[(cssetup+1)+(cshold+1)+(smpduty+1)+12] xxw123 发表于 2025-2-16 16:22
梁工你好,说明书上公式如下,同你估算的有些不一样,你估算的没加1,speed也没算进去,正常情况需按下面 ...
我的计算没有错,你再仔细看,我上面的参数是+1了的,你的设置是:
你设置SETUP=0,则SETUP时钟=1,
你设置CSHOLD=1,则CSHOLD时钟=2,
你设置SMPDUTY = 21,则SMPDUTY时钟为22。
ADC转换时间为12。
所以你的ADC总时间 = (1+2+22+12)=37个ADC时钟。
你的SPEED设置为2,则ADC时钟频率=FOSC/2/3。
建议一下,初始化寄存器时,尽量不要直接给十六进制值,不好读,可以使用我下面的宏定义,容易读懂,最重要的是不容易出错,也不用再取翻看手册寄存器:
/********************** ADC初始化函数 ************************/
#define D_ADC_POWER (1<<7) /* ADC电源,1开启,0关闭 */
#define D_ADC_START (1<<6) /* 启动转换,自动清0 */
#define D_ADC_FLAG (1<<5) /* 完成标志,软件清0 */
#define D_ADC_EPWMT (1<<4) /* 允许PWMA触发ADC */
#define D_ADC_SPEED 5 /* 0~15, ADC时钟 = SYSclk/2/(n+1) */
#define D_RES_FMT (1<<5) /* ADC结果格式 0: 左对齐, ADC_RES: D9 D8 D7 D6 D5 D4 D3 D2, ADC_RESL: D1 D0 000000 */
/* 1: 右对齐, ADC_RES: 000000D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */
#define CSSETUP (1<<7) /* 0~1,ADC通道选择时间 0: 1个ADC时钟, 1: 2个ADC时钟,默认0(默认1个ADC时钟) */
#define CSHOLD (1<<5) /* 0~3,ADC通道选择保持时间(n+1)个ADC时钟, 默认1(默认2个ADC时钟) */
#define SMPDUTY 20 /* 10~31, ADC模拟信号采样时间(n+1)个ADC时钟, 默认10(默认11个ADC时钟) */
/* ADC转换时间: 10位ADC固定为10个ADC时钟, 12位ADC固定为12个ADC时钟. */
void ADC_config(void)
{
// EAXFR = 1; //SFR enable
P1n_pure_input(1<<CHANNEL); //设置要做ADC的IO做高阻输入
ADC_CONTR = D_ADC_POWER + CHANNEL; //ADC on + channel
ADCCFG = D_RES_FMT + D_ADC_SPEED;
ADCTIM = CSSETUP + CSHOLD + SMPDUTY;
// ADC_START =1; //启动ADC转换, 完成后自动清零
// ADC_FLAG =0; //清除ADC完成(中断)标志
// ADC_EPWMT =1; //允许PWM触发ADC
// EADC= 1; //允许ADC中断
// PADCH = 1; //ADC 中断优先级高位
// PADC= 1; //ADC 中断优先级
}
谢谢梁工
页:
[1]