我想用DAC输出正弦波,遇到好多问题............

2019-07-21 02:12发布

1  DAC用通道一(应该就是DAC1了吧),明明是输出,为什么PA4口要设置为模拟输入模式?  另外这个模拟输入模式是什么意思啊?
2  DAC要输出正弦波,频率要用tim加dma实现吗? tim是怎么联系dac在dma的输出的啊?
3  DMA里8个通道,8个数据流,这通道是指GPIO口吗?数据流又是怎么回事?
4 若我用DAC 输出电压,是不是把PA4口连到示波器上就可以观察到了?ADC转化是不是连到PA5上就能读出电压了?DAC能不能也读电压?ADC能不能也输出电压? 
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
龙行
2019-07-21 22:47
[mw_shl_code=c,true]#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "lcd.h" #include "adc.h" #include "dac.h" #include "key.h" #include "math.h" #define MAXWAVECNT 200 #define WAVECNT 100 //波形的阶数,阶数越大波形拟真度越高,频率会越低 u16 wavedatatab[MAXWAVECNT] = {0}; //存储任意的波形数据 //产生波形数据函数 void GEN_WAVE(float Amp,float offset,u8 wavetype) { u16 tempAmp = Amp*(4096/3.3); u16 tempoffset = offset*(4096/3.3); u8 i; u16 step; switch(wavetype) { case 0: for(i=0 ;i<WAVECNT;i++){ wavedatatab = (u16)( tempAmp*sin(2*3.14*i/WAVECNT)+tempoffset); } break; case 1: step = tempAmp/(WAVECNT/2); for(i=0 ;i<WAVECNT;i++){ if(i<(WAVECNT/2)) wavedatatab= i*step+tempoffset; else wavedatatab = (WAVECNT-i)*step+tempoffset; } break; case 2: step = tempAmp/WAVECNT; for(i=0 ;i<WAVECNT;i++) wavedatatab= i*step+tempoffset; break; default: break; } } //初始化Tim以便于控制频率 void TIM2_Int_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<0; //TIM2时钟使能 TIM2->ARR=arr; //设定计数器自动重装值 TIM2->SC=psc; //预分频器 TIM2->CR1|=1<<7; //ARPE使能 TIM2->CR2 |=0x2<<4; //TIMER更新做为TRGO源 选择更新事件作为触发输出 TIM2->CR1 |=TIM_CR1_CEN; //使能定时器2 } //DMA初始化 void DAC_DMA_init(void) { RCC->AHB1ENR|=1<<21;//DMA1时钟使能 DMA1_Stream5->AR=(u32)&(DAC->DHR12R1); //DMA外设地址 DMA1_Stream5->M0AR=(u32)wavedatatab; //DMA 存储器0地址 DMA1_Stream5->NDTR=WAVECNT; //DMA 传输数量 DMA1_Stream5->CR=0; //先全部复位CR寄存器值 DMA1_Stream5->CR|=1<<6; //存储器到外设模式 DMA1_Stream5->CR|=1<<8; //循环模式 DMA1_Stream5->CR|=0<<9; //外设非增量模式 DMA1_Stream5->CR|=1<<10; //存储器增量模式 DMA1_Stream5->CR|=1<<11; //外设数据长度:16位 DMA1_Stream5->CR|=1<<13; //存储器数据长度:16位 DMA1_Stream5->CR|=1<<16; //中等优先级 DMA1_Stream5->CR|=0<<21; //外设突发单次传输 DMA1_Stream5->CR|=0<<23; //存储器突发单次传输 DMA1_Stream5->CR|= 0x7<<25;//通道选择 DMA1_Stream5->CR|= 1<< 0;//开DMA } //DAC初始化 void Dac1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure1; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟 //RCC->APB1ENR|=1<<29; //使能DAC时钟 //RCC->AHB1ENR|=1<<0; //使能PORTA时钟 //GPIO_Set(GPIOA,PIN4,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA4,模拟输入,下拉 GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式 GPIO_InitStructure1.GPIO_OType = GPIO_OType_PP;//推挽输出 GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉 GPIO_Init(GPIOA, &GPIO_InitStructure1);//初始化 DAC->CR|=1<<0; //使能DAC1 DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=1 DAC->CR|=1<<2; //使用触发功能 TEN1=1 DAC->CR|=4<<3; //DAC TIM2 TRGO,不过要TEN1=1才行 DAC->CR|=0<<6; //不使用波形发生 DAC->CR|=0<<8; //屏蔽、幅值设置 DAC->CR|=1<<12; //DAC1 DMA使能 DAC->DHR12R1=0; DAC_DMA_init(); TIM2_Int_Init(100,0); } //设置tim频率 即设置波的频率 void SET_DAC_FRQ(u16 frq) { TIM2->CR1 &=~TIM_CR1_CEN; TIM2->ARR = frq; TIM2->CR1 |=TIM_CR1_CEN; } //输出波形的函数 void DDS_Output_Wave(float Amp,float offset,u8 wavetype,u16 frq) { DMA1_Stream5->CR&= ~(1<< 0);//开DMA GEN_WAVE(Amp,offset,wavetype); SET_DAC_FRQ(frq); DMA1_Stream5->CR|= (1<< 0);//关DMA } int main(void) { u16 adcx; float temp,n; u8 m=0;//t=0; u16 l=1000;//dacval=0, u8 key; //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 //uart_init(115200); //初始化串口波特率为115200 LED_Init(); //初始化LED LCD_Init(); //LCD初始化 Adc_Init(); //adc初始化 KEY_Init(); //按键初始化 Dac1_Init(); //DAC通道1初始化 POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Explorer STM32F4"); LCD_ShowString(30,70,200,16,16,"DAC TEST"); LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(30,110,200,16,16,"2015/8/1"); LCD_ShowString(30,130,200,16,16,"---------"); POINT_COLOR=BLUE;//设置字体为蓝 {MOD} LCD_ShowString(30,150,200,16,16,"DAC VAL:"); LCD_ShowString(30,170,200,16,16,"DAC VOL:0.000V"); LCD_ShowString(30,190,200,16,16,"ADC VOL:0.000V"); //DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0 while(1) { key=KEY_Scan(1); switch(key) { case KEY0_PRES: if(m<=3)m+=1; else m=0; break; case KEY1_PRES: if(n<=3)n+=1; else n=0; break; case KEY2_PRES: if(l<=0xfff)l+=1000; else l=1000; break; default: break; } DDS_Output_Wave(3,0,m,10000); if(key==WKUP_PRES) //WKUP/KEY1按下了,或者定时时间到了 { adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值 LCD_ShowxNum(94,150,adcx,4,16,0); //显示DAC寄存器值 temp=(float)adcx*(3.3/4096); //得到DAC电压值 adcx=temp; LCD_ShowxNum(94,170,temp,1,16,0); //显示电压值整数部分 temp-=adcx; temp*=1000; LCD_ShowxNum(110,170,temp,3,16,0X80); //显示电压值的小数部分 adcx=Get_Adc_Average(ADC_Channel_5,10); //得到ADC转换值 temp=(float)adcx*(3.3/4096); //得到ADC电压值 adcx=temp; LCD_ShowxNum(94,190,temp,1,16,0); //显示电压值整数部分 temp-=adcx; temp*=1000; LCD_ShowxNum(110,190,temp,3,16,0X80); //显示电压值的小数部分 LED0=!LED0; } delay_ms(10); } } [/mw_shl_code] 就是这段代码,怎么看也感觉没错啊,但是PA4就是输不出波形,哎,咋办啊

一周热门 更多>