电压0-3.3V
- #include "stm32f10x.h" // Device header
- #include "Delay.h"
- #include "OLED.h"
- #include <math.h>
- #include <stdio.h>
- #include "ad.h"
- #define OLED_WIDTH 128
- #define OLED_HEIGHT 64
- #define WAVE_SAMPLES 64 // 波形采样点数
- #define WAVE_OFFSET 17 // 波形在Y轴上的偏移量
- #define VOLTAGE_RANGE 3.3 // 电压范围
- #define VOLTAGE_STEP 0.1 // 电压步长
- #define VOLTAGE_TO_PIXEL_SCALE 14 // 电压到像素的缩放比例
- int16_t wave_buffer[WAVE_SAMPLES]; // 波形缓冲区
- uint16_t wave_index = 0; // 波形缓冲区索引
- int16_t x,y;
- double radian;
- double voltage; //电压值
- double phase_angle; // 相位角,范围是0到2π
- double voltage_increment = VOLTAGE_STEP; // 电压增量
- double sample_rate = (double)OLED_WIDTH / WAVE_SAMPLES; // 采样率
- uint16_t ADValue;
- #define NUM_PERIODS 10 // 要计算平均频率的周期数
- double period_times[NUM_PERIODS]; // 存储周期时间间隔的数组
- int period_index = 0; // 当前周期时间间隔的索引
- void PWM_Init(void);
- void Servo_SetAngle(float Angle);
- void PWM_SetCompare2(uint16_t Compare);
- void Timer3_init(uint16_t arr,uint16_t psc);
- void OLED_DrawWave()
- {
- int16_t x_current;
- int16_t y_current;
- int16_t x_end = 0; // 波形结束X坐标(屏幕最左侧)
- int16_t y_prev = WAVE_OFFSET; // 上一个点的Y坐标
-
- // 绘制波形线
- for (int i = 0; i < WAVE_SAMPLES; i++)
- {
- x_current= (OLED_WIDTH - 1) - (i * (OLED_WIDTH - 1) / (WAVE_SAMPLES - 1))/1; // 当前点的X坐标
- y_current= wave_buffer[(wave_index + i) % WAVE_SAMPLES]; // 当前点的Y坐标(循环缓冲区)
-
- // 如果当前点不是第一个点,则绘制线段
- if (i > 0)
- {
- OLED_DrawLine(x_end, y_prev, x_current, y_current);
- }
-
- x_end = x_current; // 更新结束X坐标
- y_prev = y_current; // 更新上一个点的Y坐标
- }
-
- }
- void TIM3_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
- {
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
- }
- }
- int main(void)
- {
- uint8_t i;
- double frequency_sum = 0.0;
- OLED_Init();
- AD_Config();
- PWM_Init();
- Timer3_init(10000,7200);
- while(1)
- {
- i++;
- PWM_SetCompare2(i);
- ADValue = AD_GetValue();
- voltage = (float)ADValue / 4095 * VOLTAGE_RANGE;
- OLED_ClearArea(0, 0, OLED_WIDTH, OLED_HEIGHT);
- OLED_ShowFloatNum(70,0,voltage,2,2,OLED_6X8);
- // OLED_ShowFloatNum(0,0,average_frequency,2,5,OLED_6X8);
-
-
- // 将新的电压值添加到波形缓冲区,并更新索引
- wave_buffer[wave_index] = (int16_t)(voltage * VOLTAGE_TO_PIXEL_SCALE + WAVE_OFFSET);
- wave_index = (wave_index +1) % WAVE_SAMPLES; // 循环缓冲区
- OLED_DrawWave(); // 绘制波形
-
- OLED_Update(); // 将数据更新到OLED
- }
- }
- //int main(void)
- //{
- // OLED_Init();
- // AD_Config();
- // PWM_Init();
- // while (1)
- // {
- // OLED_ClearArea(0,0,128,64);
- //// // 将电压值线性映射到相位角上
- //// phase_angle = voltage * (2 * 3.14 / 3.3); // 3.3是电压范围的最大值
- //// for(x=0;x<128;x++)
- //// {
- //// radian=(double)x*(2*3.14/128)+phase_angle;
- //// y=(int16_t)(voltage*10*sin(radian)+32);
- //// OLED_DrawPoint(x, y);
- //// // 确保y坐标在OLED屏幕范围内
- //// if (y < 0) y = 0;
- //// if (y >= 64) y = 64 - 1;
- //// }
- //// voltage+=0.1;
- //// if(voltage>3.3)
- //// {
- //// voltage-=0.1;
- //// }
- //// if (phase_angle >= 2 * 3.14) {
- //// phase_angle -= 2 * 3.14; }
- //
- // OLED_ShowFloatNum(20,0,voltage,1,2,OLED_8X16);
- //
- // ADValue = AD_GetValue();
- // voltage = (float)ADValue / 4095 * 3.3;
- // // 根据voltage值计算波形数据点
- // for (int i = 0; i < WAVE_SAMPLES; i++)
- // {
- // double position = (double)i / (WAVE_SAMPLES - 1); // 当前位置(0到1之间)
- // double normalized_voltage = voltage / VOLTAGE_RANGE; // 归一化电压值
- // double wave_height = (sin(12 * 3.14 * position) + 1) / 2 * normalized_voltage * (OLED_HEIGHT - 2 * WAVE_OFFSET); // 计算波形高度
- // wave_buffer[i] = (int16_t)(WAVE_OFFSET + wave_height+10); // 转换为整数并加上偏移量
- // }
- // // 绘制波形到OLED屏幕
- // for (int i = 0; i < WAVE_SAMPLES - 1; i++)
- // {
- // OLED_DrawLine(i * sample_rate, wave_buffer[i], (i + 1) * sample_rate, wave_buffer[i + 1]);
- // }
- //// // 更新voltage值
- //// voltage += voltage_increment;
- //// if (voltage > VOLTAGE_RANGE)
- //// {
- //// voltage = VOLTAGE_RANGE;
- //// voltage_increment = -VOLTAGE_STEP; // 开始减小voltage值
- //// }
- //// else if (voltage < 0.0)
- //// {
- //// voltage = 0.0;
- //// voltage_increment = VOLTAGE_STEP; // 开始增大voltage值
- //// }
- // OLED_Update();//将数据更新到oled
- // Delay_ms(500);
- // }
- //}
- void PWM_Init(void)
- {
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- TIM_InternalClockConfig(TIM2);
-
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_Period = 4000-1; //ARR
- TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1; //PSC
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
-
- TIM_OCInitTypeDef TIM_OCInitStructure;
- TIM_OCStructInit(&TIM_OCInitStructure);
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_Pulse = 1; //CCR
- TIM_OC2Init(TIM2, &TIM_OCInitStructure);
-
- TIM_CtrlPWMOutputs(TIM2, ENABLE); //使能PWM波对外设的输出
- TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_OC2Ref);//选择TIM2上升沿作为ADC触发源
- TIM_Cmd(TIM2, ENABLE);
-
- }
- void Timer3_init(uint16_t arr,uint16_t psc)
- {
- TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStruct={0};
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
-
- //TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);//使用外部时钟,关闭外部触发TIM预分频器,上升沿激活,关闭外部触发过滤器
- TIM_InternalClockConfig(TIM3);//使用内部时钟
-
- //f=72000/10000/7200=0.001
- TIM3_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ;//时钟分频1
- TIM3_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up ;//向上计数
- TIM3_TimeBaseInitStruct.TIM_Period = arr;//负载重装值
- TIM3_TimeBaseInitStruct.TIM_Prescaler = psc ;//预分频值
- TIM3_TimeBaseInitStruct.TIM_RepetitionCounter= 0 ;//关闭重复计数(高级定时器才有)
- TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStruct);
-
- TIM_ClearFlag(TIM3,TIM_FLAG_Update);//清除更新中断标志位,避免初始化完就进入中断
-
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能中断
-
- NVIC_InitTypeDef NVIC_TIM3_InitStruct={0};
- NVIC_TIM3_InitStruct.NVIC_IRQChannel = TIM3_IRQn ;//中断通道
- NVIC_TIM3_InitStruct.NVIC_IRQChannelCmd = ENABLE ;
- NVIC_TIM3_InitStruct.NVIC_IRQChannelPreemptionPriority = 2 ;//抢占优先级
- NVIC_TIM3_InitStruct.NVIC_IRQChannelSubPriority = 2 ;//响应优先级
- NVIC_Init(&NVIC_TIM3_InitStruct);
-
- TIM_Cmd(TIM3,ENABLE);
- }
- void PWM_SetCompare2(uint16_t Compare)
- {
- TIM_SetCompare2(TIM2, Compare);
- }
- void Servo_SetAngle(float Angle)
- {
- PWM_SetCompare2(Angle / 180 * 2000 + 500);
- }
复制代码
原理图: 无
仿真: 无
代码:
32简易示波.7z
(189.13 KB, 下载次数: 0)
|