新手入门
- 积分
- 14
- 金钱
- 14
- 注册时间
- 2020-4-9
- 在线时间
- 7 小时
|
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()调用
//hdac AC句柄
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_Streamx MA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx MA通道选择,@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;
}
}
}
|
|