STM32个人学习笔记(标准库)-2023.09.22

第七节、ADC模数转换器

7.1 ADC简介

ADC(Analog-Digital Converter)模拟-数字转换器(可以看做是电压表,将引脚的电压值测出,并放在一个变量内

ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁

12位逐次逼近型ADC,1us转换时间

输入电压范围:0~3.3V,转换结果范围:0~4095

18个输入通道,可测量16个外部和2个内部信号源

规则组和注入组两个转换单元

模拟看门狗自动监测输入电压范围

逐次逼近型ADC:

 在上图的比较器中,输入端一个是待测电压,另一个是DAC的电压输出端,两端的电压同时输入到电压比较器中进行比较,如果DAC输出电压较大,则调小DAC数据,反之则增大DAC数据,直到DAC输出的电压与外部通道输入的电压近似相等。

单个ADC的结构框图如下:

ADC的基本结构如下:

触发控制:可以选择软件触发或硬件触发。

模拟看门狗:能够监测转换结果的范围,当超出设定的阈值时,通过中断输出控制,向NVIC申请中断。

开关控制:ADC_Cmd函数

根据上图,AD初始化可分为以下几个步骤:

1、RCC开启时钟,包括ADC和GPIO的时钟,并配置ADCCLK的分频器。

2、配置GPIO,将需要用的GPIO配置为模拟输入模式。

3、配置多路开关,将左边的通道接入到右边的规则组列表中。

4、配置ADC转换器。

5、开关控制。

ADC的输入通道如下表:

ADC的转换共有四个模式,分别是单次转换、非扫描模式;连续转换、非扫描模式;单次转换、扫描模式;连续转换、扫描模式。

AD转换的步骤:采样、保持、量化、编码。

STM32的ADC的总转换时间为:

Tconv=采样时间+12.5个ADC周期。

例如,当ADCCLK=14MHz,采样周期为1.5个ADC周期

Tconv=1.5+12.5=14个ADC周期=1us。

具体的ADC转换模式的操作如下:

1、触发转换。

2、等待转换完成,读取EOC标志位。

3、读取ADC数据寄存器的值。

7.2 ADC相关库函数

void ADC_DeInit(ADC_TypeDef* ADCx);//恢复缺省配置
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//ADC初始化
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);//ADC结构体初始化
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//给ADC上电
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//用于开启DMA输出信号
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//ADC中断输出控制
void ADC_ResetCalibration(ADC_TypeDef* ADCx);//复位校准
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);//获取复位校准状态
void ADC_StartCalibration(ADC_TypeDef* ADCx);//开启校准
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取开启校准状态
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC软件开始转换控制
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);//ADC获取软件触发转换状态
/*配置间断模式*/
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//ADC规则组通道配置
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC外部触发转换控制
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);//ADC获取转换值
uint32_t ADC_GetDualModeConversionValue(void);//ADC获取双模式转换值
/*ADC注入组配置*/
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
/*ADC模拟看门狗配置*/
void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);//是否启动模拟看门狗
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);//配置高低阈值
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);//配置看门通道

void ADC_TempSensorVrefintCmd(FunctionalState NewState);//ADC开启内部两个通道
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//获取标志位状态
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//清除标志位
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);//获取中断状态
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);//清除中断挂起位

7.3 代码实现AD单通道&多通道转换

7.3.1 AD单通道

AD.c:

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	/*RCC开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟分频系数
	/*配置GPIO*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	/*配置多路开关*/
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	/*结构体初始化ADC*/
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据对齐
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//ADC外部触发转换选择
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//连续转换模式
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描转换模式
	ADC_InitStructure.ADC_NbrOfChannel=1;//通道数目
	ADC_Init(ADC1,&ADC_InitStructure);
	/*ADC使能*/
	ADC_Cmd(ADC1,ENABLE);
	/*对ADC进行校准*/
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1) == SET);
}

uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发ADC转换
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//读取标志位状态
	return ADC_GetConversionValue(ADC1);//获取转换值
}

main函数:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Delay.h"
#include "AD.h"
uint16_t AD_Value;
int main(void)
{
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"ADValue:");
	while(1)
	{
		AD_Value = AD_GetValue();
		OLED_ShowNum(1,9,AD_Value,4);
	}
}
7.3.2 AD多通道

