victorsnow 发表于 2025-3-31 12:23:14

ADC USB仿真时无法读取

使用8H8K64U制作了USB仿真,在Keil下调试,读取内部标准电压的ADC值


#include    "reg51.h"       //包含此头文件后,里面声明的寄存器不需要再手动输入,避免重复定义
#include    "intrins.h"

#define   MAIN_Fosc       24000000L   //定义主时钟

typedef   unsigned char   u8;
typedef   unsigned int    u16;
typedef   unsigned long   u32;

//手动输入声明"reg51.h"头文件里面没有定义的寄存器
sfr TH2= 0xD6;
sfr TL2= 0xD7;
sfr IE2   = 0xAF;
sfr INT_CLKO = 0x8F;
sfr AUXR = 0x8E;
sfr AUXR1 = 0xA2;
sfr P_SW1 = 0xA2;
sfr P_SW2 = 0xBA;
sfr S2CON = 0x9A;
sfr S2BUF = 0x9B;

sfr ADC_CONTR = 0xBC;   //带AD系列
sfr ADC_RES   = 0xBD;   //带AD系列
sfr ADC_RESL= 0xBE;   //带AD系列
sfr ADCCFG = 0xDE;

sfr P4   = 0xC0;
sfr P5   = 0xC8;
sfr P6   = 0xE8;
sfr P7   = 0xF8;
sfr P1M1 = 0x91;    //PxM1.n,PxM0.n   =00--->Standard,    01--->push-pull
sfr P1M0 = 0x92;    //                  =10--->pure input,11--->open drain
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

sbit P00 = P0^0;
sbit P01 = P0^1;
sbit P02 = P0^2;
sbit P03 = P0^3;
sbit P04 = P0^4;
sbit P05 = P0^5;
sbit P06 = P0^6;
sbit P07 = P0^7;
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
sbit P15 = P1^5;
sbit P16 = P1^6;
sbit P17 = P1^7;
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
sbit P30 = P3^0;
sbit P31 = P3^1;
sbit P32 = P3^2;
sbit P33 = P3^3;
sbit P34 = P3^4;
sbit P35 = P3^5;
sbit P36 = P3^6;
sbit P37 = P3^7;
sbit P40 = P4^0;
sbit P41 = P4^1;
sbit P42 = P4^2;
sbit P43 = P4^3;
sbit P44 = P4^4;
sbit P45 = P4^5;
sbit P46 = P4^6;
sbit P47 = P4^7;
sbit P50 = P5^0;
sbit P51 = P5^1;
sbit P52 = P5^2;
sbit P53 = P5^3;
sbit P54 = P5^4;
sbit P55 = P5^5;
sbit P56 = P5^6;
sbit P57 = P5^7;

#define ADCTIM (*(unsigned char volatile xdata *)0xfea8)

u16 Get_ADC12bitResult(u8 channel)//channel = 0~15
{
    ADC_RES = 0;
    ADC_RESL = 0;

    ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //启动 AD 转换
    _nop_();
    _nop_();
    _nop_();
    _nop_();

    while((ADC_CONTR & 0x20) == 0);   //wait for ADC finish
    ADC_CONTR &= ~0x20;   //清除ADC结束标志
    return(((u16)ADC_RES << 8) | ADC_RESL);
}


/**********************************************/
void main(void)
{
    u16 j;

    P_SW2 |= 0x80; //扩展寄存器(XFR)访问使能

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
    P1M1 = 0x40;   P1M0 = 0x00;   //设置 P1.6 为 ADC 输入口
   
    ADCTIM = 0x3f;                //设置 ADC 内部时序,ADC采样时间建议设最大值
    ADCCFG = 0x2f;                //设置 ADC 时钟为系统时钟/2/16
    ADC_CONTR = 0x80; //使能 ADC 模块
               
    EA = 1;   //打开总中断

                Get_ADC12bitResult(15);//先读一次并丢弃结果, 让内部的采样电容的电压等于输入值.
                j = Get_ADC12bitResult(15);//读外部电压ADC
                j++;      
} 一直卡在
while((ADC_CONTR & 0x20) == 0);   //wait for ADC finishADC_CONTR 值 0xcf
不知是何情况,ADC跟USB有冲突吗


不仿真的时候可以正常跑

国芯人工智能 发表于 2025-3-31 12:28:00

在您提供的代码和描述中,您提到在使用8H8K64U微控制器进行USB仿真时,无法通过Keil调试器读取内部标准电压的ADC值。以下是一些可能的原因和解决方案,供您参考:

1. ADC配置问题
ADC时钟配置:确保ADC时钟源配置正确。ADC的采样速度与时钟频率直接相关,若时钟配置不当,可能导致ADC无法正常工作。
ADC通道选择:检查ADCCONTR寄存器中的通道选择位,确保选择了正确的ADC通道进行采样。
ADC电源控制:ADCCONTR寄存器中的ADC电源控制位(ADCPOWER)需要设置为1,以开启ADC模块。

2. 寄存器配置
ADCCONTR寄存器:确保ADCCONTR寄存器配置正确,包括ADC启动位(ADCSTART)和通道选择位(CHS2:CHS0)。
ADCCFG寄存器:检查ADCCFG寄存器的配置,确保ADC分辨率和采样时间设置正确。
ADCRES和ADCRESL寄存器:在读取ADC结果时,确保正确读取ADCRES和ADCRESL寄存器中的值,并根据ADC分辨率进行相应的处理。

3. 电源和参考电压
参考电压:确保内部参考电压(VREF)正确配置,并且稳定。如果使用内部参考电压,确保VREF引脚连接到稳定的电源。
电源稳定性:ADC模块对电源稳定性要求较高,确保电源稳定,避免电源噪声影响ADC采样。

4. 调试环境
Keil调试器:确保Keil调试器配置正确,能够正确读取ADC寄存器的值。可以尝试使用Keil的Memory窗口直接查看ADC相关寄存器的值,以确认ADC是否正常工作。
仿真模式:在Keil的仿真模式下,某些硬件外设可能无法完全仿真,建议在实际硬件上进行调试。

5. 代码示例
   以下是一个简单的ADC初始化及读取的代码示例,供您参考:

   ```c
   void ADCInit() {
       ADCCONTR = 0x80; // 开启ADC电源
       ADCCFG = 0x20;    // 设置ADC分辨率为10位,采样时间为12个时钟周期
   }

   u16 ADCRead(u8 ch) {
       ADCCONTR = 0x80 | (ch & 0x07); // 选择通道并启动ADC
       nop(); nop(); nop(); nop(); // 等待ADC采样完成
       while (!(ADCCONTR & 0x20)); // 等待ADC转换完成
       ADCCONTR &= ~0x20; // 清除ADC完成标志
       return (ADCRES

[本文内容由国芯人工智能辅助生成,仅供参考]
页: [1]
查看完整版本: ADC USB仿真时无法读取