OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/FPGA开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 141|回复: 0
打印 上一主题 下一主题

分享:767+ADC+DMA和四路ADC

[复制链接]

53

主题

1217

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
2807
金钱
2807
注册时间
2018-6-30
在线时间
531 小时
跳转到指定楼层
楼主
发表于 2019-6-13 20:07:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 1208 于 2019-6-22 17:01 编辑

本程序可以串口显示和屏幕显示四路
1)dma.c
DMA传输采用的是从外设到内存,
内存:ADC_ConvertedValueRead
外设:ADC>DR寄存器
在HAL_ADC_Start_DMA(&ADC1_Handler,&ADC_ConvertedValue[0],4);有对应的ADC>DR寄存器
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
DMA 数据流 x 外设地址寄存器 (DMA_SxPAR)  
[mw_shl_code=c,true]extern uint32_t ADC_ConvertedValueRead[4];
//DMA_HandleTypeDef  UART1TxDMA_Handler;      //DMA句柄
DMA_HandleTypeDef  ADC1TxDMA_Handler;      //DMA句柄
//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chxMA通道选择,@ref DMA_channel DMA_CHANNEL_0~DMA_CHANNEL_7
void DMA_Config(void)
{

    __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能        
        
    //Tx DMA配置
    ADC1TxDMA_Handler.Instance=DMA2_Stream0;                            //数据流选择
    ADC1TxDMA_Handler.Init.Channel=DMA_CHANNEL_0;                       //通道选择
    ADC1TxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器
    ADC1TxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
    ADC1TxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
    ADC1TxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据长度:32位
    ADC1TxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;       //存储器数据长度:32位
    ADC1TxDMA_Handler.Init.Mode=DMA_CIRCULAR;                            //外设流控模式
    ADC1TxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
    ADC1TxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    ADC1TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
    ADC1TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
    ADC1TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输
    ADC1TxDMA_Handler.XferCpltCallback = HAL_DMA_IRQHandler;
        
    HAL_DMA_DeInit(&ADC1TxDMA_Handler);   
    HAL_DMA_Init(&ADC1TxDMA_Handler);
        HAL_ADC_Start_DMA(&ADC1_Handler,&ADC_ConvertedValueRead[0],4);
        __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1TxDMA_Handler);    //将ADC与DMA联系起来(发送DMA)
        HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,0,0);
        HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
//        HAL_ADC_Stop_DMA(&ADC1_Handler);      //传输完成以后关闭串口DMA

}
void DMA2_Stream0_IRQHandler(void)
{

        HAL_DMA_IRQHandler(&ADC1TxDMA_Handler);

        
}[/mw_shl_code]
2)adc.c
STM32767在使用时一定要注意Cache的问题
[mw_shl_code=c,true]uint32_t ADC_ConvertedValueRead[4];
uint32_t ADC_ConvertedValue[4];

ADC_HandleTypeDef ADC1_Handler;//ADC句柄
//DMA_HandleTypeDef  ADC1TxDMA_Handler;      //DMA句柄


//ADC底层驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//hadc:ADC句柄
//初始化ADC
void MY_ADC_Init(void)
{
//ADC1引脚配置
    GPIO_InitTypeDef GPIO_Initure;
        ADC_ChannelConfTypeDef ADC1_ChanConf;
    __HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                        //开启GPIOA时钟
        __HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
        
    GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_6;            //PA5
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
        
        GPIO_Initure.Pin=GPIO_PIN_4; //|GPIO_PIN_5;
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
//ADC1功能配置        
        ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;   //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    ADC1_Handler.Init.ScanConvMode=ENABLE;                      //扫描模式
    ADC1_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    ADC1_Handler.Init.ContinuousConvMode=ENABLE;                //关闭连续转换
    ADC1_Handler.Init.NbrOfConversion=4;                         //4个转换在规则序列中 也就是只转换规则序列1
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    ADC1_Handler.Init.DMAContinuousRequests=ENABLE;             //开启DMA请求
        ADC1_Handler.DMA_Handle=&ADC1TxDMA_Handler;
    HAL_ADC_Init(&ADC1_Handler);
//采样通道、顺序配置
    ADC1_ChanConf.Channel=ADC_CHANNEL_7;                                   //通道
    ADC1_ChanConf.Rank=1;                                       //1个序列
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
        
        ADC1_ChanConf.Channel=ADC_CHANNEL_14;                                   //通道
    ADC1_ChanConf.Rank=2;                                       //1个序列
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
        
        ADC1_ChanConf.Channel=ADC_CHANNEL_6;                                   //通道
    ADC1_ChanConf.Rank=3;                                       //1个序列
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
        
        ADC1_ChanConf.Channel=ADC_CHANNEL_5;                                   //通道
    ADC1_ChanConf.Rank=4;                                       //1个序列
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
        
}