AD.c:

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	/*RCC开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟分频系数
	/*配置GPIO*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	/*结构体初始化ADC*/
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据对齐
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//ADC外部触发转换选择
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//连续转换模式
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描转换模式
	ADC_InitStructure.ADC_NbrOfChannel=1;//通道数目
	ADC_Init(ADC1,&ADC_InitStructure);
	/*ADC使能*/
	ADC_Cmd(ADC1,ENABLE);
	/*对ADC进行校准*/
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1) == SET);
}

uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	/*配置多路开关*/
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发ADC转换
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//读取标志位状态
	return ADC_GetConversionValue(ADC1);//获取转换值
}

main函数:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Delay.h"
#include "AD.h"
uint16_t AD0,AD1,AD2,AD3;
float Voltage;
int main(void)
{
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD2:");
	OLED_ShowString(4,1,"AD3:");
	while(1)
	{
		AD0 = AD_GetValue(ADC_Channel_0);
		AD1 = AD_GetValue(ADC_Channel_1);
		AD2 = AD_GetValue(ADC_Channel_2);
		AD3 = AD_GetValue(ADC_Channel_3);
		OLED_ShowNum(1,5,AD0,4);
		OLED_ShowNum(2,5,AD1,4);
		OLED_ShowNum(3,5,AD2,4);
		OLED_ShowNum(4,5,AD3,4);
		Delay_ms(100);
	}
}

第八节、DMA直接存储器存取

8.1 DMA简介

DMA(Direct Memory Access)直接存储器存取。

DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源。

12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)。

每个通道都支持软件触发和特定的硬件触发。一般来说,存储器到存储器之间的数据转运,使用软件触发;而外设到存储器的数据转运,使用硬件触发。

存储器映像:

DMA框图:

寄存器是一种特殊的存储器,一方面,CPU可以对寄存器进行读写,另一方面,寄存器的每一位背后都连接了一根导线,可以用于控制外设电路的状态。

上图中,DCode总线专门用于访问flash,而系统总线用于访问其他。

8.2 DMA的基本结构

DMA的基本结构图如下:

Flash:只读,不能对Flash进行写入操作。

传输计数器:指定总共需要转运多少次。

自动重装器:指定当传输计数器减为0时,是否要自动恢复到最初的值。

DMA进行转运,需要满足以下几个条件:

1、开关控制,DMA_Cmd必须使能。

2、传输寄存器必须大于0。

3、触发源必须有触发信号。

从上图可以看出,DMA初始化分为以下几个步骤:
1、RCC开启时钟。

2、调用DMA_Init函数,初始化DMA。

3、调用DMA_Cmd进行开关控制。

8.3 DMA请求

数据转运+DMA:

ADC扫描模式+DMA:

8.4 DMA相关库函数

DMA的相关库函数如下:

void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);//恢复缺省配置
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);//DMA初始化
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);//结构体初始化
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);//DMA使能
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);//DMA中断输出使能
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); //给传输寄存器写入数据
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);//返回传输寄存器的值
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);//获取标志位状态
void DMA_ClearFlag(uint32_t DMAy_FLAG);//清除标志位
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);//获取中断状态
void DMA_ClearITPendingBit(uint32_t DMAy_IT);//清除中断挂起位

8.5 代码实现DMA功能

DMA数据转运:

DMA.c:

#include "stm32f10x.h"                  // Device header

uint16_t MyDMA_Size;
void MyDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size)
{
	MyDMA_Size=Size;
	/*RCC开启时钟*/
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	/*初始化DMA*/
	DMA_InitTypeDef DMA_InitStructure;
	/*外设站点的起始地址、数据宽度、是否自增*/
	DMA_InitStructure.DMA_PeripheralBaseAddr=AddrA;
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;
	/*存储器站点的起始地址、数据宽度、是否自增*/
	DMA_InitStructure.DMA_MemoryBaseAddr=AddrB;
	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向
	DMA_InitStructure.DMA_BufferSize=Size;//缓冲区大小
	DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//传输模式
	DMA_InitStructure.DMA_M2M=DMA_M2M_Enable;//选择是否是存储器到存储器
	DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	/*使能DMA*/
	DMA_Cmd(DMA1_Channel1,DISABLE);
}

