電壓0-3.3V
bfe0c46d178e77a7f2c47f32cf0c53c.jpg (99.86 KB, 下載次數: 0)
下載附件
2025-1-2 18:26 上傳
- #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)
2025-1-2 22:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|