找回密码
 立即注册
查看: 36|回复: 5

AI8051U在32位模式下不能使用PWM连续ADC采样的问题?

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:15
  • 最近打卡:2026-01-07 09:20:45
已绑定手机

8

主题

19

回帖

232

积分

中级会员

积分
232
发表于 3 天前 | 显示全部楼层 |阅读模式
代码如下。同样的代码。在8位模式下,ADC中断可以测到P33引脚在翻转,说明PWM自动触发ADC连续采样。但是32位模式下不能使用。求助!
/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

/*************  功能说明    **************

本例程基于AI8051U为主控芯片的实验箱进行编写测试.

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

程序使用P0口来演示跑马灯,输出低驱动。

下载时, 选择时钟 24MHZ (用户可自行修改频率).

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


#include "stdio.h"
#include "intrins.h"
#include <AI8051U.H>



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

#define MAIN_Fosc        40000000UL

//==========================================================================


/*************  本地常量声明    **************/


/*************  IO口定义    **************/

/*************  本地变量声明    **************/


/*************  本地函数声明    **************/

void  delay_ms(u8 ms);

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



#define ADC_SPEED   15      /* 0~15, ADC转换时间(CPU时钟数) = (n+1)*32  ADCCFG */
#define RES_FMT     (1<<5)  /* ADC结果格式 0: 左对齐, ADC_RES: D11 D10 D9 D8 D7 D6 D5 D4, ADC_RESL: D3 D2 D1 D0 0 0 0 0 */
                            /* ADCCFG     1: 右对齐, ADC_RES: 0 0 0 0 D11 D10 D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */




void adc_gpio_init() // 设置ADC输入口为高阻输入
{
  P1M0 = 0x00; P1M1 = 0xff; // P1口设置成高阻输入
  P3M0 |= 0x08; P3M1 &= ~0x08; //P33 设备强推挽输出。用来测试

}


void adc_pwma_config(u8 enable) // 初始化ADC
{
    if(enable )
                {

        ADCTIM = 0x3f;  //设置通道选择时间、保持时间、采样时间
            ADCCFG = 0x23;  //右对齐,设置时钟频率
           // ADCCFG = RES_FMT + ADC_SPEED;
        ADC_CONTR = ADC_POWER | ADC_EPWMT | 1; //选择 1 通道          
//        ADC_CONTR = 0x80;                           //使能ADC模块
//        ADC_CONTR |= 0x40;                          //启动AD转换

//            PWMA_PSCRH = 0;// 预分频器高8位
//            PWMA_PSCRL = 0 ; //预分频     
        PWMA_ARRH = 0x08;
            PWMA_ARRL = 0xA3; //100uS
//               
                EADC = 1;                                   //使能ADC中断       
                PWMA_CR2 = 0x20; //CEN 信号为 TRGO,可用于触发 ADC. 设置 0x10:单次触发;0x20:周期触发
        PWMA_IER = 0x40;
        PWMA_CR1 = 0x01; //设置 CEN 启动 PWMA 定时器,实时触发 ADC   
            EA = 1 ;

     }
          else
                {
                   PWMA_CR1 = 0x00; //设置 CEN 启动 PWMA 定时器,实时触发 ADC   
                }

}





/******************** 主函数 **************************/
void main(void)
{
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXSFR(); //扩展寄存器(XFR)访问使能

    CKCON = 0; //提高访问XRAM速度

    P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 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;   //设置为准双向口

    P3M0 |= 0x10; P3M1 &= ~0x10;

    adc_gpio_init(); // 设置ADC输入口为高阻输入
          adc_pwma_config(1) ;// 初始化ADC
       
       
       

  

       
    while(1)
    {
        delay_ms(200);
                P34 = !P34 ;
    }
}

//========================================================================
// 函数: void  delay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void  delay_ms(u8 ms)
{
     u16 i;
     do{
          i = MAIN_Fosc / 6000;
          while(--i);
     }while(--ms);
}







void ADC_ISR() interrupt 5  //ADC中断
{
       
   u16 new_data ;       
   ADC_CONTR &= ~0x20;                         //清中断标志
   P33 = !P33; //测频
   new_data = ((unsigned int)ADC_RES << 8) + ADC_RESL;

}



void PWMA_ISR() interrupt 26
{
    if(PWMA_SR1 & 0x01)
    {
        PWMA_SR1 &=~0x01;
    }
}

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-01-07 08:56:44
已绑定手机

98

主题

3975

回帖

8583

积分

荣誉版主

无情的代码机器

积分
8583
发表于 3 天前 | 显示全部楼层
位操作分 sbit直接赋值宏定义按位与或非
截图202601042111566567.jpg
截图202601042112062476.jpg

截图202601042112153957.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:15
  • 最近打卡:2026-01-07 09:20:45
已绑定手机

8

主题

19

回帖

232

积分

中级会员

积分
232
发表于 前天 08:27 | 显示全部楼层
erci*** 发表于 2026-1-4 21:12
位操作分 sbit直接赋值 和 宏定义按位与或非 :

确实如你所说。没注意到这两种定义方式

点评

8位单片机,可以被8整除的sfr地址才能位操作 32位单片机,所有的sfr都可以位操作,所以移植这两种的时候,需要注意一下这个问题 通常推荐使用与或宏定义实现操作  详情 回复 发表于 前天 09:17
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:15
  • 最近打卡:2026-01-07 09:20:45
已绑定手机

8

主题

19

回帖

232

积分

中级会员

积分
232
发表于 前天 08:29 | 显示全部楼层
问题解决
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:658
  • 最近打卡:2026-01-06 09:44:30
已绑定手机
已实名认证

124

主题

3314

回帖

8445

积分

版主

积分
8445
发表于 前天 09:17 | 显示全部楼层
jrh20*** 发表于 2026-1-5 08:27
确实如你所说。没注意到这两种定义方式

8位单片机,可以被8整除的sfr地址才能位操作
32位单片机,所有的sfr都可以位操作,所以移植这两种的时候,需要注意一下这个问题
通常推荐使用与或宏定义实现操作
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2026-01-07 00:00:02
已绑定手机

0

主题

42

回帖

275

积分

中级会员

积分
275
发表于 前天 20:42 | 显示全部楼层
学习了。!
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-1-7 16:00 , Processed in 0.120649 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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