OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2956|回复: 2

想用F429DAC做一个10KHz正弦信号,参考了其他人的代码,编译没问题,自我感觉逻辑也对(新手),但是没有波形,麻烦大神帮忙....

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2020-4-9
在线时间
7 小时
发表于 2020-5-18 21:31:44 | 显示全部楼层 |阅读模式
10金钱
#include "dac.h"
#include "led.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//DAC驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//在正点原子原来的DAC实验上改成输出10KHz正弦波
//////////////////////////////////////////////////////////////////////////////////        

DAC_HandleTypeDef DAC1_Handler;//DAC句柄
TIM_HandleTypeDef TIM2_Handler;      //定时器句柄
DMA_HandleTypeDef  DAC1TxDMA_Handler;      //DMA句柄


///********生成正弦波形输出表***********/
//void SineWave_Data( u16 cycle ,u16 *D)
//{
//        u16 i;
//        for( i=0;i<cycle;i++)
//        {
//                D=(u16)((Um*sin(( 1.0*i/(cycle-1))*2*PI)+Um)*4095/3.3);
//        }
//}

//初始化DAC
void DAC1_Init(void)
{
    DAC_ChannelConfTypeDef DACCH1_Config;

    DAC1_Handler.Instance=DAC;
    HAL_DAC_Init(&DAC1_Handler);                 //初始化DAC

    DACCH1_Config.DAC_Trigger=DAC_TRIGGER_T2_TRGO;             //定时器2触发功能
    DACCH1_Config.DAC_OutputBuffer=DAC_OUTPUTBUFFER_DISABLE;//DAC1输出缓冲关闭
    HAL_DAC_ConfigChannel(&DAC1_Handler,&DACCH1_Config,DAC_CHANNEL_1);//DAC通道1配置

    HAL_DAC_Start(&DAC1_Handler,DAC_CHANNEL_1);  //开启DAC通道1
       
}

//DAC底层驱动,时钟配置,引脚 配置
//此函数会被HAL_DAC_Init()调用
//hdacAC句柄
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
{      
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_DAC_CLK_ENABLE();             //使能DAC时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                        //开启GPIOA时钟
       
    GPIO_Initure.Pin=GPIO_PIN_4;            //PA4
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟输出
        GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;        //高速输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}

//通用定时器2中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器2!(定时器3挂在APB1上,时钟为HCLK/2)
void TIM2_Init(u16 arr,u16 psc)
{  
    TIM2_Handler.Instance=TIM2;                          //通用定时器2
    TIM2_Handler.Init.Prescaler=psc;                     //分频系数
    TIM2_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
    TIM2_Handler.Init.Period=arr;                        //自动装载值
    TIM2_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子
    HAL_TIM_Base_Init(&TIM2_Handler);

    HAL_TIM_Base_Start_IT(&TIM2_Handler); //使能定时器2和定时器2更新中断:TIM_IT_UPDATE   
         //__HAL_TIM_URS_ENABLE(&TIM2_Handler);        //这行代码不懂
}

//定时器底册驱动,开启时钟,设置中断优先级
//此函数会被HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM2)
        {
                __HAL_RCC_TIM2_CLK_ENABLE();            //使能TIM2时钟
                HAL_NVIC_SetPriority(TIM2_IRQn,1,3);    //设置中断优先级,抢占优先级1,子优先级3
                HAL_NVIC_EnableIRQ(TIM2_IRQn);          //开启ITM2中断   
        }  
}

//定时器3中断服务函数
void TIM2_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&TIM2_Handler);
}

//定时器3中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim==(&TIM2_Handler))
    {
        LED1=!LED1;        //LED1反转
    }
}

//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chxMA通道选择,@Ref DMA_channel DMA_CHANNEL_0~DMA_CHANNEL_7
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx)
{
        if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
        __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能       
        }else
        {
        __HAL_RCC_DMA1_CLK_ENABLE();//DMA1时钟使能
        }

    __HAL_LINKDMA(&DAC1_Handler,DMA_Handle1,DAC1TxDMA_Handler);    //将DMA与DAC联系起来(发送DMA)

    //Tx DMA配置
    DAC1TxDMA_Handler.Instance=DMA_Streamx;                            //数据流选择
    DAC1TxDMA_Handler.Init.Channel=chx;                                //通道选择
    DAC1TxDMA_Handler.Init.Direction=DMA_MEMORY_TO_PERIPH;             //存储器到外设
    DAC1TxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
    DAC1TxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
    DAC1TxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据长度:8位
        DAC1TxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;       //存储器数据长度:8位
    DAC1TxDMA_Handler.Init.Mode=DMA_CIRCULAR;                            //外设流控模式
        DAC1TxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
    DAC1TxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    DAC1TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
    DAC1TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
    DAC1TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输

    HAL_DMA_DeInit(&DAC1TxDMA_Handler);   
    HAL_DMA_Init(&DAC1TxDMA_Handler);
}