/*DMA传输函数*/
void MyDMA_Transfer(void)
{
	DMA_Cmd(DMA1_Channel1,DISABLE);//给DMA失能
	DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);//传输数据
	DMA_Cmd(DMA1_Channel1,ENABLE);//给DMA使能
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
	DMA_ClearFlag(DMA1_FLAG_TC1);
}

 main函数:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Delay.h"
#include "DMA.h"
uint8_t DataA[] = {0x01,0x02,0x03,0x04};
uint8_t DataB[] = {0,0,0,0};

int main(void)
{
	OLED_Init();
	MyDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);
	OLED_ShowString(1,1,"DataA:");
	OLED_ShowString(3,1,"DataB:");
	OLED_ShowHexNum(1,8,(uint32_t)DataA,8);
	OLED_ShowHexNum(3,8,(uint32_t)DataB,8);
	
	
	
	while(1)
	{
	DataA[0]++;
	DataA[1]++;
	DataA[2]++;
	DataA[3]++;
		
	OLED_ShowHexNum(2,1,DataA[0],2);
	OLED_ShowHexNum(2,4,DataA[1],2);
	OLED_ShowHexNum(2,7,DataA[2],2);
	OLED_ShowHexNum(2,10,DataA[3],2);
	
	OLED_ShowHexNum(4,1,DataB[0],2);
	OLED_ShowHexNum(4,4,DataB[1],2);
	OLED_ShowHexNum(4,7,DataB[2],2);
	OLED_ShowHexNum(4,10,DataB[3],2);
	Delay_ms(1000);
	MyDMA_Transfer();
	OLED_ShowHexNum(2,1,DataA[0],2);
	OLED_ShowHexNum(2,4,DataA[1],2);
	OLED_ShowHexNum(2,7,DataA[2],2);
	OLED_ShowHexNum(2,10,DataA[3],2);
	
	OLED_ShowHexNum(4,1,DataB[0],2);
	OLED_ShowHexNum(4,4,DataB[1],2);
	OLED_ShowHexNum(4,7,DataB[2],2);
	OLED_ShowHexNum(4,10,DataB[3],2);
	Delay_ms(1000);
	}
}


 DMA+AD多通道:

AD.c:

#include "stm32f10x.h"                  // Device header

uint16_t AD_Value[4];
void AD_Init(void)
{
	/*RCC开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟分频系数
	/*配置GPIO*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	/*配置扫描通道*/
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	/*结构体初始化ADC*/
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据对齐
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//ADC外部触发转换选择
	ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//连续转换模式
	ADC_InitStructure.ADC_ScanConvMode=ENABLE;//扫描转换模式
	ADC_InitStructure.ADC_NbrOfChannel=4;//通道数目
	ADC_Init(ADC1,&ADC_InitStructure);
	/*初始化DMA*/
	DMA_InitTypeDef DMA_InitStructure;
	/*外设站点的起始地址、数据宽度、是否自增*/
	DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)&ADC1->DR;
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
	/*存储器站点的起始地址、数据宽度、是否自增*/
	DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)AD_Value;
	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向
	DMA_InitStructure.DMA_BufferSize=4;//缓冲区大小
	DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//传输模式
	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//选择是否是存储器到存储器
	DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	/*使能DMA*/
	DMA_Cmd(DMA1_Channel1,ENABLE);
	/*开启ADC到DMA的输出*/
	ADC_DMACmd(ADC1,ENABLE);
	/*ADC使能*/
	ADC_Cmd(ADC1,ENABLE);
	/*对ADC进行校准*/
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1) == SET);
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发ADC转换
}



main函数:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Delay.h"
#include "AD.h"


int main(void)
{
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD2:");
	OLED_ShowString(4,1,"AD3:");
	while(1)
	{
		OLED_ShowNum(1,5,AD_Value[0],4);
		OLED_ShowNum(2,5,AD_Value[1],4);
		OLED_ShowNum(3,5,AD_Value[2],4);
		OLED_ShowNum(4,5,AD_Value[3],4);
		Delay_ms(100);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值