[STM32F1] STM32F103 使用AD采集后串口送出,怎么才能做到实时的采集和传输呢,需要开辟缓存吗

[复制链接]
3531|8
 楼主| maxingyu 发表于 2016-3-19 17:30 | 显示全部楼层 |阅读模式
STM32F103 使用AD采集后串口送出,怎么才能做到实时的采集和传输呢,需要开辟缓存吗
xyz549040622 发表于 2016-3-19 18:59 | 显示全部楼层
用DMA传输就好了,速度很快的。完全可以达到你实时的效果了。
orangebanana 发表于 2016-3-20 07:57 | 显示全部楼层
开两个缓存,一个发一个收就可以了
dongnanxibei 发表于 2016-3-20 13:10 | 显示全部楼层
如果不好用DMA可以开辟一个缓存,用于采集后的位置存储并发送,首先采集后你不能直接发送,你要对数据进行滤波,比如采集10个吧,然后按大小排序,最掉最大值和最小值,然后再求平均值发送。
309030 发表于 2016-3-20 20:07 | 显示全部楼层
建议用DMA
 楼主| maxingyu 发表于 2016-3-22 17:40 | 显示全部楼层
xyz549040622 发表于 2016-3-19 18:59
用DMA传输就好了,速度很快的。完全可以达到你实时的效果了。

是说用DMA串口传输吗  我现在是AD采集用的DMA 这两个可以同时用吗
 楼主| maxingyu 发表于 2016-3-22 17:41 | 显示全部楼层
orangebanana 发表于 2016-3-20 07:57
开两个缓存,一个发一个收就可以了

一直不理解这个开缓存到底是怎么开 就是开辟一个数组然后存数据吗
mintspring 发表于 2016-3-22 23:53 | 显示全部楼层
你可以把转换函数作为发送的参数进行直接传递。
fasong(getac());
类似这种用法。
734774645 发表于 2016-3-23 10:21 | 显示全部楼层
  1. #include "ad_driver.h"

  2. //全局变量
  3. //AD采样存放空间
  4. __IO uint16_t ADCConvertedValue[20];

  5. //函数
  6. //初始化AD
  7. void init_ad(void)
  8. {
  9.         ADC_InitTypeDef ADC_InitStructure;
  10.         DMA_InitTypeDef DMA_InitStructure;
  11.         GPIO_InitTypeDef GPIO_InitStructure;

  12.         //---------------------充电AD初始化--------------------
  13.         //启动DMA时钟
  14.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  15.         //启动ADC1时钟
  16.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  17.         //采样脚设置
  18.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  19.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  20.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  21.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  22.         //DMA1通道1配置
  23.         DMA_DeInit(DMA1_Channel1);
  24.         //外设地址
  25.         DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS;
  26.         //内存地址
  27.         DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue;
  28.         //dma传输方向单向
  29.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  30.         //设置DMA在传输时缓冲区的长度
  31.         DMA_InitStructure.DMA_BufferSize = 20;
  32.         //设置DMA的外设递增模式,一个外设
  33.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  34.         //设置DMA的内存递增模式
  35.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  36.         //外设数据字长
  37.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  38.         //内存数据字长
  39.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  40.         //设置DMA的传输模式:连续不断的循环模式
  41.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  42.         //设置DMA的优先级别
  43.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  44.         //设置DMA的2个memory中的变量互相访问
  45.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  46.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  47.        
  48.         //使能通道1
  49.         DMA_Cmd(DMA1_Channel1, ENABLE);

  50.         //ADC1配置
  51.         //独立工作模式
  52.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  53.         //扫描方式
  54.         ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  55.         //连续转换
  56.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  57.         //外部触发禁止
  58.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  59.         //数据右对齐
  60.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  61.         //用于转换的通道数
  62.         ADC_InitStructure.ADC_NbrOfChannel = 2;
  63.         ADC_Init(ADC1, &ADC_InitStructure);
  64.        
  65.         //规则模式通道配置
  66.         ADC_RegularChannelConfig(ADC1, ADC_Channel_1 , 1, ADC_SampleTime_239Cycles5);
  67.         ADC_RegularChannelConfig(ADC1, ADC_Channel_2 , 2, ADC_SampleTime_239Cycles5);
  68.        
  69.         //使能ADC1的DMA
  70.         ADC_DMACmd(ADC1, ENABLE);
  71.        
  72.         //使能ADC1
  73.         ADC_Cmd(ADC1, ENABLE);
  74.        
  75.         //使能ADC1复位校准寄存器  
  76.         ADC_ResetCalibration(ADC1);
  77.         //检查校准寄存器是否复位完毕
  78.         while(ADC_GetResetCalibrationStatus(ADC1));
  79.        
  80.         //开始校准
  81.         ADC_StartCalibration(ADC1);
  82.         //检测是否校准完毕
  83.         while(ADC_GetCalibrationStatus(ADC1));
  84.          
  85.         //开启ADC1的软件转换
  86.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  87. }

  88. //获得充电电压
  89. float voltage_charge(void)
  90. {
  91.         uint8_t i = 0;
  92.         uint16_t sum = 0;
  93.         float v = 0;

  94.         //取得10次充电电压平均值
  95.         for (i = 0;i < 10;i++)
  96.         {
  97.                  sum += ADCConvertedValue[i * 2];
  98.         }
  99.         sum /= 10;
  100.         //变换成电压值
  101.         v = 0.002991 * sum;

  102.         return v;
  103. }

  104. //获得放电电压
  105. float voltage_discharge(void)
  106. {
  107.         uint8_t i = 0;
  108.         uint16_t sum = 0;
  109.         float v = 0;

  110.         //取得10次充电电压平均值
  111.         for (i = 0;i < 10;i++)
  112.         {
  113.                  sum += ADCConvertedValue[i * 2 + 1];
  114.         }
  115.         sum /= 10;
  116.         //变换成电压值
  117.         v = 0.002991 * sum;

  118.         return v;
  119. }


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

本版积分规则

38

主题

121

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部