OpenEdv-开源电子网

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

江湖救急啊~~~原子哥帮我看下这段程序吧,肿么把ADC的数值转换得到呀?下个礼拜要交差的@_@

[复制链接]

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
发表于 2011-7-25 00:14:05 | 显示全部楼层 |阅读模式

芯片用的是STMffice:smarttags" />32F103VBT6,上面有12ADC输入,我只需用2路就可以了,把转换得到值换算成PWM的占空比输出即可,可是这个ADC+DMA就是不会用啊!!!泪奔了,看了一个下午,也没整出来,人家说直接调用DMA就可以了,怎么调用呀?下面是部分代码,不能都全复制上来,放不下。。。fficeffice" />

麻烦原子哥看一下,就是主函数里面怎么写代码,直接调用他写好的函数就好,把ADC的的转换值从DMA里面读出来,救救小弟吧~~~~~~

#include "stm32f10x_lib.h"

#include "stdio.h"

 

// 用于定义ITM Viewer相关的ITM激励寄存器端口

#define ITM_Port8(n)        (*((vu8 *)(0xE0000000 + 4 * n)))

#define ITM_Port16(n)        (*((vu16 *)(0xE0000000 + 4 * n)))

#define ITM_Port32(n)       (*((vu32 *)(0xE0000000 + 4 * n)))

 

#define DEMCR              (*((vu32 *)(0xE000EDFC)))

#define TRCENA             0x01000000

 

 

#define LTC1446_CLK_H                    GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET)

#define LTC1446_CLK_L                    GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_RESET)

#define LTC1446_CS_H                     GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET)

#define LTC1446_CS_L                      GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_RESET)

#define LTC1446_DIN_H                   GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_SET)

#define LTC1446_DIN_L                   GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_RESET)

          

 

//用于定义是否使用ITM Viewer

//#define DBG_ITM  

 

// Private typedef

// Private define

#define ADC1_DR_Address    ((u32)0x4001244C)

 

//#define RTCClockSource_LSI   // Use the internal 32 KHz oscillator as RTC clock source

#define RTCClockSource_LSE   // Use the external 32.768 KHz oscillator as RTC clock source

 

//#define RTCClockOutput_Enable  // RTC Clock/64 is output on tamper pin(PC.13)

 

// Private macro

// Private variables

ADC_InitTypeDef                          ADC_InitStructure;

DMA_InitTypeDef                         DMA_InitStructure;

TIM_TimeBaseInitTypeDef        TIM_TimeBaseStructure;

TIM_OCInitTypeDef                   TIM_OCInitStructure;

SPI_InitTypeDef                  SPI_InitStructure;

 

vu16                            vu16_DacBuffer[8];          //    8DAC输出缓存(12)

static vu32 vu32_TimingDelay;

 

vu16                            vu16_Adc1ConvertedValue[16];                    //    16 ADC缓存 

 

vu8                             vu8_RxReadPoint = 0;

vu8                             vu8_RxWritePoint = 0;

vu8                             vu8_RxBuffer[256];

 

 

u16                             CCR1_Val = 999;

u16                             CCR2_Val;

 

u16                             adcx;

float                          temp;

 

ErrorStatus       HSEStartUpStatus;

 

// Private function prototypes

void RCC_Configuration(void);

void GPIO_Configuration(void);

void NVIC_Configuration(void);

void RTC_Configuration(void);

void USART_Configuration1(void);

void TIM_Configuration(void);

void DMA_Configuration(void);

void ADC1_Configuration(void);

int fputc(int ch, FILE *f); 

 

void DACs_Update(void);

 

void GPIOs_Test(void);

 

void Delay_ms(u32 nTime);

void TimingDelay_Decrement(void);

 

void Delay(vu32 nCount);

 

//-------------------------------------------------------------------------------------

// Function Name  : main

// Description    : Main program

// Input          : None

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

int main(void)

