用库函数模板编写一个stm32多通道采集电压用lcd1602显示的代码,分为主函数,.c和.h文件三个部分
时间: 2023-06-20 19:05:50 浏览: 87
基于stm32 的LCD1602驱动代码
以下是一个简单的示例代码,仅供参考:
主函数:
```
#include "stm32f10x.h"
#include "adc.h"
#include "delay.h"
#include "lcd1602.h"
int main(void)
{
// 初始化ADC和LCD1602
ADC_Init();
LCD1602_Init();
while(1)
{
// 读取ADC的值,并转换为电压值
float voltage1 = ADC_ReadVoltage(ADC_Channel_1);
float voltage2 = ADC_ReadVoltage(ADC_Channel_2);
// 在LCD1602上显示电压值
LCD1602_Clear();
LCD1602_WriteString("Channel 1:");
LCD1602_WriteFloat(voltage1, 2);
LCD1602_WriteString("V");
LCD1602_SetCursor(0, 1);
LCD1602_WriteString("Channel 2:");
LCD1602_WriteFloat(voltage2, 2);
LCD1602_WriteString("V");
// 延时一段时间
Delay_Ms(500);
}
}
```
adc.c 文件:
```
#include "adc.h"
void ADC_Init(void)
{
// 使能 ADC1 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// 初始化 ADC1
ADC_InitTypeDef ADC_InitStruct;
ADC_StructInit(&ADC_InitStruct);
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
ADC_InitStruct.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStruct);
// 配置 ADC1 的通道 1 和通道 2
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
// 使能 ADC1
ADC_Cmd(ADC1, ENABLE);
// 等待 ADC1 启动
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
}
float ADC_ReadVoltage(uint8_t channel)
{
// 选择 ADC1 的通道
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_55Cycles5);
// 启动 ADC1 的转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// 等待转换完成
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
// 读取 ADC1 的转换结果,并计算电压值
uint16_t adc_value = ADC_GetConversionValue(ADC1);
float voltage = (float)adc_value * 3.3 / 4096;
return voltage;
}
```
adc.h 文件:
```
#ifndef __ADC_H
#define __ADC_H
#include "stm32f10x.h"
void ADC_Init(void);
float ADC_ReadVoltage(uint8_t channel);
enum {
ADC_Channel_1 = 0,
ADC_Channel_2,
ADC_Channel_3,
ADC_Channel_4,
ADC_Channel_5,
ADC_Channel_6,
ADC_Channel_7,
ADC_Channel_8,
ADC_Channel_9,
ADC_Channel_10,
ADC_Channel_11,
ADC_Channel_12,
ADC_Channel_13,
ADC_Channel_14,
ADC_Channel_15,
ADC_Channel_16,
};
#endif /* __ADC_H */
```
lcd1602.c 文件:
```
#include "lcd1602.h"
#include "delay.h"
void LCD1602_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
// 使能 GPIOB 和 GPIOA 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE);
// 配置 PB8 和 PB9 为推挽输出,用于控制 LCD1602 的 RS 和 E 引脚
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置 PA0 ~ PA5 为推挽输出,用于控制 LCD1602 的 D4 ~ D7 引脚
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 初始化 LCD1602
LCD1602_WriteCommand(0x28);
LCD1602_WriteCommand(0x0C);
LCD1602_WriteCommand(0x06);
LCD1602_WriteCommand(0x01);
}
void LCD1602_WriteCommand(uint8_t command)
{
// 设置 RS 引脚为低电平,表示要写入命令
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
// 设置 E 引脚为高电平
GPIO_SetBits(GPIOB, GPIO_Pin_9);
// 写入高四位数据
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (command & 0x10) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, (command & 0x20) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (command & 0x40) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, (command & 0x80) ? Bit_SET : Bit_RESET);
// 设置 E 引脚为低电平
GPIO_ResetBits(GPIOB, GPIO_Pin_9);
// 延时一段时间
Delay_Us(2);
// 设置 E 引脚为高电平
GPIO_SetBits(GPIOB, GPIO_Pin_9);
// 写入低四位数据
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (command & 0x01) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, (command & 0x02) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (command & 0x04) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, (command & 0x08) ? Bit_SET : Bit_RESET);
// 设置 E 引脚为低电平
GPIO_ResetBits(GPIOB, GPIO_Pin_9);
// 延时一段时间
Delay_Us(2);
}
void LCD1602_WriteData(uint8_t data)
{
// 设置 RS 引脚为高电平,表示要写入数据
GPIO_SetBits(GPIOB, GPIO_Pin_8);
// 设置 E 引脚为高电平
GPIO_SetBits(GPIOB, GPIO_Pin_9);
// 写入高四位数据
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (data & 0x10) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, (data & 0x20) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (data & 0x40) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, (data & 0x80) ? Bit_SET : Bit_RESET);
// 设置 E 引脚为低电平
GPIO_ResetBits(GPIOB, GPIO_Pin_9);
// 延时一段时间
Delay_Us(2);
// 设置 E 引脚为高电平
GPIO_SetBits(GPIOB, GPIO_Pin_9);
// 写入低四位数据
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (data & 0x01) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, (data & 0x02) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (data & 0x04) ? Bit_SET : Bit_RESET);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, (data & 0x08) ? Bit_SET : Bit_RESET);
// 设置 E 引脚为低电平
GPIO_ResetBits(GPIOB, GPIO_Pin_9);
// 延时一段时间
Delay_Us(2);
}
void LCD1602_WriteString(char *str)
{
while(*str)
{
LCD1602_WriteData(*str++);
}
}
void LCD1602_WriteFloat(float value, uint8_t decimal)
{
int integer = (int)value;
LCD1602_WriteInteger(integer);
LCD1602_WriteData('.');
int decimal_part = (int)((value - integer) * pow(10, decimal));
LCD1602_WriteInteger(decimal_part);
}
void LCD1602_WriteInteger(int value)
{
char buffer[16];
sprintf(buffer, "%d", value);
LCD1602_WriteString(buffer);
}
void LCD1602_SetCursor(uint8_t col, uint8_t row)
{
uint8_t address;
switch(row)
{
case 0: address = 0x80 + col; break;
case 1: address = 0xC0 + col; break;
default: return;
}
LCD1602_WriteCommand(address);
}
void LCD1602_Clear(void)
{
LCD1602_WriteCommand(0x01);
}
```
lcd1602.h 文件:
```
#ifndef __LCD1602_H
#define __LCD1602_H
#include "stm32f10x.h"
#include <math.h>
#include <stdio.h>
void LCD1602_Init(void);
void LCD1602_WriteCommand(uint8_t command);
void LCD1602_WriteData(uint8_t data);
void LCD1602_WriteString(char *str);
void LCD1602_WriteFloat(float value, uint8_t decimal);
void LCD1602_WriteInteger(int value);
void LCD1602_SetCursor(uint8_t col, uint8_t row);
void LCD1602_Clear(void);
#endif /* __LCD1602_H */
```
阅读全文