- 打卡等级:偶尔看看I
- 打卡总天数:15
- 最近打卡:2026-01-07 09:20:45
已绑定手机
中级会员
- 积分
- 232
|
代码如下。同样的代码。在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;
}
}
|
|