{

#ifdef DEBUG

      debug();

#endif

 

       u8          i;

 

       //----------------------------------

       //    以下初始化调试用

       vu16_DacBuffer[0] = 800;

       vu16_DacBuffer[1] = 1200;

       vu16_DacBuffer[2] = 1600;

       vu16_DacBuffer[3] = 2000;

       vu16_DacBuffer[4] = 2400;

       vu16_DacBuffer[5] = 2800;

       vu16_DacBuffer[6] = 3200;

       vu16_DacBuffer[7] = 3600;

 

       //---------------------------------------------------------------

     

 

      

       // System clocks configuration

      RCC_Configuration();

      // NVIC configuration

      NVIC_Configuration();

      // GPIO configuration

      GPIO_Configuration();

 

      //    SysTick end of count event each 1ms with input clock equal to 9MHz (HCLK/8, default)

      SysTick_SetReload(9000);

 

      //    Enable SysTick interrupt

      SysTick_ITConfig(ENABLE);

 

   // Configure the USART1

      USART_Configuration1();

 

      // TIM configuration

      TIM_Configuration();

      // DMA configuration

      DMA_Configuration();

      // ADC1 configuration

      ADC1_Configuration();

 

       //----------------------------------------------------------

       DACs_Update();

     

   //----------------------------------------------------------

       GPIOs_Test();

        

      // TIM IT enable

      TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);             //    TIM2_CC2:中断使能     

      // TIM enable counter

      TIM_Cmd(TIM2, ENABLE);

 

       // Clear reset flags

      RCC_ClearFlag();

 

      

      while(1)

      {

             Delay_ms(250);

              for(i = 0; i < 16; i++)

              {

                     printf("%4d, ", vu16_Adc1ConvertedValue);

             }

              printf("\r\n");

             

              ADC_SoftwareStartConvCmd(ADC1, ENABLE);

 

              temp=(float)vu16_Adc1ConvertedValue[0]*(999/4096);

 

              CCR2_Val = temp;

 

              TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

 

             TIM_OC2Init(TIM3, &TIM_OCInitStructure);

      }

}

 

//-------------------------------------------------------------------------------------

// Function Name  : RCC_Configuration

// Description    : Configures the different system clocks.

// Input          : None

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void RCC_Configuration(void)

{

      // RCC system reset(for debug purpose)

      RCC_DeInit();

 

      // Enable HSE                                (外部晶振启动)

      RCC_HSEConfig(RCC_HSE_ON);

 

      // Wait till HSE is ready (等待外部晶振运行正常)

      HSEStartUpStatus = RCC_WaitForHSEStartUp();

 

      if(HSEStartUpStatus == SUCCESS)

      {

           // HCLK = SYSCLK                  (to AHB bus, core, memory ahd DMA)                 72MHz

           RCC_HCLKConfig(RCC_SYSCLK_Div1);

 

           // PCLK2 = HCLK                    (to APB2 peripherals)                                                 72MHz

           RCC_PCLK2Config(RCC_HCLK_Div1);

 

           // PCLK1 = HCLK/2                  (to APB1 peripherals)                                           36MHz

           RCC_PCLK1Config(RCC_HCLK_Div2);          

 

           // ADCCLK = PCLK2/4             (to ADC)                                                                                    18MHz

           RCC_ADCCLKConfig(RCC_PCLK2_Div4);

 

           // Flash 2 wait state

           FLASH_SetLatency(FLASH_Latency_2);

 

           // Enable Prefetch Buffer

           FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

 

           // PLLCLK = 8MHz * 9 = 72 MHz

           RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

 

           // Enable PLL                           (使能PLL)

           RCC_PLLCmd(ENABLE);          

 

           // Wait till PLL is ready

           while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

           {

           }

 

           // Select PLL as system clock source

           RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

           // Wait till PLL is used as system clock source

           while(RCC_GetSYSCLKSource() != 0x08)

           {

           }

      }

 

       // Enable peripheral clocks

      // Enable DMA clock

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 

      // Enable ADC1 and GPIOA, --, GPIOE clock

      RCC_APB2PeriphClockCmd(     RCC_APB2Periph_ADC1\

                                                                | RCC_APB2Periph_USART1\

                                                            | RCC_APB2Periph_GPIOA\

                                                                | RCC_APB2Periph_GPIOB\

                                                                | RCC_APB2Periph_GPIOC\

                                                                | RCC_APB2Periph_GPIOD\

                                                                | RCC_APB2Periph_GPIOE, ENABLE );

 

       RCC_APB2PeriphClockCmd(             RCC_APB2Periph_AFIO, ENABLE);

 

      // TIM2 and TIM3 and SPI2 Periph and PWR and BKP clock  enable

      RCC_APB1PeriphClockCmd(    RCC_APB1Periph_TIM2\

                                                                |    RCC_APB1Periph_TIM3\

                                                                | RCC_APB1Periph_SPI2\

                                                                | RCC_APB1Periph_PWR\

                                                                | RCC_APB1Periph_BKP, ENABLE);

 

 

}

 

