OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3445|回复: 5

新手编写的DMA+双ADC+串口通信程序。。求大神看看对不对

[复制链接]

4

主题

9

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-6-7
在线时间
10 小时
发表于 2016-6-13 17:21:44 | 显示全部楼层 |阅读模式
1金钱
[qq]496071617[/qq]#include "sys.h"#include "usart.h"               
#include "delay.h"        
#include "led.h"         
#include "timer.h"                                                   
#include "lcd.h"
#include "usmart.h"                          
#include "adc.h"                  
#include "dma.h"                  
#define get_dac_data_length 160
#define send_dac_data_length 1120

u32 get_adc_data[get_dac_data_length];
u8 send_dac_data[send_dac_data_length];

int main(void)
{        
        u8 SendBuff[7];
        u16 crc=0;
        u16 test_intex=0;/////////////////////////

         Stm32_Clock_Init(9);        //系统时钟设置  9倍频得到系统时钟为72M
        uart_init(72,115200);        //串口初始化为115200
        delay_init(72);                            //延时初始化
        TIM3_ADC_Init(499,71);
MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)send_dac_data,send_dac_data_length);//DMA1通道4,外设为串口1,存储器为SendBuff,长度5168.
        ADC_DMA_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)get_adc_data,get_dac_data_length);
        Adc_Init();                                  //ADC初始化
        SendBuff[0]=0xaa;
        SendBuff[1]=0xaa;
        SendBuff[2]=0x02;
        SendBuff[3]=0x04;

        //显示提示信息        

        while(1)
        {

                if(ADC_DMA_convert_finish==1)
                {

u16 i=0;
                        u16 j=0;
                        u8 k=0;

                        /*************************得到发送数据包******************************************************/
                        for(i=0;i<get_dac_data_length;i++)
                        {
                                 get_adc_data=(get_adc_data&0xffff)+(get_adc_data>>16);
         SendBuff[5]=(get_adc_data&0xffff)&0xff;//+(get_adc_data>>16)&0xff;
                     SendBuff[4]=((get_adc_data&0xffff)>>8)&0x0f;//+(((get_adc_data>>16)&0xffff)>>8)&0x0f;//get 12 bits data
                     crc=SendBuff[3]+SendBuff[4]+SendBuff[5];
                     SendBuff[6]= (crc ^ 0xFFFFFFFF) & 0xFF;

                                 for(j=0;j<7;j++)
                                 {
           send_dac_data[k++]=SendBuff[j];
         }

      }                        

            MYDMA_Enable(DMA1_Channel4);//开始一次DMA传输!
                        ADC_DMA_convert_finish=0;               
    }

        }
}


//初始化ADC
//这里我们仅以规则通道为例
//我们默认仅开启通道1                                                                                                                                          
void  Adc_Init(void)
{   
        //先初始化IO口
         RCC->APB2ENR|=1<<2;    //使能PORTA口时钟
        GPIOA->CRL&=0XFFFF0F0F;//PA1,PA3 anolog输入
        //通道10/11设置                        
        RCC->APB2ENR|=3<<9;    //ADC1,ADC2时钟使能         
        RCC->APB2RSTR|=3<<9;   //ADC1,ADC2复位
        RCC->APB2RSTR&=~(3<<9);//复位结束            
        RCC->CFGR&=~(3<<14);   //分频因子清零        对APB2(56M) 4分频得到ADC的失踪为14M
        //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
        //否则将导致ADC准确度下降!
        RCC->CFGR|=2<<14;  //这里设置AD转换器的分频时钟,在RCC_CFGR寄存器中,ADC时钟由高速APB2时钟经2,4 ,6 ,8分频后获得
        
        ADC1->CR1&=0XF0FFFF;   //工作模式清零
        ADC1->CR1|=6<<16;      //规则同步工作模式  
        ADC1->CR1&=~(1<<8);    //非扫描模式         
  //ADC1->CR1|=1<<8;          //扫描模式         
        ADC1->CR2|=0<<1;    //单次转换模式
        ADC1->CR2|=1<<8;   //启用DMA
        ADC1->CR2&=~(7<<17);           
        ADC1->CR2|=4<<17;           //定时器3的TRGO事件
        ADC1->CR2|=1<<20;      //允许外部事件触发
        ADC1->CR2&=~(1<<11);   //右对齐         
        ADC1->SQR1&=~(0XF<<20);
        ADC1->SQR1|=0<<20;     //  1个转换在规则序列中 也就是只转换规则序列1                        
  ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch///////////////////////////////////////////////////////////////////
        ADC1->SQR3|=ADC_CH1;        /////通道1///////////////////////////////////////////////////////////////////////////////////////
        //设置通道1的采样时间
        ADC1->SMPR2&=~(7<<3);  //通道1采样时间清空         
         ADC1->SMPR2|=5<<3;     //通道1  55.5周期

  ADC1->CR2|=1<<0;           //开启AD转换器         
        ADC1->CR2|=1<<3;       //使能复位校准  
        while(ADC1->CR2&1<<3); //等待校准结束                          
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。                  
        ADC1->CR2|=1<<2;        //开启AD校准           
        while(ADC1->CR2&1<<2);  //等待校准结束




  ADC2->CR1&=0XF0FFFF;   //工作模式清零
        ADC2->CR1|=6<<16;      //规则同步工作模式  
        ADC2->CR1&=~(1<<8);    //非扫描模式         
        //ADC1->CR1|=1<<8;          //扫描模式        
        ADC2->CR2|=1<<1;    //连续转换模式???????
        //ADC2->CR2|=1<<8;   //启用DMA??????
        //ADC2->CR2&=~(7<<17);           
        //ADC2->CR2|=4<<17;           //定时器3的TRGO事件
        ADC2->CR2|=0x07<<17;    //软件触发
        ADC2->CR2|=1<<20;      //允许外部事件触发
        ADC2->CR2&=~(1<<11);   //右对齐         
        
        ADC2->SQR1&=~(0XF<<20);
        ADC2->SQR1|=0<<20;     //  1个转换在规则序列中 也就是只转换规则序列1                        
  ADC2->SQR3&=0XFFFFFFE0;//规则序列1 通道ch///////////////////////////////////////////////////////////////////
        ADC2->SQR3|=ADC_CH3;        /////通道3///////////////////////////////////////////////////////////////////////////////////////
        //设置通道1的采样时间
        ADC2->SMPR2&=~(7<<3);  //通道1采样时间清空         
         ADC2->SMPR2|=5<<3;     //通道1  55.5周期

        ADC2->CR2|=1<<0;           //开启AD转换器         
        ADC2->CR2|=1<<20;      //允许外部事件触发///////////////////////////////////////
        ADC2->CR2|=1<<3;       //使能复位校准  
        while(ADC2->CR2&1<<3); //等待校准结束                          
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。                  
        ADC2->CR2|=1<<2;        //开启AD校准           
        while(ADC2->CR2&1<<2);  //等待校准结束
        ADC2->CR2|=1<<22; //启动规则转换通道
        //该位由软件设置以开始校准,并在校准结束时由硬件清除  
        //ADC1->CR2|=1<<22; //启动规则转换通道///////关闭规则启动,因为这里是由定时器2的事件来触发的
}



