STM32F103ZET6之AD采集利用IIC通过OLED显示波形
时间: 2023-08-03 08:09:29 浏览: 262
STM32F103ZET6之AD采集利用IIC通过OLED显示波形.rar
首先,需要使用STM32F103ZET6的ADC模块进行模拟信号的采集。接着,需要使用IIC通信协议将采集到的数据传输到OLED屏幕上进行显示。
以下是一个简单的示例代码:
```c
#include "stm32f10x.h"
#include "oled.h"
#define I2C_Speed 100000
#define I2C1_SLAVE_ADDRESS7 0xA0
#define I2C_PageSize 8
uint16_t ADC_ConvertedValue;
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
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);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
uint16_t Get_Adc(uint8_t ch)
{
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
void I2C_SendData(uint8_t data)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, data);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
void OLED_WriteCmd(uint8_t cmd)
{
I2C_SendData(0x00);
I2C_SendData(cmd);
}
void OLED_WriteData(uint8_t data)
{
I2C_SendData(0x40);
I2C_SendData(data);
}
void OLED_Init(void)
{
OLED_WriteCmd(0xAE); // 关闭OLED
OLED_WriteCmd(0x00); // 设置列低地址
OLED_WriteCmd(0x10); // 设置列高地址
OLED_WriteCmd(0x40); // 设置起始行地址
OLED_WriteCmd(0x81); // 对比度设置
OLED_WriteCmd(0xCF); // 设置对比度
OLED_WriteCmd(0xA1); // 设置段重定向
OLED_WriteCmd(0xC8); // 设置COM重定向
OLED_WriteCmd(0xA6); // 设置正常显示
OLED_WriteCmd(0xA8); // 设置多路复用比
OLED_WriteCmd(0x3F); // 设置多路复用比
OLED_WriteCmd(0xD3); // 设置显示偏移
OLED_WriteCmd(0x00); // 无偏移
OLED_WriteCmd(0xd5); // 设置震荡器频率
OLED_WriteCmd(0x80);
OLED_WriteCmd(0xD9); // 设置预充电周期
OLED_WriteCmd(0xF1);
OLED_WriteCmd(0xDA); // 设置COM引脚硬件配置
OLED_WriteCmd(0x12);
OLED_WriteCmd(0xdb); // 设置VCOMH
OLED_WriteCmd(0x40);
OLED_WriteCmd(0x8d); // 设置电源
OLED_WriteCmd(0x14);
OLED_WriteCmd(0xAF); // 打开OLED
}
void OLED_Clear(void)
{
uint8_t i, j;
for(i=0; i<8; i++)
{
OLED_WriteCmd(0xb0+i);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
for(j=0; j<128; j++)
{
OLED_WriteData(0x00);
}
}
}
void OLED_ShowWave(uint16_t data)
{
static uint8_t count = 0;
static uint16_t last_data = 0;
if(count == 0)
{
OLED_Clear();
OLED_WriteCmd(0xb0+7);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
}
else
{
uint8_t i;
for(i=0; i<8; i++)
{
OLED_WriteCmd(0xb0+i);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
uint8_t k;
for(k=0; k<16; k++)
{
uint16_t temp = last_data + (data-last_data)/(k+1)*(count+k);
uint8_t pixel = (temp>>7) & 0xff;
OLED_WriteData(pixel);
}
}
}
last_data = data;
count++;
if(count >= 16)
{
count = 0;
}
}
int main(void)
{
ADC_Configuration();
I2C_Configuration();
OLED_Init();
while(1)
{
ADC_ConvertedValue = Get_Adc(0);
OLED_ShowWave(ADC_ConvertedValue);
}
}
```
在以上代码中,首先进行了ADC和IIC的初始化配置,然后在主函数中循环读取ADC采集到的数据,并将数据传输到OLED屏幕上进行波形显示。需要注意的是,为了实现连续的波形显示,需要使用一个计数器来控制每次只显示一部分数据,然后逐步更新显示。
阅读全文