初级会员

- 积分
- 55
- 金钱
- 55
- 注册时间
- 2017-10-1
- 在线时间
- 39 小时
|

楼主 |
发表于 2017-10-5 13:54:08
|
显示全部楼层
程序如下
DMA部分的初始化
#include "dma.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//DMA 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_Streamx MA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx MA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//par:外设地址
//mar:存储器地址
//ndtr:数据传输量
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
}else
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
}
DMA_DeInit(DMA_Streamx);
while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = chx; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据长度:32位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//存储器数据长度:32位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//最高优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC , ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitStructure);
}
ADC的初始化
#include "adc.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//ADC 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//初始化ADC
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟
//先初始化GPIO口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_4;//ADC1的PA0和ADC2的PA4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE); //ADC2复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE); //复位结束
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;//双重ADC规则同时模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;//两个采样阶段之间的延迟5个时钟
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2; //DMA2模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T4_CC4;//触发源TIM4CH4
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;//上升沿触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//从adc关闭触发
ADC_Init(ADC2, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);//开启AD转换器
ADC_Cmd(ADC2, ENABLE);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_480Cycles);
ADC_DMACmd(ADC1, ENABLE);
}
PWM初始化
void TIM4_PWM_Init(void)
{
//此部分需手动修改IO口设置
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //TIM4时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能GPIOB时钟
GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_TIM4); //GPIOB9复用为定时器4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOB9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB9
TIM_TimeBaseStructure.TIM_Prescaler=8399; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=499; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//初始化定时器4
//初始化TIM4 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR1上的预装载寄存器
TIM_CtrlPWMOutputs(TIM4, ENABLE);//高级定时器要开启MOE位
TIM_SetCompare1(TIM4, 100);
TIM_ARRPreloadConfig(TIM4,ENABLE);//ARPE使能
TIM_Cmd(TIM4, ENABLE); //使能TIM14
}
主程序
#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "adc.h"
#include "dma.h"
#include "lcd.h"
#include "led.h"
#include "pwm.h"
//ALIENTEK 探索者STM32F407开发板 实验0
//STM32F4工程模板-库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK
/*定义32位数组储存ADC1和ADC2的电压*/
void DMA2_Stream0_IRQHandler()
{
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)==1)
{
TIM_Cmd(TIM4, DISABLE);
}
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TC);
}
u32 Voltage[20];
u8 time=0;
u32 voltage1,voltage2;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
Adc_Init();
LCD_Init();
TIM4_PWM_Init();
MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC->CDR,(u32)Voltage,20);
LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V"); //先在固定位置显示小数点
DMA_Cmd(DMA2_Stream0, ENABLE);
TIM_Cmd(TIM4, ENABLE);
delay_ms(50);
voltage2=(ADC->CDR)&0xFFFF0000;
printf("\r\n voltage1 value = %fV\r\n",(float)voltage2);
LCD_ShowxNum(134,130,voltage2,4,16,0);
delay_ms(1000);
for(time=0;time<20;time++)
{
voltage1=Voltage[time]&0x0000FFFF;
voltage1=(float)(voltage1*3.3/4096);
voltage2=(Voltage[time]&0xFFFF0000)>>16;
voltage2=(float)(voltage2*3.3/4096);
printf("\r\n voltage1 value = %fV\r\n",(float)voltage1);
printf("\r\n voltage2 value = %fV\r\n",(float)voltage2);
}
} |
|