找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 392|回复: 13
打印 上一主题 下一主题
收起左侧

请教一下,为什么我的单片机ADC_DMA进不了中断

[复制链接]
跳转到指定楼层
楼主
#include "stc8h.h"
#include "eeprom.h"
#include "stdio.h"
#include "intrins.h"



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

/*************        ±¾µØ³£Á¿ÉùÃ÷        **************/
//1~16,使用的ADC转换通道数量,必须和[ADC_DMA通道使能寄存器(DMA_ADC_CHSWx)]中启用的ADC通道数量一致
#define ADC_CH_NUM          1  
//ADC转换次数,必须和[ADC_DMA配置寄存器2(DMA_ADC_CFG2)]设置的一致
#define ADC_SAMPLES_NUM     8   
//每个通道ADC转换数据总字节数=2*转换次数+4
#define ADC_DATA_SIZE       (ADC_SAMPLES_NUM*2 + 4)   

//存储ADC DMA转换结果,即ADC DMA的目的地址
u8 xdata adc_samples_buff[ADC_CH_NUM][ADC_DATA_SIZE];   
//ADC DMA转换完成标志
bit DmaFlag;





void Uart1_Init(void);        //4800bps@11.0592MHz
void sendByte(char dat);
void sendString(unsigned char *dat);
char putchar(char c);
void adc_dma_config(void);  
void Delay500ms(void);        //@11.0592MHz
void ADC_Init(void);


void main()
{
   u8 i,j;  
   u16 adc_value;   
   float voltage;
   Uart1_Init();
   ADC_Init();

   EA = 1;  
   printf("Hello");  

   while(1)
   {   
           if(DmaFlag)  
           {  
                      DmaFlag = 0;  
         
                      adc_value=(adc_samples_buff[0][16]<<8)+adc_samples_buff[0][17];
                      voltage   = (5*adc_value)/4096;         
                       printf("voltage: %.2fV\r\n",voltage);   

                     DMA_ADC_CR = 0xC0;      
           }
           Delay500ms();
        }

}



void adc_dma_config(void)  
{  
   P_SW2 = 0x80;  
   DMA_ADC_STA = 0x00;         //清零ADC DMA状态寄存器
   DMA_ADC_CFG = 0x80;         //开启ADC DMA中断
   DMA_ADC_RXAH = (u8)((u16)(&adc_samples_buff) >> 8); //ADC转换数据存储地址,即ADC DMA目的地址
   DMA_ADC_RXAL = (u8)((u16)(&adc_samples_buff));  
   DMA_ADC_CFG2 = 0x0A;    //每个通道ADC转换次数:8
   DMA_ADC_CHSW0 = 0x01;   //使能ADC通道1
   DMA_ADC_CHSW1 = 0x00;   
   DMA_ADC_CR = 0xC0;      //启动ADC DMA转换
}  

void ADC_Init(void)
{
        P1M0=0x00;                 //设置P10为高阻输入
        P1M1=0x01;

           ADCTIM = 0x3F;                  //设置ADC内部时许
        ADCCFG = 0x2F;                  //设置ADC时钟为系统时钟,数据右对齐
        ADC_CONTR = 0x80;    //使能ADC模块

}

void Uart1_Init(void)        //4800bps@11.0592MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据位,可变波特率
        AUXR &= 0xBF;                //定时器时钟12T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;               
        TMOD |= 0x20;               
        TL1 = 0xFA;                       
        TH1 = 0xFA;                       
        ET1 = 0;                       
        TR1 = 1;                       
}



void sendByte(char dat)
{
        SBUF = dat;
        while(!TI);
        TI = 0;      
}

void sendString(unsigned char *dat)
{
        while(*dat != '\0')
        {
                sendByte(*dat++);
        }
}

char putchar(char c)
{
        sendByte(c);
        return c;
}

void ADC_DMA_Interrupt(void) interrupt 13
{
        DMA_ADC_STA = 0;
        DmaFlag = 1;
}


void Delay500ms(void)        //@11.0592MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 22;
        j = 3;
        k = 227;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1034262 发表于 2024-7-12 17:40 | 只看该作者
试试STC官方的例子:
STC8H系列-ADC相关程序.rar (918.47 KB, 下载次数: 3)

回复

使用道具 举报

