- 打卡等级:偶尔看看I
- 打卡总天数:18
- 最近打卡:2026-01-14 15:00:51
已绑定手机
中级会员
- 积分
- 263
|
发表于 2026-1-6 16:18:03
|
显示全部楼层
我的目的是想让 ADC 以DMA的方式,扫描ADC0~ADC7通道。每625微秒轮巡一次。无限循环。AI8051U 32位模式。如下配置,没有观察到P33翻转。
/*---------------------------------------------------------------------*/
/* --- 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
#define ADC_CH 8
#define ADC_DATA 6
u8 xdata AdcDmaBuff[ADC_CH][ADC_DATA] = {0};
u8 data AdcDmaFlag = 0; // AdcDma中断标志位
void UartPutc(unsigned char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
char putchar(char c)
{
UartPutc(c);
return c;
}
//==========================================================================
void Uart1Init(void) //115200bps@40.000MHz
{
P3M0 &=~ 0X01;
P3M1 &=~ 0X02;
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xA9; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
//ES = 1; //串口中断允许
}
//=============================================================================
void Uart1Send(u8 dat)
{
SBUF = dat ; //
while(TI==0)
{;}
TI = 0;
}
void uart1_send_bytes_to_str(unsigned char *p,unsigned int length) // // 串口 4 发CR数组里的数据,可以设置长度
{
unsigned char code zi[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned int i = 0;
unsigned char tempH ;
unsigned char tempL ;
while(i<length)
{
tempH = zi[(*(p+i))>>4];
tempL = zi[(*(p+i)&0x0f)];
Uart1Send(tempH);
Uart1Send(tempL);
Uart1Send(' ');
i++;
}
}
//======================================================================================
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_dma_config() // 初始化ADC
{
ADCCFG &= ~0x0f; //SPEED(0) 400KSPS@40.000MHz
ADCTIM = 0xff; //CSSETUP(1), CSHOLD(3), SMPDUTY(31)
ADC_CONTR = 0X80; //选择 1 通道
DMA_ADC_STA = 0x00;
DMA_ADC_CFG = 0x8A; //bit7 1:Enable Interrupt 中断优先级2,数据总线优先级2
DMA_ADC_RXAH = (u8)((u16)AdcDmaBuff >> 8); //ADC转换数据存储地址
DMA_ADC_RXAL = (u8)AdcDmaBuff;
DMA_ADC_CFG2 = 0x00; //每个通道ADC转换次数:1
DMA_ADC_CHSW0 = 0xff; //ADC通道使能寄存器 ADC7~ADC0
DMA_ADC_CHSW1 = 0x00; //ADC通道使能寄存器 ADC15~ADC8
DMA_ADC_AMTH = 0XFF; //设置循环扫描总次数寄存器 0XFFFF 表示无限循环
DMA_ADC_AMT = 0XFF;
DMA_ADC_ITVH = (u8)((40*625)/256 );//设置两次ADC之间的时间隔 625uS
DMA_ADC_ITVL = (u8)((40*625)%256 );
DMA_ADC_CR = 0xc0; //bit7 1:Enable ADC_DMA, bit6 1:Start ADC_DMA
EA = 1 ;
}
/******************** 主函数 **************************/
void main(void)
{
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
// EAXFR = 1; //扩展寄存器(XFR)访问使能
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;
Uart1Init();
adc_gpio_init(); // 设置ADC输入口为高阻输入
//
adc_dma_config() ;// 初始化ADC
while(1)
{
delay_ms(200);
P34 = !P34 ;
printf("adc\n");
}
}
//========================================================================
// 函数: 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 ADC_DMA_Interrupt(void) interrupt 13
{
if( DMA_ADC_STA &0x01 ) //ADC DMA中断
{
DMA_ADC_STA = 0;
printf("e");
P33 = !P33; //测频
}
}
//============================================================
|
|