打印
[STM32F1]

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

[复制链接]
3176|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个吧,然后按大小排序,最掉最大值和最小值,然后再求平均值发送。

使用特权

评论回复
5
309030| | 2016-3-20 20:07 | 只看该作者
建议用DMA

使用特权

评论回复
6
maxingyu|  楼主 | 2016-3-22 17:40 | 只看该作者
xyz549040622 发表于 2016-3-19 18:59
用DMA传输就好了,速度很快的。完全可以达到你实时的效果了。

是说用DMA串口传输吗  我现在是AD采集用的DMA 这两个可以同时用吗

使用特权

评论回复
7
maxingyu|  楼主 | 2016-3-22 17:41 | 只看该作者
orangebanana 发表于 2016-3-20 07:57
开两个缓存,一个发一个收就可以了

一直不理解这个开缓存到底是怎么开 就是开辟一个数组然后存数据吗

使用特权

评论回复
8
mintspring| | 2016-3-22 23:53 | 只看该作者
你可以把转换函数作为发送的参数进行直接传递。
fasong(getac());
类似这种用法。

使用特权

评论回复
9
734774645| | 2016-3-23 10:21 | 只看该作者
#include "ad_driver.h"

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

//函数
//初始化AD
void init_ad(void)
{
        ADC_InitTypeDef ADC_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

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

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

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

        //DMA1通道1配置
        DMA_DeInit(DMA1_Channel1);
        //外设地址
        DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS;
        //内存地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue;
        //dma传输方向单向
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
        //设置DMA在传输时缓冲区的长度
        DMA_InitStructure.DMA_BufferSize = 20;
        //设置DMA的外设递增模式,一个外设
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        //设置DMA的内存递增模式
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        //外设数据字长
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        //内存数据字长
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
        //设置DMA的传输模式:连续不断的循环模式
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        //设置DMA的优先级别
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
        //设置DMA的2个memory中的变量互相访问
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);
       
        //使能通道1
        DMA_Cmd(DMA1_Channel1, ENABLE);

        //ADC1配置
        //独立工作模式
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
        //扫描方式
        ADC_InitStructure.ADC_ScanConvMode = ENABLE;
        //连续转换
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
        //外部触发禁止
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
        //数据右对齐
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
        //用于转换的通道数
        ADC_InitStructure.ADC_NbrOfChannel = 2;
        ADC_Init(ADC1, &ADC_InitStructure);
       
        //规则模式通道配置
        ADC_RegularChannelConfig(ADC1, ADC_Channel_1 , 1, ADC_SampleTime_239Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_2 , 2, ADC_SampleTime_239Cycles5);
       
        //使能ADC1的DMA
        ADC_DMACmd(ADC1, ENABLE);
       
        //使能ADC1
        ADC_Cmd(ADC1, ENABLE);
       
        //使能ADC1复位校准寄存器  
        ADC_ResetCalibration(ADC1);
        //检查校准寄存器是否复位完毕
        while(ADC_GetResetCalibrationStatus(ADC1));
       
        //开始校准
        ADC_StartCalibration(ADC1);
        //检测是否校准完毕
        while(ADC_GetCalibrationStatus(ADC1));
         
        //开启ADC1的软件转换
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

//获得充电电压
float voltage_charge(void)
{
        uint8_t i = 0;
        uint16_t sum = 0;
        float v = 0;

        //取得10次充电电压平均值
        for (i = 0;i < 10;i++)
        {
                 sum += ADCConvertedValue[i * 2];
        }
        sum /= 10;
        //变换成电压值
        v = 0.002991 * sum;

        return v;
}

//获得放电电压
float voltage_discharge(void)
{
        uint8_t i = 0;
        uint16_t sum = 0;
        float v = 0;

        //取得10次充电电压平均值
        for (i = 0;i < 10;i++)
        {
                 sum += ADCConvertedValue[i * 2 + 1];
        }
        sum /= 10;
        //变换成电压值
        v = 0.002991 * sum;

        return v;
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

121

帖子

1

粉丝