准备:
例如:
- STM32F103RCT6
- TFT1.44寸液晶屏
- nRF24L01无线模块
项目需求概述:
- [😊 ] STM32标准库完成ADC1的6通道采集电压,对于6个GPIO引脚的电压值,转换数据后,显示3组数据到屏幕上
前言:
STM32F103电压采集范围0~3.3V,最终是需要计算转化得到实际值。
ADC精度是12bit,那么经过ADC转换后为一个12Bit的数字,要想看到实际的采集电压值,需要这么计算:
(1)ADC是12bit,采集范围0~3.3V,也就是2^12(4096)对应3.3
(2)实际电压=adc采集值*3.3/4096
代码:
主函数main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "tsensor.h"
#include "Lcd_Driver.h"
#include "GUI.h"
#include "nRF24L01_API.h"
#include "string.h"
int i;
u8 sta;
short temp;
float vol_arr[6];
u8 ADC_str1[NumMax];
u8 ADC_str2[NumMax];
u8 ADC_str3[NumMax];
u8 Temp_str1[NumMax];
u8 ADC_A0C0[NumMax];
u8 ADC_A1C1[NumMax];
u8 ADC_A2C2[NumMax];
u8 ADC_A3C3[NumMax];
u8 ADC_B0C8[NumMax];
u8 ADC_B1C9[NumMax];
u8 Power1[NumMax];
u8 Power2[NumMax];
u8 Power3[NumMax];
uint8_t Num_TXD=0;//发送缓冲区的字节数
uint8_t TX_Buffer[20]="----------------\r\n";
uint8_t TX_RF_Buffer[32];
uint8_t RX_RF_Buffer[32];
u8 *addresshead[9]={ADC_A0C0,ADC_A1C1,Power1,ADC_A2C2,ADC_A3C3,Power2,ADC_B0C8,ADC_B1C9,Power3};
int main(void){
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
uart_init(115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
Adc_Init(); //ADC初始化
Lcd_Init();
Lcd_Clear(GRAY0);
nRF24L01_GPIO_Init();//nRF24L01使用的 I/O 初始化
while(NRF24L01_Check())//检测不到24L01
{
Gui_DrawFont_GBK16(10,10,BLUE,GRAY0,"NRF Check Fail");
LED0=!LED0;
delay_ms(250);
}
Gui_DrawFont_GBK16(12,10,BLUE,GRAY0,"NRF Check Okay!");
nRF24L01_Init(); //初始化无线模块
Gui_DrawFont_GBK16(12,30,BLUE,GRAY0,"NRF Init Okay!");
delay_ms(3000);
Lcd_Clear(GRAY0);
while(1)
{
Get_Vol();
show();
for(i=0;i<9;i++){
strcat((char *)addresshead[i],"\r\n");//0x0d 0x0a
Num_TXD=strlen((char *)addresshead[i]);
memset(TX_RF_Buffer,0,sizeof(TX_RF_Buffer));
strcat((char *)&TX_RF_Buffer[1],(char *)addresshead[i]);
TX_RF_Buffer[0]=Num_TXD;//设置本包数据的长度
sta=RF_TXD(TX_RF_Buffer);//NRF24L01 最大一次发送32个字节
delay_ms(15);
}
}
}
ADC初始化:
void Adc_Init(void) //ADC通道初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOB , ENABLE ); //使能GPIOA,ADC1通道时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //分频因子6时钟为72M/6=12MHz
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1; //B0--->ADC_Channel_8 B1--->ADC_Channel_9
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//IRQ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //重置指定的ADC1的复位寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1重置校准寄存器的状态,设置状态则等待
ADC_StartCalibration(ADC1); //
while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
最终效果:
电脑无限模块接收串口助手显示:
完整项目附带资料下载百度网盘:https://pan.baidu.com/s/1_Tf_sgdpOk04iAlj_vG1YA?pwd=2023