STM32驱动AD9850输出正弦波和方波,能够通过按键控制输出的数量,并且调整频率和相位的的代码
时间: 2023-12-14 16:38:05 浏览: 358
以下是基于STM32驱动AD9850输出正弦波和方波,并通过按键控制输出数量,同时能够调整频率和相位的代码示例:
```c
#include "stm32f10x.h"
#include "delay.h"
#define FSYNC PBout(12)
#define SCLK PBout(13)
#define SDATA PBout(15)
void AD9850_Init(void);
void AD9850_SetFrequency(unsigned long frequence);
void AD9850_SetPhase(unsigned int phase);
void AD9850_SendData(unsigned long data);
int main(void)
{
SystemInit();
delay_init();
AD9850_Init();
unsigned long freq = 1000000; // 初始频率为1MHz
unsigned int phase = 0; // 初始相位为0
int output_num = 1; // 初始输出数量为1
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) // 如果按键被按下
{
delay_ms(20); // 延时去抖动
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) // 确认按键仍被按下
{
output_num++; // 增加输出数量
if(output_num > 4) output_num = 1; // 如果超过4个输出则重置为1个输出
}
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0) // 如果按键被按下
{
delay_ms(20); // 延时去抖动
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0) // 确认按键仍被按下
{
freq += 100000; // 增加频率100kHz
if(freq > 4000000) freq = 1000000; // 如果超过4MHz则重置为1MHz
AD9850_SetFrequency(freq); // 设置新的频率
}
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 0) // 如果按键被按下
{
delay_ms(20); // 延时去抖动
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 0) // 确认按键仍被按下
{
phase += 45; // 增加相位45度
if(phase >= 360) phase = 0; // 如果超过360度则重置为0度
AD9850_SetPhase(phase); // 设置新的相位
}
}
// 输出正弦波或方波
unsigned int i;
for(i=0; i<output_num; i++)
{
AD9850_SendData(0x400000); // 正弦波输出
delay_ms(10);
AD9850_SendData(0x000000); // 方波输出
delay_ms(10);
}
}
}
void AD9850_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
FSYNC = 1;
SCLK = 0;
SDATA = 0;
}
void AD9850_SetFrequency(unsigned long frequence)
{
unsigned long tuning_word = (unsigned long)(frequence * 4294967296.0 / 125000000.0); // 根据公式计算调谐字
AD9850_SendData(0x210000); // 写入频率控制寄存器,选择频率控制字1
AD9850_SendData((tuning_word >> 0) & 0xFF); // 写入频率控制字1的低8位
AD9850_SendData((tuning_word >> 8) & 0xFF); // 写入频率控制字1的中间8位
AD9850_SendData((tuning_word >> 16) & 0xFF); // 写入频率控制字1的高8位
AD9850_SendData((tuning_word >> 24) & 0xFF); // 写入频率控制字1的顶部8位
AD9850_SendData(0x200000); // 写入频率控制寄存器,选择频率控制字0
AD9850_SendData(0x000000); // 写入频率控制字0的低8位
AD9850_SendData(0x000000); // 写入频率控制字0的中间8位
AD9850_SendData(0x000000); // 写入频率控制字0的高8位
AD9850_SendData(0x000001); // 写入频率控制字0的顶部8位
}
void AD9850_SetPhase(unsigned int phase)
{
unsigned long phase_word = (unsigned long)(phase * 65536.0 / 360.0); // 根据公式计算相位字
AD9850_SendData(0xC00000); // 写入相位控制寄存器
AD9850_SendData((phase_word >> 8) & 0xFF); // 写入相位字的高8位
AD9850_SendData(phase_word & 0xFF); // 写入相位字的低8位
AD9850_SendData(0x000000); // 写入相位控制寄存器
AD9850_SendData(0x000000); // 写入相位控制寄存器
AD9850_SendData(0x000000); // 写入相位控制寄存器
}
void AD9850_SendData(unsigned long data)
{
unsigned char i;
FSYNC = 0;
for(i=0; i<32; i++)
{
if(data & 0x80000000) SDATA = 1; else SDATA = 0; // 发送MSB
SCLK = 1;
data <<= 1; // 下一位
SCLK = 0;
}
FSYNC = 1;
}
```
在上述代码中,我们使用了PA0、PA1和PA2三个引脚来控制输出数量、频率和相位。代码中使用了STM32的定时器和延时函数来控制输出频率和延时。需要注意的是,AD9850的时钟输入需要125MHz,因此在设置频率时需要将计算出的调谐字乘以4294967296.0 / 125000000.0(即2^32 / 125000000.0)得到实际的调谐字。相位的设置同理,计算出的相位字需要乘以65536.0 / 360.0(即2^16 / 360.0)得到实际的相位字。
阅读全文