板凳
ID:1109793 发表于 2024-7-12 17:49 | 只看该作者
8G和8H的ADC中断向量号好像是5吧,我看工具里面的示例里面的是5
void ADC_Isr() interrupt 5
{
    ADC_CONTR &= ~0x20;                         //清中断标志
    P2 = ADC_RES;                               //读取ADC结果
    ADC_CONTR |= 0x40;                          //继续AD转换
}
回复

使用道具 举报

地板
ID:624769 发表于 2024-7-13 13:04 | 只看该作者
看你你中断号用的 13
那么……, 你 LJMP 那段汇编 写了没有?
并且,是否用的 .A51 格式? 是否正确插入了项目?
回复

使用道具 举报

5#
ID:298743 发表于 2024-7-14 14:44 | 只看该作者
xiaobendan001 发表于 2024-7-12 17:49
8G和8H的ADC中断向量号好像是5吧,我看工具里面的示例里面的是5
void ADC_Isr() interrupt 5
{

STC的官方程序写的是13
回复

使用道具 举报

6#
ID:298743 发表于 2024-7-14 14:46 | 只看该作者
188610329 发表于 2024-7-13 13:04
看你你中断号用的 13
那么……, 你 LJMP 那段汇编 写了没有?
并且,是否用的 .A51 格式? 是否正确插入 ...

这个"stc8h.h"这个头文件没有吗?我程序里还有中断12 开的定时器2也能正常工作
回复

使用道具 举报

7#
ID:1109793 发表于 2024-7-14 15:00 | 只看该作者
asdadqw2 发表于 2024-7-14 14:44
STC的官方程序写的是13

改成5试试啊,你的官方历程截图看看吧
回复

使用道具 举报

8#
ID:161164 发表于 2024-7-14 17:36 | 只看该作者
asdadqw2 发表于 2024-7-14 14:44
STC的官方程序写的是13

例程是13没错,但还要加中断号48跳到13的附加操作



回复

使用道具 举报

9#
ID:1109793 发表于 2024-7-14 20:07 | 只看该作者
lkc8210 发表于 2024-7-14 17:36
例程是13没错,但还要加中断号48跳到13的附加操作

那是处理大于31号的手段。ADC的就是5,又不大于31,为何要借用13号?13号就是保留的,让编译器把服务代码放到13号的位置,然后在不如32号的位置人为添加LJMP跳转到13号。借用其他不使用的也一样啊。但是ADC的就是5号,直接用就行了啊,不懂为何要借用,然后还得添加汇编代码。这不是那啥?
回复

使用道具 举报

10#
ID:624769 发表于 2024-7-14 20:31 | 只看该作者
asdadqw2 发表于 2024-7-14 14:46
这个"stc8h.h"这个头文件没有吗?我程序里还有中断12 开的定时器2也能正常工作

你如果看得是官方例程,你继续往下翻,应该会有类似这样的代码:
ISR.ASM
CSEG  AT  0183H
LJMP  0063H
END
你把他做成 ASM 文件 加入到项目里才可以。
回复

使用道具 举报

11#
ID:161164 发表于 2024-7-14 22:19 | 只看该作者
xiaobendan001 发表于 2024-7-14 20:07
那是处理大于31号的手段。ADC的就是5,又不大于31,为何要借用13号?13号就是保留的,让编译器把服务代码 ...

因为他用的是DMA_ADC,而不是单纯的ADC
回复

使用道具 举报

12#
ID:1109793 发表于 2024-7-15 07:28 | 只看该作者
lkc8210 发表于 2024-7-14 22:19
因为他用的是DMA_ADC,而不是单纯的ADC

哦,没用过H的,刚下载了PDF看了下是48号,话说DMA有啥好处?还要借用跳转。直接用ADC中断不行?
回复

使用道具 举报

13#
ID:161164 发表于 2024-7-16 16:09 | 只看该作者
xiaobendan001 发表于 2024-7-15 07:28
哦,没用过H的,刚下载了PDF看了下是48号,话说DMA有啥好处?还要借用跳转。直接用ADC中断不行?

不用频繁进中断
回复

使用道具 举报

14#
ID:1109793 发表于 2024-7-16 18:23 | 只看该作者
lkc8210 发表于 2024-7-16 16:09
不用频繁进中断

意思是时不时的关掉48号?DMA中断也是中断啊。5号也可以时不时 的关闭一下吧。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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