//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHxMA通道CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量  
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
        RCC->AHBENR|=1<<0;                        //开启DMA1时钟
        delay_ms(5);                                //等待DMA时钟稳定
        DMA_CHx->CPAR=cpar;                  //DMA1 外设地址
        DMA_CHx->CMAR=(u32)cmar;         //DMA1,存储器地址
        DMA1_MEM_LEN=cndtr;              //保存DMA传输数据量
        DMA_CHx->CNDTR=cndtr;            //DMA1,传输数据量
        DMA_CHx->CCR=0X00000000;        //复位
        DMA_CHx->CCR|=1<<1;     //允许DMA传输完中断
        DMA_CHx->CCR|=1<<4;                  //从存储器读
        DMA_CHx->CCR|=0<<5;                  //不执行循环模式
        DMA_CHx->CCR|=0<<6;                 //外设地址非增量模式
        DMA_CHx->CCR|=1<<7;                  //存储器增量模式
        DMA_CHx->CCR|=0<<8;                  //外设数据宽度为8位
        DMA_CHx->CCR|=0<<10;                 //存储器数据宽度8位
        DMA_CHx->CCR|=1<<12;                 //中等优先级
        DMA_CHx->CCR|=0<<14;                 //非存储器到存储器模式                  
  MY_NVIC_Init(1,3,DMA1_Channel4_IRQn ,3);        
}
//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
        DMA_CHx->CCR&=~(1<<0);       //关闭DMA传输
        DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量
        DMA_CHx->CCR|=1<<0;          //开启DMA传输
}         



//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHxMA通道CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量  
void ADC_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
        RCC->AHBENR|=1<<0;                        //开启DMA1时钟
        delay_ms(5);                                //等待DMA时钟稳定
        DMA_CHx->CPAR=cpar;                  //DMA1 外设地址
        DMA_CHx->CMAR=(u32)cmar;         //DMA1,存储器地址
        ADC_DMA1_MEM_LEN=cndtr;              //保存DMA传输数据量
        DMA_CHx->CNDTR=cndtr;            //DMA1,传输数据量
        DMA_CHx->CCR=0X00000000;        //复位
        DMA_CHx->CCR|=1<<1;     //允许DMA传输完中断
        DMA_CHx->CCR|=0<<4;                  //从外设读
        DMA_CHx->CCR|=1<<5;                  //不执行循环模式
        DMA_CHx->CCR|=0<<6;                 //外设地址非增量模式
        DMA_CHx->CCR|=1<<7;                  //存储器增量模式
        
        
        DMA_CHx->CCR|=2<<8;                  //外设数据宽度为32位
        DMA_CHx->CCR|=2<<10;                 //存储器数据宽度32位
        
        DMA_CHx->CCR|=1<<12;                 //中等优先级
        DMA_CHx->CCR|=0<<14;                 //非存储器到存储器模式        
  MY_NVIC_Init(1,3,DMA1_Channel1_IRQn ,2);
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

9

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-6-7
在线时间
10 小时
 楼主| 发表于 2016-6-13 17:22:12 | 显示全部楼层
目的是实现两个ADC采样后结果相加。。
回复

使用道具 举报

4

主题

9

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-6-7
在线时间
10 小时
 楼主| 发表于 2016-6-13 18:21:01 | 显示全部楼层
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11548
金钱
11548
注册时间
2014-4-1
在线时间
1316 小时
发表于 2016-6-13 18:35:29 | 显示全部楼层
实验效果怎么样?


回复

使用道具 举报

4

主题

9

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-6-7
在线时间
10 小时
 楼主| 发表于 2016-6-13 19:02:08 | 显示全部楼层
xuande 发表于 2016-6-13 18:35
实验效果怎么样?

想采集声音信号。。ADC1是可以正常采样的,但是ADC2好像就只可以采集到上半部分的波形。就不知道ADC2配置有没有问题?
回复

使用道具 举报

4

主题

9

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-6-7
在线时间
10 小时
 楼主| 发表于 2016-6-14 14:52:38 | 显示全部楼层
大神帮忙看看呀。ADC2配置正确吗?
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-12 12:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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