//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------

// Function Name  : DMA_Configuration

// Description    : Configures Vector Table base location.

// Input          : None

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void DMA_Configuration(void)

{   

       // DMA channel1 configuration

       DMA_DeInit(DMA1_Channel1);

      DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

      DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&vu16_Adc1ConvertedValue;

      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

      DMA_InitStructure.DMA_BufferSize = 16;            

      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

      DMA_InitStructure.DMA_Priority = DMA_Priority_High;

      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

      DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 

      // DMA IT enable

//         DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE);

 

      // Enable DMA channel1

      DMA_Cmd(DMA1_Channel1, ENABLE);

}

 

//-------------------------------------------------------------------------------------

// Function Name  : ADC1_Configuration

// Description    : Configures Vector Table base location.

// Input          : None

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void ADC1_Configuration(void)

{

      ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //    ADC1ADC2工作在独立模式 

      ADC_InitStructure.ADC_ScanConvMode = ENABLE;                     //    ENABLE 扫描(多通道)模式;

                                                                                                                              //    DISABLE 单次(单通道)模式;

      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//      ENABLE 连续模式;

                                                                                                                              //    DISABLE 单次模式;

      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;

                                                                                                                              //    ADC_ExternalTrigConv_None;

                                                                                                                              //    ADC_ExternalTrigConv_T2_CC2;

      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //    右对齐

      ADC_InitStructure.ADC_NbrOfChannel = 16;                         //    顺序规则转换的ADC通道数目

      ADC_Init(ADC1, &ADC_InitStructure);

 

      // ADC1 regular channel0 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel1 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel2 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel3 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel4 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel5 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel6 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel7 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel8 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel9 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel10 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 11, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel11 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 12, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel12 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 13, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel13 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 14, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel14 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 15, ADC_SampleTime_55Cycles5);

      // ADC1 regular channel15 configuration

      ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 16, ADC_SampleTime_55Cycles5);

 

       //    使能温度传感器和内部参考电压通道

       ADC_TempSensorVrefintCmd(ENABLE);

 

      // Enable ADC1 DMA

      ADC_DMACmd(ADC1, ENABLE);

 

      // Enable ADC1 external trigger

      ADC_ExternalTrigConvCmd(ADC1, ENABLE);

 

      // Enable ADC1

      ADC_Cmd(ADC1, ENABLE);

 

      // Enable ADC1 reset calibaration register  

      ADC_ResetCalibration(ADC1);

      // Check the end of ADC1 reset calibration register

      while(ADC_GetResetCalibrationStatus(ADC1));

      // Start ADC1 calibaration

      ADC_StartCalibration(ADC1);

      // Check the end of ADC1 calibration

      while(ADC_GetCalibrationStatus(ADC1));

}

 

#ifdef  DEBUG

//-------------------------------------------------------------------------------------

// Function Name  : assert_failed

// Description    : Reports the name of the source file and the source line number

//                  where the assert error has occurred.

// Input          : - file: pointer to the source file name

//                  - line: assert error line source number

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void assert_failed(u8* file, u32 line)

{

      // User can add his own implementation to report the file name and line number,

   //    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line)

 

      // Infinite loop

      while(1)

      {

      }

}

#endif

 

//-------------------------------------------------------------------------------------

// Function Name  : fputc

// Description    : Retargets the C library printf function to the USART or ITM Viewer.

