利用STM32的DAC+TIME产生可调频调幅正弦波

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、如何产生正弦波?
  • 二、生成采样数值函数
    • 1.函数生成DAC数组函数
    • 2.通过高级定时器TIM1更新中断控制DAC输出
  • 三、通过四个按钮控制输出的频率和幅度
  • 四、下面是我的实测波形,附上程序百度网盘
  • 总结


前言

        这个程序非常简单,说白了就是每隔一段时间改变引脚输出的电压,就能得到一个正弦波。

主要是为了方便大家调试FFT,有一个输入大于0小于3.3V取样信号,方便大家学习。

一、如何产生正弦波?

  本文采用查表法的方式生成一个数值范围为[0,4096]的正弦波数组,通过定时器更新中断不断以DAC进行输出,从而产生一个正弦波,并且通过改变定时器的预装载值(ARR)或者预分频系数(psc),改变进入中断的时间进而改变正弦波频率。

二、生成采样数值函数

代码如下:

void out_sine(void) 
{
    double index = 250;//250个数据
    float pi = 3.141592;
    int fori = 0;
    float outv = 0;
    for(;fori <index;fori++)
    {
        outv = 0.5*(sin((2*pi)/index*fori)+1)*4095;
        printf("%.0f,\t",outv);
        if(!((fori+1)%8))
            printf("\r\n");//将数据打印出来
    }    
}

下表是通过串口软件打印出来的数据,有了这个一维数组我们只需要将数组里的值依次赋给DAC就能得到正弦波啦。

const u16 Sine12bit_250[250] = {
2048,	2099,	2150,	2202,	2253,	2304,	2355,	2406,	
2456,	2507,	2557,	2606,	2656,	2705,	2753,	2801,	
2849,	2896,	2942,	2988,	3034,	3079,	3123,	3166,	
3209,	3251,	3292,	3333,	3372,	3411,	3449,	3486,	
3522,	3558,	3592,	3625,	3657,	3689,	3719,	3748,	
3776,	3803,	3829,	3854,	3878,	3900,	3921,	3942,	
3961,	3978,	3995,	4010,	4024,	4037,	4048,	4059,	
4068,	4075,	4082,	4087,	4091,	4094,	4095,	4095,	
4094,	4091,	4087,	4082,	4075,	4068,	4059,	4048,	
4037,	4024,	4010,	3995,	3978,	3961,	3942,	3921,	
3900,	3878,	3854,	3829,	3803,	3776,	3748,	3719,	
3689,	3657,	3625,	3592,	3558,	3522,	3486,	3449,	
3411,	3372,	3333,	3292,	3251,	3209,	3166,	3123,	
3079,	3034,	2988,	2942,	2896,	2849,	2801,	2753,	
2705,	2656,	2606,	2557,	2507,	2456,	2406,	2355,	
2304,	2253,	2202,	2150,	2099,	2048,	1996,	1945,	
1893,	1842,	1791,	1740,	1689,	1639,	1588,	1538,	
1489,	1439,	1390,	1342,	1294,	1246,	1199,	1153,	
1107,	1061,	1016,	972,	929,	886,	844,	803,	
762,	723,	684,	646,	609,	573,	537,	503,	
470,	438,	406,	376,	347,	319,	292,	266,	
241,	217,	195,   	174,	153,	134,	117,	100,	
85,	    71,	    58,	    47,	    36,	    27,	    20,	    13,	
8,	    4,	    1,	    0,	    0,	    1,	    4,	    8,	
13,	    20,	    27,	    36,	    47,	    58,	    71,	    85,	
100,	117,	134,	153,	174,	195,	217,	241,	
266,	292,	319,	347,	376,	406,	438,	470,	
503,	537,	573,	609,	646,	684,	723,	762,	
803,	844,	886,	929,	972,	1016,	1061,	1107,	
1153,	1199,	1246,	1294,	1342,	1390,	1439,	1489,	
1538,	1588,	1639,	1689,	1740,	1791,	1842,	1893,	
1945,	1996,

};

2.通过高级定时器TIM1更新中断控制DAC输出

代码如下:

#define CLIP_ROT(V,MIN,MAX) ( ( V>MAX?MIN:(V<MIN?MAX:V) ) )  
void AdcPushData()
{
	static int DAC_index_1 = 0;
	DAC_SetChannel1Data(DAC_Align_12b_R,(Sine12bit_250[DAC_index_1])*DacAmp/10);//250个点        
                                                                              4Khz(0.4ms)
	DAC_index_1++;
	DAC_index_1 = CLIP_ROT(DAC_index_1,0,250);
}
  
void Timer1_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrecture;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);/*使能定时器1的时钟*/


	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;/*定时器1的中断通道使能*/
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/*定时器1的中断通道使能*/
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/*抢占优先级*/
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;/*响应优先级*/
	NVIC_Init(&NVIC_InitStructure);/*配置中断分组,并使能中断*/

	TIM_TimeBaseInitStrecture.TIM_Period = arr;/*重装载寄存器*/
	TIM_TimeBaseInitStrecture.TIM_Prescaler = psc;/*预分配*/
	TIM_TimeBaseInitStrecture.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频*/
	TIM_TimeBaseInitStrecture.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数*/
	TIM_TimeBaseInitStrecture.TIM_RepetitionCounter = 0;/*重复计数寄存器*/
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStrecture);/*初始化*/

	TIM_ClearFlag(TIM1,TIM_FLAG_Update);/*清更新标志位*/
	TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);/*使能中断*/
	TIM_Cmd(TIM1,ENABLE);/*使能计数*/

}



