使用STM32f103控制OLED实时显示波形并更新波形的代码
时间: 2024-05-15 16:13:08 浏览: 110
以下是使用STM32f103控制OLED实时显示波形并更新波形的代码:
```
#include "stm32f10x.h"
#include "oled.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#define PI 3.1415926535
uint8_t buffer[128]; // 缓冲区
void delay_us(uint32_t nus) // 微秒级延时函数
{
uint32_t i;
while(nus--)
{
i = 7;
while(i--);
}
}
void delay_ms(uint16_t nms) // 毫秒级延时函数
{
uint16_t i;
while(nms--)
{
i = 12000;
while(i--);
}
}
void ADC_Configuration(void) // ADC配置函数
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); // 使能ADC1和PA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // ADC1通道0连接PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); // ADC1外设寄存器恢复默认值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 关闭扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 开启连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 转换由软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; // 转换通道数目
ADC_Init(ADC1, &ADC_InitStructure); // ADC1初始化
ADC_Cmd(ADC1, ENABLE); // 使能ADC1
ADC_ResetCalibration(ADC1); // 复位ADC1校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); // 等待ADC1校准寄存器复位完成
ADC_StartCalibration(ADC1); // 开始ADC1校准
while(ADC_GetCalibrationStatus(ADC1)); // 等待ADC1校准完成
}
uint16_t Get_ADC(void) // 获取ADC值
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 开始ADC1转换
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换完成
return ADC_GetConversionValue(ADC1); // 返回转换结果
}
int main(void)
{
OLED_Init(); // OLED初始化
ADC_Configuration(); // ADC配置
uint16_t adc_value;
uint8_t x, y, i;
while(1)
{
adc_value = Get_ADC(); // 获取ADC值
y = 0; // y坐标清零
for(x = 0; x < 128; x++) // 遍历x坐标
{
buffer[x] = 0; // 缓冲区清零
for(i = 0; i < 8; i++) // 遍历8位
{
if((uint8_t)(adc_value & (1 << i)) != 0) // 判断ADC值的第i位是否为1
{
buffer[x] |= (1 << i); // 将缓冲区的第i位设为1
}
}
y = (uint8_t)(64 + 10 * sin(2 * PI * x / 128)); // 计算y坐标
OLED_DrawPoint(x, y, 1); // 在屏幕上绘制点
OLED_DrawByte(x, y + 8, buffer[x]); // 在屏幕上绘制字节
delay_us(100); // 延时,控制刷新速度
}
}
}
```
该代码实现了在OLED屏幕上实时显示波形,并且可以更新波形。具体实现过程如下:
1. 定义缓冲区`buffer`,用于存储ADC值的二进制表示。
2. 实现微秒级延时函数`delay_us`和毫秒级延时函数`delay_ms`,用于控制刷新速度。
3. 实现ADC配置函数`ADC_Configuration`,用于初始化ADC1和PA0引脚。
4. 实现获取ADC值的函数`Get_ADC`,用于获取ADC1通道0的值。
5. 在主函数中,循环获取ADC值,并使用`sine`函数计算y坐标,绘制波形。
6. 遍历x坐标,将ADC值的二进制表示存储到缓冲区`buffer`中,并在屏幕上绘制点和字节。
7. 延时一段时间,控制刷新速度。
注意:本代码仅作为参考,具体实现方式可能会因硬件配置、库文件版本等因素而有所差异。
阅读全文