微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于多路AD采样问题

关于多路AD采样问题

时间:10-02 整理:3721RD 点击:
编译没错,可能存储地址哪里有错误,配置地址数组不知道正确否,求大神解答,感谢,主要是从存储地址里取值,又LED显示,但是就是没显示,好纠结。下面是我的程序。
#include "stm32f10x_lib.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"
#include <stdio.h>
#include "led.h"
///////////////////////////////////////////
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void EXTI_Configuration(void);
void DMA_Config(void);//配置DMA1_CHx
void DMA_Enable(DMA_Channel_TypeDef*DMA_CHx);//使能DMA1_CHx
void ADC1_Init(void);
///////////////////////////////////////////
unsigned int N=50,M=6;
vu16  AD_Value[50][6];   //用来存放ADC转换结果,也是DMA的目标地址
vu16  After_filter[6];    //用来存放求平均值之后的结果
int i;
long unsigned int x=0,y,n0,n1,n2,n3,z,m=0;
u16 table[10]={0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009};   
ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void)
{   RCC_DeInit();
        RCC_HSEConfig(RCC_HSE_ON);
    HSEStartUpStatus=RCC_WaitForHSEStartUp();
        if(HSEStartUpStatus==SUCCESS)
     {
          RCC_HCLKConfig(RCC_SYSCLK_Div1);
          RCC_PCLK2Config(RCC_HCLK_Div1);
          RCC_PCLK1Config(RCC_HCLK_Div2);
          FLASH_SetLatency(FLASH_Latency_2);
          RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
          RCC_PLLCmd(ENABLE);
          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)  {}
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
          while(RCC_GetSYSCLKSource()!=0x08) {}
           }
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_SPI1|
          RCC_APB2Periph_AFIO,ENABLE);
}
//DMA配置
void DMA_Config(void)
{
//第2步,DMA时钟使能
RCC->AHBENR|=1<<0;//DMA时钟使能
//第2步,DMA时钟使能
DMA1_Channel1->CPAR=(u32)&ADC1->DR;//DMA1 外设地址
DMA1_Channel1->CMAR=(u32)&AD_Value;//DMA1,存储器地址         
DMA1_Channel1->CNDTR=N*M;//DMA1,传输数据量
DMA1_Channel1->CCR=0x00000000;//复位
DMA1_Channel1->CCR|=1<<8;//外设大小PSIZE[1:0]=01
DMA1_Channel1->CCR|=1<<10;//存储器大小MSIZE[1:0]=01
DMA1_Channel1->CCR|=0<<6;//外设地址增量禁用,PINC=0
DMA1_Channel1->CCR|=1<<7;//存储器地址增量使能,MINC=1

DMA1_Channel1->CCR|=1<<5;//使能循环模式,CIRC=0
DMA1_Channel1->CCR|=1<<4;//从存储器读, DIR=1
DMA1_Channel1->CCR|=2<<12;//中等优先级
DMA1_Channel1->CCR|=0<<14;//非存储器到存储器模式
DMA1_Channel1->CCR|=1<<0;//通道使能
}
//开启 DMA传输
void DMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{   
        DMA_CHx->CCR&=~(1<<0);  //关闭DMA传输
        DMA_CHx->CNDTR=N*M ;  //DMA1,传输数据量
        DMA_CHx->CCR|=1<<0;  //开启DMA传输
}
//AD配置
void ADC1_Init(void)
{
//第1步,PORTA.1时钟使能
RCC->APB2ENR|=1<<2;//PORTA时钟使能        
GPIOA->CRL&=0xFF000000;//配置PA1为复用输入引脚      
RCC->AHBENR|=1<<0;
//第2步,ADC1时钟使能
RCC->APB2ENR|=1<<9;     //ADC1时钟使能        
RCC->APB2RSTR|=1<<9;    //ADC1复位时钟
RCC->APB2RSTR&=~(1<<9); //ADC1复位结束
RCC->CFGR&=~(3<<14);    //分频因子清零
RCC->CFGR|=2<<14;       //72/6=12M
ADC1->CR1&=~(0x0f<<16);  //工作方式清零
ADC1->CR1|=0<<16;        //独立模式DULMOD[3:0]=0000
ADC1->CR1|=1<<8;         //扫描模式使能 SCAN=1
ADC1->CR2&=~(1<<1);
ADC1->CR2|=1<<1;       //连续转换模式 CONT=1
ADC1->CR2&=~(7<<17);     //软件控制方式        EXTSEL[3:0]=111,SWSTART
ADC1->CR2|=7<<17;        //EXTSEL[3:0]=111,SWSTART
ADC1->CR2|=0<<20;        //使用外部触发EXTTRIG=1
ADC1->CR2&=~(1<<11);     //右对齐
ADC1->SMPR2&=~(7<<0);    //SMP1[3:0]=111,239.5个周期
ADC1->SMPR2|=7<<0;
ADC1->SMPR2&=~(7<<3);    //SMP1[3:0]=111,239.5个周期
ADC1->SMPR2|=7<<3;
ADC1->SMPR2&=~(7<<6);    //SMP2[3:0]=111,239.5个周期
ADC1->SMPR2|=7<<6;
ADC1->SMPR2&=~(7<<9);    //SMP3[3:0]=111,239.5个周期
ADC1->SMPR2|=7<<9;
ADC1->SMPR2&=~(7<<12);   //SMP4[3:0]=111,239.5个周期
ADC1->SMPR2|=7<<12;
ADC1->SMPR2&=~(7<<15);   //SMP5[3:0]=111,239.5个周期
ADC1->SMPR2|=7<<15;
//ADC1->SMPR2|=0<<0;
ADC1->SQR1&=~(0x0F<<20); //L[3:0]=0000,一个转换
ADC1->SQR1|=0x6<<20;     //L[3:0]=0000,1个转换
ADC1->SQR3&=~0XFFFFFFFF; //首先清零 第一个转换 通道ch
ADC1->SQR3|=0<<0;//第1个转换为通道0
ADC1->SQR3|=1<<5;//第2个转换
ADC1->SQR3|=2<<10;//第3个转换
ADC1->SQR3|=3<<15;//第4个转换
ADC1->SQR3|=4<<20;//第5个转换
ADC1->SQR3|=5<<25;//第6个转换
ADC1->CR2&=~(1<<8);        //DMA=1,DMA使能
ADC1->CR2|=1<<8;
ADC1->CR2|=1<<22;           //开始转换规则通道
ADC1->CR2|=1<<0;                //ADCON=1,启动A/D
ADC1->CR2|=1<<3;
while(ADC1->CR2&1<<3);
ADC1->CR2|=1<<2;
while(ADC1->CR2&1<<2);
}
//获取AD值
u16 Get_Adc(u8 ch)   
{
        //设置转换序列                           
        ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch
        ADC1->SQR3|=ch;                                              
        ADC1->CR2|=1<<22;       //启动规则转换通道
        while(!(ADC1->SR&1<<1));//等待转换结束                   
        return ADC1->DR;                    //返回adc值       
}
//求平均值函数
void filter(void)
{
   int sum=0;
   u8 count;
   for(i=0;i<6;i++)
   {
     for(count=0;count<N;count++)
         {
           sum+=AD_Value[count][i];
         }
         After_filter[i]=sum/N;
         sum=0;
        }
}
//串口显示配置
void SPI1_Init(void)
{            
  //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
  //GPIO_PinRemapConfig(GPIO_Remap_SPI1,ENABLE);
  RCC->APB2ENR|=1<<0;
  RCC->APB2ENR|=1<<2;           //PORTA
  RCC->APB2ENR|=1<<3;     //PORTB时钟使能
  RCC->APB2ENR|=1<<4;            //PORTC
  RCC->APB2ENR|=1<<12;    //SPI1时钟使能
//只针对SPI口初始化
  GPIOC->CRH&=0xFFFF0FFF;
  GPIOC->CRH|=0x00003000; //配置PC11为输出  26引脚
  AFIO->MAPR&=0XF8FFFFFE;
  AFIO->MAPR|=0x0A000001;
  GPIOA->CRH&=0x0FFFFFFF;
  GPIOA->CRH|=0xB0000000;
  GPIOB->CRL&=0xFF0F0FFF;
  GPIOB->CRL|=0x00B0B000; //配置PB3.5为复用输出
  GPIOC->ODR&=0<<11;
  SPI1->CR1|=1<<15;
  SPI1->CR1|=1<<14;        
  SPI1->CR1|=1<<8;         //内部从设备选择
  SPI1->CR1|=1<<2;         //主从设备选择,配置为主设备
  SPI1->CR1|=1<<11;        //收发数据长度,8bit数据格式
  SPI1->CR1|=1<<1;         //时钟极性选择,空闲状态适保瑂ck保持高电平
  SPI1->CR1|=1<<0;         //数据采样从第二个时间边沿开始
  SPI1->CR1|=7<<3;         //波特率控制?現sck=Fcpu/256
  SPI1->CR1|=0<<7;         //MSBfirst,第一个发送位选择
  SPI1->CR2|=1<<2;
  SPI1->CR1|=1<<6;         //SPI设备使能
}
//u16 SPI2_WriteByte(u16 TxData)
//{
//  u8 retry=0;
//        while((SPI2->SR&1<<1)==0)
//        {
//                 retry++;
//                 if(retry>200) return 0;
//   }
//        SPI2->DR=TxData;
//}
//LED显示
void max7219_init(void)
{
  GPIOC->ODR&=0<<11;       
  SPI1->DR=0x09ff;         //译码方式  
  while((SPI1->SR&1<<1)==0)//等待数据发送完毕
  {}
  delay_ms(0.1);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);        
       
  GPIOC->ODR&=0<<11;       
  SPI1->DR=0x0A0a;         //亮度级别0-f
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.1);
  GPIOC->ODR|=1<<11;                         
  delay_ms(0.1);
  GPIOC->ODR&=0<<11;       
  SPI1->DR=0x0B07;         //扫描界限寄存器
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.1);
  GPIOC->ODR|=1<<11;                         
  delay_ms(0.1);
  GPIOC->ODR&=0<<11;       
  SPI1->DR=0x0C01;         //停机方式,开启(1),停机(0)
  while((SPI1->SR&1<<1)==0)
  delay_ms(0.1);
  GPIOC->ODR|=1<<11;                         
  delay_ms(0.1);
  GPIOC->ODR&=0<<11;       
  SPI1->DR=0x0F00;         //测试模式,开(1),关(0)
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.1);
  GPIOC->ODR|=1<<11;                         
  delay_ms(0.1);
}
//////////////////////////////////////////////
void display1(void)
{
  filter();
  x=After_filter[1];
  y=x;      
  y=y%10000;
  n3=y/1000;
  GPIOC->ODR&=0<<11;        //PB0为0
  SPI1->DR=0x0100|table[n3];
  while((SPI1->SR&1<<7)==1)//等待数据发送完毕
  {}
  delay_ms(0.01);          //延时
  GPIOC->ODR|=1<<11;        //PB0为1
  delay_ms(0.1);       
                 
  n2=(y-n3*1000)/100;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0200|table[n2];
  while((SPI1->SR&1<<7)==1)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);
         
  n1=(y-n3*1000-n2*100)/10;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0300|table[n1];
  while((SPI1->SR&1<<7)==1)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);
  n0=y-n3*1000-n2*100-n1*10;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0400|table[n0];
  while((SPI1->SR&1<<7)==1)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);
}
////////////////////////////////////
void display2(void)
{
  m++;
  z=m;        
  z=z%10000;
  n3=z/1000;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0500|table[n3];
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);                  
  n2=(z-n3*1000)/100;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0600|table[n2];
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);     
  n1=(z-n3*1000-n2*100)/10;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0700|table[n1];
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);
  n0=z-n3*1000-n2*100-n1*10;
  GPIOC->ODR&=0<<11;
  SPI1->DR=0x0800|table[n0];
  while((SPI1->SR&1<<1)==0)
  {}
  delay_ms(0.01);
  GPIOC->ODR|=1<<11;
  delay_ms(0.1);      
}
///////////////////////////////////////////
int main(void)
{       
    RCC_Configuration();
        delay_init(72);      //延时初始化
        Stm32_Clock_Init(9);
    ADC1_Init();
        DMA_Config();
        filter();
        SPI1_Init();
    max7219_init();
//        ADC1->CR2|=1<<22;
//        DMA1_Channel1->CCR|=1<<0;
    while(1)
        {
          ADC1->CR2|=1<<22;
          DMA1_Channel1->CCR|=1<<0;
          filter();
          SPI1_Init();
          max7219_init();
          display1();
          delay_ms(100);
          display2();
          delay_ms(100);
        }
}









没耐心看完,不过我说,首先看有没有电路上的问题,在看程序自己仔细分析一下。我做过51的AD电压采集就,反正没拿到板子自己调都说不好

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top