基于STM32的信号发生器:打造多功能波形输出利器
基于stm32的信号发生器(仅代码) 可输出正弦波 、三角波、矩形波,4.3寸lcd显示,可按键控制输出波形的频率,以及波形,输出峰峰值3.0V,频率范围5khz-40khz(这俩指标处于误差范围5%之内)理论上其他范围的频率也可以,需要自己改代码,怎么改我代码里有讲。

最近捣鼓了一个基于STM32的信号发生器,它能输出正弦波、三角波和矩形波,还配备4.3寸LCD显示,通过按键就能轻松控制输出波形的频率和类型,输出峰峰值稳定在3.0V,频率范围在5kHz - 40kHz(误差控制在5%以内),要是你有其他频率需求,改改代码也能实现,下面就给大家分享分享。
一、整体思路
整个系统主要由STM32主控芯片、LCD显示模块、按键模块以及波形输出模块构成。STM32负责生成不同波形的数据,通过DAC输出模拟信号,同时处理按键输入来调整波形和频率,LCD实时显示当前的波形和频率信息。
二、关键代码解析
1. 正弦波生成代码
// 定义正弦波数据数组
#define SINE_TABLE_SIZE 256
const uint16_t sineTable[SINE_TABLE_SIZE];
// 初始化正弦波表
void initSineTable(void) {
for (uint16_t i = 0; i < SINE_TABLE_SIZE; i++) {
sineTable[i] = (uint16_t)(1023 * (1 + sin(2 * PI * i / SINE_TABLE_SIZE)) / 2);
}
}
// 输出正弦波
void outputSineWave(uint32_t frequency) {
uint32_t period = SystemCoreClock / frequency;
for (uint16_t i = 0; i < SINE_TABLE_SIZE; i++) {
DAC_SetChannel1Data(DAC_Align_12b_R, sineTable[i]);
for (volatile int j = 0; j < period / SINE_TABLE_SIZE; j++);
}
}
这里先定义了一个正弦波表 sineTable,initSineTable 函数初始化这个表,通过三角函数计算每个点的值。outputSineWave 函数根据设定的频率,通过DAC输出正弦波数据,在每个数据点之间通过简单的延时来控制输出频率。
2. 三角波生成代码
// 输出三角波
void outputTriangleWave(uint32_t frequency) {
uint32_t period = SystemCoreClock / frequency;
uint16_t value = 0;
uint8_t direction = 1;
while (1) {
if (direction) {
value++;
if (value >= 4095) {
value = 4095;
direction = 0;
}
} else {
value--;
if (value <= 0) {
value = 0;
direction = 1;
}
}
DAC_SetChannel1Data(DAC_Align_12b_R, value);
for (volatile int j = 0; j < period / 4096; j++);
}
}
三角波生成采用了一个简单的计数器逻辑,direction 变量控制计数方向,当达到最大值或最小值时改变方向,然后通过DAC输出相应的数据,同样通过延时控制频率。
3. 矩形波生成代码
// 输出矩形波
void outputSquareWave(uint32_t frequency) {
uint32_t period = SystemCoreClock / frequency;
uint8_t value = 0;
while (1) {
value =!value;
DAC_SetChannel1Data(DAC_Align_12b_R, value? 4095 : 0);
for (volatile int j = 0; j < period / 2; j++);
}
}
矩形波就更简单啦,通过一个 value 变量取反来控制DAC输出高电平和低电平,延时时间为周期的一半,这样就生成了占空比为50%的矩形波。
4. 按键处理代码
// 按键扫描
void keyScan(void) {
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
// 按键1按下,切换波形
currentWaveform = (currentWaveform + 1) % 3;
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0);
}
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0) {
// 按键2按下,增加频率
if (currentFrequency < 40000) {
currentFrequency += 5000;
}
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0);
}
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 0) {
// 按键3按下,降低频率
if (currentFrequency > 5000) {
currentFrequency -= 5000;
}
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 0);
}
}
按键扫描函数通过检测GPIO口的电平状态来判断按键是否按下,分别实现了波形切换、频率增加和频率降低的功能。
5. LCD显示代码
// LCD初始化
void LCD_Init(void) {
// 初始化LCD相关寄存器和引脚配置
// 这里省略具体代码,一般涉及SPI或其他接口初始化
}
// 在LCD上显示波形和频率信息
void displayInfo(void) {
char buffer[20];
switch (currentWaveform) {
case 0:
sprintf(buffer, "Sine: %d Hz", currentFrequency);
break;
case 1:
sprintf(buffer, "Triangle: %d Hz", currentFrequency);
break;
case 2:
sprintf(buffer, "Square: %d Hz", currentFrequency);
break;
}
LCD_SetCursor(0, 0);
LCD_Puts(buffer);
}
LCD初始化函数完成LCD相关的初始化工作,displayInfo 函数根据当前的波形和频率信息,格式化字符串后显示在LCD上。
三、频率范围调整说明
如果需要调整频率范围,在上述代码中主要涉及到频率计算部分。例如,outputSineWave、outputTriangleWave 和 outputSquareWave 函数中的 period 计算依赖于 SystemCoreClock 和设定的频率 frequency。如果要拓展频率范围,除了修改 currentFrequency 的限制判断,还需要根据硬件性能合理调整 SystemCoreClock 以及延时部分,确保输出的频率在误差允许范围内。

基于stm32的信号发生器(仅代码) 可输出正弦波 、三角波、矩形波,4.3寸lcd显示,可按键控制输出波形的频率,以及波形,输出峰峰值3.0V,频率范围5khz-40khz(这俩指标处于误差范围5%之内)理论上其他范围的频率也可以,需要自己改代码,怎么改我代码里有讲。

通过这些代码,一个基于STM32的多功能信号发生器就基本实现啦,希望对大家有所帮助,一起享受硬件编程的乐趣!
更多推荐
所有评论(0)