基于STM32F103 的电压显示

 

 

运用STM32F103和LCD1602实现实时显示电压的功能

ADC运用的管脚是  PA(0)

下面是ADC的配置

#include "ADC.h"
void ADC_Init_MY(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_ADC1,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	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);//重置ADC校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1));//等待重置结束
	ADC_StartCalibration(ADC1);//开始校准ADC
	while(ADC_GetCalibrationStatus(ADC1));//等待校准结束

}

 

接下来我们配置LCD1602 

#include "LCD1602.h"
#include "delay.h"
void LCD1602_Init(void)
{
	// D0<--> B11
	// D1<--> B10
	// D2<--> B1
	// D3<--> B0
	// D4<--> A7
	// D5<--> A6
	// D6<--> A5
	// D7<--> A4
	
	// RS<-->A3
	// E<--> A2
	// RW<-->A1
	// V0<-->电阻接地
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);//开启PA和PB GPIO的 时钟
	
	//配置PA0~7为推挽式输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
																GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

//配置PB0 1 10 11为推挽式输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_10 |GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void LCD1602_Write_Cmd(unsigned char cmd)
{
	LCD_RS = 0;
	LCD_RW = 0;
	delay_ms(1);
	LCD_E = 1;

	LCD_D0 = cmd>>0;
	LCD_D1 = cmd>>1;
	LCD_D2 = cmd>>2;
	LCD_D3 = cmd>>3;
	LCD_D4 = cmd>>4;
	LCD_D5 = cmd>>5;
	LCD_D6 = cmd>>6;
	LCD_D7 = cmd>>7;
	delay_ms(1);
	LCD_E = 0;
	delay_ms(1);

}

void LCD1602_Write_Date(unsigned char date)
{
	LCD_RS = 1;
	LCD_RW = 0;
	delay_ms(1);
	LCD_E = 1;

	LCD_D0 = date>>0;
	LCD_D1 = date>>1;
	LCD_D2 = date>>2;
	LCD_D3 = date>>3;	
	LCD_D4 = date>>4;
	LCD_D5 = date>>5;
	LCD_D6 = date>>6;
	LCD_D7 = date>>7;

	delay_ms(1);
	LCD_E = 0;
	delay_ms(1);	
}

这里遇到的问题是E0管脚接电阻接地所接的电阻值的大小,这个阻值最好不大于5K不小于500R,太大了显示的内容太淡,阻值太小全是方块,看不清显示的内容,好像每一块1602的最佳阻值都不一样,最好使用电位器自己调试。

下面是我的主程序

#include "sys.h"
#include "ADC.h"
#include "usart.h"
#include "delay.h"
#include "LCD1602.h"
#include "string.h"
u16 ADC_BUF = 0;
u8 i = 0;
float v = 0;
unsigned char str_T[10] = {0};	

int main(void)
{
	delay_init();
	uart_init(115200);
	ADC_Init_MY();
	LCD1602_Init();
	
	LCD1602_Write_Cmd(0x38);//配置16*2显示,5*7点阵,8位数据接口
	LCD1602_Write_Cmd(0x0C);//设置开显示,不显示光标
	LCD1602_Write_Cmd(0x06);//写字符后地址自动加1
	LCD1602_Write_Cmd(0x01);//显示清0,数据指针清0 

	
	while(1)
	{
		/************ADC****************/
		ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
		ADC_SoftwareStartConvCmd(ADC1,ENABLE);
		while(!ADC_FLAG_EOC);
		ADC_BUF = ADC_GetConversionValue(ADC1);
		v = 3.3*ADC_BUF/4095;
		printf("Volt %fV\r\n",v);
		delay_ms(500);
		
		sprintf(str_T,"U:%fV",v);
	
		/*********LCD1602***********/
		LCD1602_Write_Cmd(0X80+0X00);//显示在第1行第一个
			for(i = 0;i<strlen(str_T);i++)
					{
					LCD1602_Write_Date(str_T[i]);
					}
	}
}

以上的程序测试过可以使用,下面附一张显示图,我的采样方式是将两个阻值一样的电阻分别接VCC和GND,从中间引出一根线接PA(0)

  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值