#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "lcd.h" #include "dac.h" #include "adc.h" #include "timer.h" #include "stm32f10x_it.h" #include "key.h" #include "stm32f10x.h" #include "math.h" //数值可以用int u8 最大256 int fangbo[512]={ 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, }; int sin_table[512]= { 128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173, 176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226, 228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253, 254,254,254,255,255,255,255,255,255,255,254,254,254,253,253,252,251,250,250,249,248, 246,245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,218,215,213,211, 208,206,203,201,198,196,193,190,188,185,182,179,176,173,170,167,165,162,158,155,152, 149,146,143,140,137,134,131,128,124,121,118,115,112,109,106,103,100,97,93,90,88,85, 82,79,76,73,70,67,65,62,59,57,54,52,49,47,44,42,40,37,35,33,31,29,27,25,23,21,20,18, 17,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11, 12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73, 76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,128,131,134,137,140,143,146, 149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208, 211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248, 249,250,250,251,252,253,253,254,254,254,255,255,255,255,255,255,255,254,254,254,253,253, 252,251,250,250,249,248,246,245,244,243,241,240,238,237,235,234,232,230,228,226,224,222, 220,218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,176,173,170,167,165, 162,158,155,152,149,146,143,140,137,134,131,128,124,121,118,115,112,109,106,103,100,97, 93,90,88,85,82,79,76,73,70,67,65,62,59,57,54,52,49,47,44,42,40,37,35,33,31,29,27,25,23, 21,20,18,17,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9, 10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70, 73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124}; int Triangle[256]={ 136,137,138, 139,140,141,142,143,144,145,146,147,148, 149,150,151,152,153,154,155,156,157,158, 159,160,161,162,163,164,165,166,167,168, 169,170,171,172,173,174,175,176,177,178, 179,180,181,182,183,184,185,186,187,188, 189,190,191,192,193,194,195,196,197,198, 199,200,199,198,197,196,195,194,193,192, 191,190,189,188,187,186,185,184,183,182, 181,180,179,178,177,176,175,174,173,172, 171,170,169,168,167,166,165,164,163,162, 161,160,159,158,157,156,155,154,153,152, 151,150,149,148,147,146,145,144,143,142, 141,140,139,138,137, 136,137,138, 139,140,141,142,143,144,145,146,147,148, 149,150,151,152,153,154,155,156,157,158, 159,160,161,162,163,164,165,166,167,168, 169,170,171,172,173,174,175,176,177,178, 179,180,181,182,183,184,185,186,187,188, 189,190,191,192,193,194,195,196,197,198, 199,200,199,198,197,196,195,194,193,192, 191,190,189,188,187,186,185,184,183,182, 181,180,179,178,177,176,175,174,173,172, 171,170,169,168,167,166,165,164,163,162, 161,160,159,158,157,156,155,154,153,152, 151,150,149,148,147,146,145,144,143,142, 141,140,139,138,137 }; int main(void) { // u8 ping=0; u8 pinglv=99; u8 yanshi=1; u8 zkb=50;u8 zkbbef=50; u8 t,len; u16 iii=0; u16 i; u16 adcx,adcxtemp,adcxtemp1; //float temp; u8 jishu=0; u8 jishu1=0; u16 ii=0; u8 key=0; //u8 key1=0; // u8 x; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 LED_Init(); //初始化LED LCD_Init(); //初始化LCD KEY_Init(); LED0 = 0; Adc_Init(); //ADC初始化 Dac1_Init(); //DAC初始化 //usmart_dev.init(72); //初始化USMART ??串口用 (DAC_Align_12b_R, 0);//初始值为0 POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(60,280,200,16,16,"Freq(HZ): 0."); LCD_ShowString(60,300,200,16,16,"Duty Cycle(%):"); while(1) { //串口功能 我是单片机 接受 :电脑串口发给我 发送:我发给串口电脑 if(USART_RX_STA&0x8000) // USART_RX_STA|=0x8000; 接收完成了 一次大循环接受一个u8(一个数字或者字符),存入BUF 再存入res中 { printf("\r\n您发送的频率0.1-0.99Hz占空比2位0-99%\r\n\r\n"); //频率范围 单位hz len=USART_RX_STA&0x3fff;//得到此次接收到的数据长? for(t=0;t<len;t++) { USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数? 先进来的存在? buf0中,,,, //u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.一个字节8b len个数组 整型数组 pinglv=10*(USART_RX_BUF[0]-48)+(USART_RX_BUF[1]-48); zkb=10*(USART_RX_BUF[2]-48)+(USART_RX_BUF[3]-48); zkb=100-zkb; while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 } printf("\r\n\r\n");//插入换行 USART_RX_STA=0;//??/接收状态标记 } key=KEY_Scan(0); //得到键值 修改通过一个按键切换三种波形 //返回1,KEY0按下 if(key==KEY0_PRES) { jishu1=jishu; jishu++; } switch(jishu%3) { case 0: //正弦 if(jishu!=jishu1) { jishu1=jishu; ii=0;iii=0; LCD_Clear(WHITE); LCD_ShowString(60,280,200,16,16,"Freq(HZ): 0."); LCD_ShowString(60,300,200,16,16,"Duty Cycle(%):"); } //LCD_Fast_DrawPoint(ii,sin_table[2*ii],BLACK);//打点 Dac1_Set_Vol(sin_table[2*ii]);//DA输出 pA4输出da转模拟值 pa1输入模拟值转ad if(ii>=1) LCD_DrawLine(ii,sin_table[2*ii],ii-1,sin_table[2*ii-2]);//画线 ii++; if(ii==255) {ii=0;} break; case 1: //三角 if(jishu!=jishu1) {jishu1=jishu; ii=0;iii=0; LCD_Clear(WHITE); LCD_ShowString(60,280,200,16,16,"Freq(HZ): 0."); LCD_ShowString(60,300,200,16,16,"Duty Cycle(%):"); } LCD_Fast_DrawPoint(ii,Triangle[ii],BLACK); Dac1_Set_Vol(Triangle[ii]);//DA输出 ii++; if(ii==255) {ii=0;} break; case 2: //方波 一个周期128点 低64 高64 if(jishu!=jishu1) {jishu1=jishu; iii=0;ii=0; LCD_Clear(WHITE); LCD_ShowString(60,280,200,16,16,"Freq(HZ): 0."); LCD_ShowString(60,300,200,16,16,"Duty Cycle(%):"); } // LCD_Fast_DrawPoint(ii,fangbo[2*ii],BLACK); //修改占空比zkb 0-99 修改数组值 if(zkb!=zkbbef) //检测zkb是否改变 如果改变再重新赋值数组fangbo { zkbbef=zkb; for(i=0;i<128*zkb/100*2;i++)//zkb给的是整数 { fangbo[i]=255; fangbo[i+256]=255; //fangbo[256-(int)(128*zkb/100*2)]=128; fangbo[512-i-1]=128; } for(i=(int)(128*zkb/100*2);i<256;i++) { fangbo[i]=1; fangbo[i+256]=1; //fangbo[256-(int)(128*zkb/100*2)]=128; fangbo[512-i-1]=128; } } if (ii>=1) LCD_DrawLine(ii,fangbo[2*ii],ii-1,fangbo[2*ii-2]);//画线 ii++; if(ii==255) {ii=0; } Dac1_Set_Vol(fangbo[2*ii]);//DA输出 break; } //adc输出后再清屏 adcx=Get_Adc(ADC_Channel_1); // adcx=Get_Adc_Average(ADC_Channel_1,1); //10-1 //采样1次 输出ad平均值 LCD_ShowxNum(156,280,pinglv,4,16,0);//显示频率 LCD_ShowxNum(156,300,100-zkb,4,16,0);//显示zkb值 // LCD_ShowxNum(156,320,yanshi,4,16,0); adcxtemp1=adcxtemp; adcxtemp=(int)(adcx*0.03125+284); //384 //显示在下半屏幕 // LCD_Fast_DrawPoint(iii,adcxtemp,255); //打点 if(iii>=1) LCD_DrawLine(iii,adcxtemp,iii-1,adcxtemp1);//画线 iii++; if(iii==255) { iii=0; LCD_Clear(WHITE); LCD_ShowString(60,280,200,16,16,"Freq(HZ): 0."); LCD_ShowString(60,300,200,16,16,"Duty Cycle(%)"); }//显示zkb } //clear 前面ii=255不清屏 iii=255清屏 yanshi=100-pinglv; // delay_ms(yanshi); /* 输入pinglv=1000hz T=0.001 一个点yanshi? us 正弦128 方波一个周期128 三角128 pinglv=100 t=0.01 10 0.1 18359x 5 0.2 1 1 2382 0.5 2 */ } } 修改代码:改为频率范围为1~10k赫兹
时间: 2025-07-01 17:29:58 浏览: 4
### 修改代码以支持1~10kHz频率范围
为了实现1~10kHz的频率范围,同时保留波形类型(正弦波、方波、三角波)和幅度控制功能,需要对定时器配置进行调整,并确保波形生成逻辑正确。以下是修改后的完整代码:
```c
#include "stm32f10x.h"
#include "math.h"
#define WAVE_POINTS 1024 // 波形点数
#define DAC_DHR12R1_ADDRESS 0x40007408 // DAC通道1数据寄存器地址
// 波形类型枚举
typedef enum {
SINE_WAVE = 0,
SQUARE_WAVE,
TRIANGLE_WAVE
} WaveType;
// 全局变量
volatile uint16_t waveBuffer[WAVE_POINTS]; // 波形数据缓冲区
volatile float amplitude = 1.0; // 幅度系数 (0.0-1.0)
volatile uint32_t frequency = 1000; // 频率(Hz)
volatile WaveType currentWave = SINE_WAVE;
// 生成正弦波数据
void GenerateSineWave(void) {
for(int i = 0; i < WAVE_POINTS; i++) {
float value = sin(2 * M_PI * i / WAVE_POINTS);
waveBuffer[i] = (uint16_t)(2048 * (1 + amplitude * value)); // 0-4095范围
}
}
// 生成方波数据
void GenerateSquareWave(void) {
for(int i = 0; i < WAVE_POINTS; i++) {
waveBuffer[i] = (i < WAVE_POINTS/2) ?
(uint16_t)(4095 * amplitude) :
(uint16_t)(0);
}
}
// 生成三角波数据
void GenerateTriangleWave(void) {
for(int i = 0; i < WAVE_POINTS; i++) {
float value = fabs((float)(i % (WAVE_POINTS / 2)) - (WAVE_POINTS / 4)) / (WAVE_POINTS / 4);
waveBuffer[i] = (uint16_t)(2048 + 2047 * amplitude * value); // 0-4095范围
}
}
// 更新波形数据
void UpdateWaveform(void) {
switch(currentWave) {
case SINE_WAVE:
GenerateSineWave();
break;
case SQUARE_WAVE:
GenerateSquareWave();
break;
case TRIANGLE_WAVE:
GenerateTriangleWave();
break;
}
}
// DAC初始化
void DAC_Config(void) {
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
// 配置PA4为模拟输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// DAC通道1配置
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; // 定时器6触发
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE);
}
// DMA初始化
void DMA_Config(void) {
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
DMA_DeInit(DMA2_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)waveBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = WAVE_POINTS;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA2_Channel3, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
}
// 定时器配置 (控制输出频率)
void TIM6_Config(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
// 定时器频率 = 72MHz / (TIM_Prescaler+1)
TIM_TimeBaseStructure.TIM_Period = (72000000 / (frequency * WAVE_POINTS)) - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
TIM_Cmd(TIM6, ENABLE);
}
// 设置波形类型
void SetWaveType(WaveType type) {
currentWave = type;
UpdateWaveform();
}
// 设置输出幅度 (0.0-1.0)
void SetAmplitude(float amp) {
amplitude = (amp > 1.0) ? 1.0 : ((amp < 0) ? 0 : amp);
UpdateWaveform();
}
// 设置输出频率 (Hz)
void SetFrequency(uint32_t freq) {
frequency = (freq < 1) ? 1 : ((freq > 10000) ? 10000 : freq);
TIM6->ARR = (72000000 / (frequency * WAVE_POINTS)) - 1;
}
int main(void) {
// 系统初始化
SystemInit();
// 生成初始波形
UpdateWaveform();
// 外设初始化
DAC_Config();
DMA_Config();
TIM6_Config();
while(1) {
// 此处可添加用户交互逻辑
}
}
```
### 关键修改点
1. **波形点数调整**:
- 将波形点数从256增加到1024,以提高波形平滑度[^1]。
2. **频率计算公式**:
- 使用定时器6的自动重装载寄存器(ARR)来设置更新频率。公式为:
$$
\text{ARR} = \frac{\text{系统时钟}}{\text{输出频率} \times \text{波形点数}} - 1
$$
这样可以覆盖1~10kHz的频率范围。
3. **波形生成函数**:
- 增加了三角波生成函数`GenerateTriangleWave()`,并将其集成到波形更新逻辑中。
4. **幅度控制**:
- 幅度控制通过缩放DAC输出值实现,范围为0.0~1.0。
5. **频率范围限制**:
- 在`SetFrequency()`函数中,确保频率范围在1~10kHz之间。
### 性能参数
- 输出频率范围:1Hz ~ 10kHz
- 幅度分辨率:12位(4096级)
- 波形类型:正弦波、方波、三角波
- 最大输出电压:3.3V(需外部运放放大)
###
阅读全文
相关推荐