//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void DAC1_Set_Vol(u16 vol)
{
        double temp=vol;
        temp/=1000;
        temp=temp*4096/3.3;
    HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,temp);//12位右对齐数据格式设置DAC值
}

#include "sys.h"
#include "math.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "sdram.h"
#include "usmart.h"
#include "adc.h"
#include "dac.h"
/************************************************
ALIENTEK 阿波罗STM32F429开发板实验21
DAC实验-HAL库函数版
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com  
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/

#define DAC_SIN_SIZE    100         //发送数据长度,最好等于sizeof(TEXT_TO_SEND)+2的整数倍.

u32 DAC_SIN_BUF[DAC_SIN_SIZE];  //发送数据缓冲区

#define PI 3.1415962

extern DAC_HandleTypeDef DAC1_Handler;            //DAC句柄
extern DMA_HandleTypeDef DAC1TxDMA_Handler;      //DMA句柄
extern TIM_HandleTypeDef TIM2_Handler;            //TIM句柄

//产生正弦波函序列,根据DAC_SIN_SIZE生成。
void dac_creat_sin_buf(void)
{
    u8 i;
    float inc=2*PI/DAC_SIN_SIZE;        //计算增量(一个周期DAC_SIN_BUF个点)
    float outdata=0;
    for(i=0;i<DAC_SIN_SIZE;i++)
    {
        outdata=(u32)(2047*(1+sin(inc*i)));    //计算以dots个点为周期的每个点的值,放大2048倍,并偏移到正数区域。
        printf("%f\r\n",outdata);
        DAC_SIN_BUF=outdata;
    }  
}



int main(void)
{
    //u16 adcx;
        //float temp;
        u8 i=0;         
        //u16 dacval=0;
        //u8 key;       
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    uart_init(115200);              //初始化USART
    usmart_dev.init(90);                     //初始化USMART       
    LED_Init();                     //初始化LED
    KEY_Init();                     //初始化按键
    SDRAM_Init();                   //初始化SDRAM
    LCD_Init();                     //初始化LCD
    MY_ADC_Init();                  //初始化ADC1
    DAC1_Init();                    //初始化DAC1
        TIM2_Init(1000-1,9000-1);       //定时器2初始化,定时器时钟为90M,分频系数为9000-1,
                                    //所以定时器2的频率为90M/9000=10K,自动重装载为5000-1,那么定时器周期就是500ms
                                                                        //溢出时间*数据个数=正弦波频率。 溢出时间=(arr+1)*(psc+1)/定时器时钟
       
        dac_creat_sin_buf();                        //生成正弦信号数据
       
        MYDMA_Config(DMA1_Stream5,DMA_CHANNEL_7);//初始化DMA

        POINT_COLOR=RED;
        LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");       
        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,"2016/1/24");         
        LCD_ShowString(30,130,200,16,16,"WK_UP:+  KEY1:-");         
        POINT_COLOR=BLUE;//设置字体为蓝色               
        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");        

    HAL_DAC_Start_DMA(&DAC1_Handler,DAC_CHANNEL_1, DAC_SIN_BUF, DAC_SIN_SIZE, DAC_ALIGN_12B_R);
    while(1)
        {
               

                i++;
                delay_ms(10);
                if(i==20)
                {
                        LED0=!LED0;                 //LED0翻转提示系统正在运行       
                        i=0;
                }                  
               
        }
}





实验21 DAC实验_正弦信号.zip

17.07 MB, 下载次数: 2

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2020-4-9
在线时间
7 小时
 楼主| 发表于 2020-5-18 21:42:10 | 显示全部楼层
基本上是参照论坛里有个767的代码改的,目前没找到链接了
回复

使用道具 举报

0

主题

62

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2020-5-3
在线时间
0 小时
发表于 2020-5-18 21:42:17 | 显示全部楼层
路过留痕,帮顶。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-2 20:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表