// Input          : None

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

int fputc(int ch, FILE *f)

{

#ifdef DBG_ITM

       // Printf内容发往ITM激励寄存器端口

      if(DEMCR & TRCENA)

       {

           while(ITM_Port32(0) == 0);

           ITM_Port8(0) = ch;

      }

#else 

       // Printf内容发往串口

      USART_SendData(USART1, (u8)ch);

      while(!(USART1->SR & USART_FLAG_TXE));

#endif 

      return(ch);

}

 

//-------------------------------------------------------------------------------------

// Function Name  : DACs_Update

// Input          : None

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void DACs_Update(void)

{

       u8 ucTmp1, ucTmp2;

       u16  uiTmp1;

 

       LTC1446_CLK_L;

       Delay(2);

       LTC1446_CS_L;

       Delay(2);

 

       for(ucTmp1 = 0; ucTmp1 < 8; ucTmp1++)

       {

              uiTmp1 = vu16_DacBuffer[ucTmp1];

 

              for(ucTmp2 = 0; ucTmp2 < 12; ucTmp2++)

              {

                     if(uiTmp1 & 0x0800)

                            LTC1446_DIN_H;

                     else

                            LTC1446_DIN_L;

 

                     uiTmp1 <<= 1;

                     Delay(2);

                     LTC1446_CLK_H;

                     Delay(2);

                     LTC1446_CLK_L;

                     Delay(2);

              }

       }

 

       LTC1446_CS_H;

}

 

//-------------------------------------------------------------------------------------

// Function Name  : Delay

// Input          : nCount

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void Delay(vu32 nCount)

{

       for(; nCount != 0; nCount--);

}

 

//-------------------------------------------------------------------------------------

// Function Name  : Delay_ms

// Input          : nTime,  (us)

// Output         : None

// Return         : None

//-------------------------------------------------------------------------------------

void Delay_ms(u32 nTime)

{

       //    允许SysTick计数器

       SysTick_CounterCmd(SysTick_Counter_Enable);

 

       vu32_TimingDelay = nTime;

 

       while(vu32_TimingDelay != 0);

 

       //    禁止SysTick计数器

       SysTick_CounterCmd(SysTick_Counter_Disable);

 

       //    SysTick计数器清零

       SysTick_CounterCmd(SysTick_Counter_Clear);

}

 

//-------------------------------------------------------------------------------------

// Function Name  : TimingDelay_Decrement

// Description    : Decrements the TimingDelay variable.

// Input          : None

// Output         : TimingDelay

// Return         : None

//-------------------------------------------------------------------------------------

void TimingDelay_Decrement(void)

{

      if (vu32_TimingDelay != 0x00)

      {

           vu32_TimingDelay--;

      }

}

 

//=====================================================================================

//                                              END OF FILE

//=====================================================================================

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-7-25 00:55:55 | 显示全部楼层
才一个下午...
一个星期也不长啊.

DMA+ADC,是可以的.你一堆的库,和我的代码差的比较多啊.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
 楼主| 发表于 2011-7-25 16:42:02 | 显示全部楼层
原子哥,我搞出来了,但现在有个问题我吃不太准,想请教一下,这是我用万用表测的输入输出的电压值,以及输出/输入的比值,这个误差正常么?算线性么?
in    out    比例
0.029 0.340  11.724
0.057 0.635  11.140
0.084 0.914  10.881
0.114 1.235  10.833
0.166 1.785  10.753
以上数据是这样得到的,因为板子上的adc输入是先经过运放的,所以输入电压很小,输入电压作为模拟信号输入以后,通过adc转换得到数值x1,然后用x1除以4096,再乘以占空比的最大值(999),得到x2,把x2做为PWM的占空比输出得到输出电压。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-7-25 16:52:09 | 显示全部楼层
不太明白.
你的东西是不是   电压->运放->adc-stm32处理->pwm->lpf->电压
??是不是个这样的东东啊?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
 楼主| 发表于 2011-7-26 21:55:55 | 显示全部楼层
对的,是线性的,已经搞明白了~`
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 18:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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