/** * 函数功能: ADC转换完成回调函数
* 输入参数: hadc:ADC外设设备句柄
* 返 回 值: 无 * 说 明: 读取ADC转化结果时,一定要关闭Cache,
否则数组中的数据为空,即关闭Cache后读取数据,读完在打开。
此函数在 void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) 中调用 */

void  HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
         uint32_t i;
         SCB_DisableDCache();
         for(i=0;i<4;i++)
         {
                 ADC_ConvertedValue = ADC_ConvertedValueRead;
         }
          SCB_EnableDCache();        
}[/mw_shl_code]
3)main.c
[mw_shl_code=c,true]#define N 4

extern uint32_t ADC_ConvertedValue[4];
extern u16  value[N];
int main(void)
{
    u16 adcx;
        float temp[6];
        int i,k,j;
    Cache_Enable();                 //打开L1-Cache
    HAL_Init();                                        //初始化HAL库
    Stm32_Clock_Init(432,25,2,9);   //设置时钟,216Mhz
    delay_init(216);                //延时初始化
        uart_init(115200);                        //串口初始化
    LED_Init();                     //初始化LED
    KEY_Init();                     //初始化按键
    SDRAM_Init();                   //初始化SDRAM
    LCD_Init();                     //LCD初始化
    MY_ADC_Init();                  //初始化ADC1通道5
    DMA_Config();
        //Time_Config();
        POINT_COLOR=RED;
        LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");        
        LCD_ShowString(30,70,200,16,16,"ADC TEST");        
        LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,110,200,16,16,"2016/7/12");         
        POINT_COLOR=BLUE;//设置字体为蓝色
        LCD_ShowString(30,130,200,16,16,"ADC1_PA7_VAL:");
        LCD_ShowString(30,150,200,16,16,"ADC1_PC4_VAL:");
        LCD_ShowString(30,170,200,16,16,"ADC1_PA6_VAL:");
        LCD_ShowString(30,190,200,16,16,"ADC1_PA5_VAL:");
        LCD_ShowString(30,210,200,16,16,"ADC1_PA7_VOL:0.000V");        //先在固定位置显示小数点
        LCD_ShowString(30,230,200,16,16,"ADC1_PC4_VOL:0.000V");        //先在固定位置显示小数点
        LCD_ShowString(30,250,200,16,16,"ADC1_PA6_VOL:0.000V");        //先在固定位置显示小数点
        LCD_ShowString(30,270,200,16,16,"ADC1_PA5_VOL:0.000V");        //先在固定位置显示小数点
        while(1)
        {                        
               
            for(j=0;j<4;j++)
                        {
                                value[j] = (u16)(ADC_ConvertedValue[j]);
                                LCD_ShowxNum(134,130+20*j,value[j],4,16,0); //显示ADCC采样后的原始值
                        }
                  
                        for(k=0; k<4; k++)
                        {
                                temp[k]=(float)value[k]*(3.3/4096);          //获取计算后的带小数的实际电压值,比如3.1111
                                adcx=temp[k];                            //赋值整数部分给adcx变量,因为adcx为u16整形
                                LCD_ShowxNum(134,210+20*k,adcx,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
                                temp[k]-=adcx;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
                                temp[k]*=1000;                           //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
                                LCD_ShowxNum(150,210+20*k,temp[k],3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
                                printf("\r\n 编号%d \t 编号%d \t AD值: %d\r\n", k,i, value[k]);
                        }
            delay_ms(500);
//                        HAL_ADC_Stop_DMA(&ADC1_Handler);      //传输完成以后关闭串口DMA
        }

}[/mw_shl_code]

阿波罗F767:板子四路ADC+除法运算2.zip

17.33 MB, 下载次数: 0

阿波罗F767:板子四路ADC+DMA.zip

18.38 MB, 下载次数: 9

阿波罗F767:板子四路ADC1.zip

17.82 MB, 下载次数: 0

业精于勤,荒于嬉;行成于思,毁于随!
回复

使用道具 举报

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

本版积分规则



关闭

正点原子STM32/FPGA资料免费下载上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2019-6-29 14:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
三级片电影