void TIM1_UP_TIM10_IRQHandler(void)
{

    if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET){//判断TIM中断发生与否:TIM 中断源 
		TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除中断标志位,否则卡死在中断里 
/***************在此处添加中断执行内容******************/
	AdcPushData();
	LED1 = ~LED1;
    }
}

中断配置好了就可以输出一个好看的正弦波了,那怎么调频和调幅呢?

二、通过四个按钮控制输出的频率和幅度

代码如下:

static int DacAmp = 0.0;

void Sine()
{
	u16 key=KEY_Scan(0);
	static u16 F = 128 - 1 ;//默认50HZ	
	switch(key)
	{
		case WKUP_PRES:DacAmp +=1;break;//
		case KEY1_PRES:DacAmp -=1;break;
		case KEY2_PRES:F += 10;break;//改变TIM1的预装载值,从而改变频率
		case KEY0_PRES:F -= 10;break;
		default:break;
	}
	DacAmp = CLIP_ROT(DacAmp,0,10);
	TIM1->ARR = F;// 改变预分配系数也是可行的,(PSC)TIM1->PSC =F;
	
}

按下WKUP_PRES和KEY1_PRES,正弦波幅值变化,KEY2_PRES和KEY0_PRES控制频率变化。

三、下面是我的实测波形

 附上代码:链接:https://pan.baidu.com/s/1aXAH2Qu5vF8uVKZdXpQx0g?pwd=1234 
提取码:1234

需要的自取哈,代码写的不好,就当交流学习。

总结

额,不知道写啥,有问题请留言,如果觉得有用的话,请点个赞,不胜感激。

  • 92
    点赞
  • 347
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 要利用STM32DAC和定时器产生调频调幅正弦波,可以按照以下步骤进行实现。 首先,要设置DAC输出通道和引脚,并配置DAC的时钟。可以使用HAL库提供的相关函数来实现这些配置。 接下来,需要设置定时器以产生适当的波特率和PWM波形。根据所需的频率和调制指数,可以选择合适的定时器和计数值。可以使用HAL库提供的函数来设置定时器。 在定时器中断处理函数中,我们可以通过加载一个预先计算好的正弦表来实现正弦波产生。在每个计时器周期中,根据计数器的数值,在正弦表中找到相应位置的数值,并将其输出DAC。 同时,还可以使用一个变量来调整幅度,从而实现调幅。通过改变该变量的值,可以调整输出波的幅度大小。 最后,通过配置DAC输出的幅度和波特率,可以实现可调频调幅正弦波产生。可以根据实际需求进行调试和调整,以获得期望的频率和幅度。 需要注意的是,为了保证输出正弦波质量和稳定性,还需要相应的滤波和抗干扰措施。 ### 回答2: 要利用STM32DAC和定时器(TIM)来生成可调频调幅正弦波,可以按照以下步骤进行操作: 1. 配置DAC通道:首先需要初始化并配置DAC通道,选择所需输出DAC通道,设置对应的GPIO引脚作为DAC输出引脚。 2. 配置TIM定时器:接下来需要初始化TIM定时器,选择合适的定时器通道和相关的GPIO引脚,设置TIM的计数模式和控制模式。 3. 配置时钟频率:根据需要生成的正弦波的频率,配置时钟频率和预分频系数,确定TIM的计数频率。 4. 配置DAC的数据对齐和数据个数:设置DAC的数据对齐模式(左对齐或右对齐)和数据个数。 5. 配置DAC的波形发生器:选择所需的波形发生器(三角波、正弦波、方波等)和波形发生器的相关设置。 6. 启动TIM定时器:使能TIM定时器,并启动定时器的计数。 7. 生成正弦波:根据需要生成的正弦波的频率和幅值,根据TIM定时器的计数值和DAC的数据对齐模式,计算并设置DAC输出的电压值,从而生成正弦波。 8. 调整频率和幅值:通过调整TIM的预分频系数和计数器的自动重装载值,可以实现对正弦波的频率进行调整;通过增大或减小DAC输出的电压值,可以调整正弦波的幅值。 综上所述,通过合理配置DAC通道、TIM定时器和相关参数,可以利用STM32DAC和定时器生成可调频调幅正弦波。 ### 回答3: STM32 是一款功能强大的微控制器,其中的DAC(数字模拟转换器)用于将数字信号转换成模拟信号。利用DAC和中断定时器技术,我们可以实现产生调频调幅正弦波的功能。 首先,我们需要设置DAC输出引脚和相应的时钟源。然后,初始化DAC并配置为波形模式,将其连接到输出引脚。同时,我们需要初始化一个计时器,并设置其为中断模式和适当的频率,用于控制正弦波的频率。接下来,我们需要编写一个中断服务函数,在每个定时器中断时改变DAC输出的值。 在编写中断服务函数时,我们可以根据需要调整正弦波的频率和幅度。通过改变计数器的值,我们可以调整频率;通过改变DAC输出的值,我们可以调整幅度。具体来说,我们可以使用一个数组来存储一个完整的正弦波周期的数值,然后在每个中断中递增一个计数器,并使用该计数器作为数组的索引,将对应的数值写入DAC输出寄存器。 在主程序中,我们需要初始化相关的外设,并启动计时器和DAC输出。然后,我们可以通过编写一个无限循环,并在循环中添加适当的延迟,来使程序持续产生正弦波。 在程序运行时,DAC将根据计时器中断的频率和中断服务函数的实现来输出调频调幅正弦波。我们可以根据需要,调整计时器的频率和中断服务函数的实现来改变正弦波的频率和幅度。 以上是利用STM32DAC和中断定时器技术来产生调频调幅正弦波的基本思路和流程。当然,具体的代码实现需要根据具体的STM32型号和开发环境来确定,但是以上提供的步骤和方法是通用的。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值