赞
踩
芯片:STM32F103R6
LCD:LM016L
运算放大器:LM358
PT100
芯片设置这里,选择你在keil里面编译的程序,注意在Keil里要勾选一下Create HEX File,频率那里要写50k,不然仿真的时候时间跳的很慢。
LCD部分的函数借鉴自LCD1602单片机(STC51/STM32)驱动程序详解,具体信息可移步至此观看。
- #ifndef __LCD1602_H
- #define __LCD1602_H
-
- /***************************根据自己的硬件引脚做修改*****************************/
- #define LCD_RS_Set() GPIO_SetBits( GPIOB, GPIO_Pin_12 )//1602的数据/指令选择控制线
- #define LCD_RS_Clr() GPIO_ResetBits( GPIOB, GPIO_Pin_12 )
-
- #define LCD_RW_Set() GPIO_SetBits( GPIOB, GPIO_Pin_13 )//1602的读写控制线
- #define LCD_RW_Clr() GPIO_ResetBits( GPIOB, GPIO_Pin_13 )
-
- #define LCD_EN_Set() GPIO_SetBits( GPIOB, GPIO_Pin_14 )//1602的使能控制线
- #define LCD_EN_Clr() GPIO_ResetBits( GPIOB, GPIO_Pin_14 )
-
- #define DATAOUT( x ) GPIO_Write( GPIOA, x ) //1602的8条数据控制线
-
- void GPIO_Configuration(void);
-
- void LCD1602_Init(void);
-
- void LCD1602_Wait_Ready(void);
-
- void LCD1602_Write_Cmd( u8 cmd );
-
- void LCD1602_Write_Dat( u8 data );
-
- void LCD1602_ClearScreen(void);
-
- void LCD1602_Set_Cursor( u8 x, u8 y );
-
- void LCD1602_Show_Str( u8 x, u8 y, u8 *str );
-
- #endif

- #include "stm32f10x.h" // Device header
- #include "Delay.h"
- #include "LCD1602.h"
- /******************************************************************************
- * 函数名称:void GPIO_Configuration() *
- * 函数功能:LCD1602引脚初始化 *
- * 输入参数:无 *
- * 返回值 :无 *
- * 其他说明: *
- ******************************************************************************/
- /*******************根据自己的硬件引脚做修改*****************************************/
- void GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择工作频率
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置工作模式
- GPIO_Init( GPIOB, &GPIO_InitStructure );
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
- GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置工作模式
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择工作频率
- GPIO_Init( GPIOA, &GPIO_InitStructure );
- }
-
- /******************************************************************************
- * 函数名称:void LCD1602_Init() *
- * 函数功能:LCD1602初始化 *
- * 输入参数:无 *
- * 返回值 :无 *
- * 其他说明: *
- ******************************************************************************/
- void LCD1602_Init(void)
- {
- GPIO_Configuration(); //初始化引脚
-
- LCD1602_Write_Cmd( 0x38 ); //显示模式设置
- Delay_ms( 5 );
- LCD1602_Write_Cmd( 0x0c ); //显示开及光标设置
- Delay_ms( 5 );
- LCD1602_Write_Cmd( 0x06 ); //显示光标移动位置
- Delay_ms( 5 );
- LCD1602_Write_Cmd( 0x01 ); //显示清屏
- Delay_ms( 5 );
- }
-
- /******************************************************************************
- * 函数名称:void LCD1602_Write_Cmd(u8 cmd) *
- * 函数功能:写命令函数 *
- * 输入参数: cmd 命令 *
- * 返回值 :无 *
- * 其他说明: *
- ******************************************************************************/
- void LCD1602_Write_Cmd( u8 cmd )
- {
- LCD_RS_Clr();
- LCD_RW_Clr();
- LCD_EN_Set();
-
- GPIO_Write( GPIOA, (GPIO_ReadOutputData( GPIOA ) & 0xff00) | cmd );//对电平的读取
-
- DATAOUT( cmd );
- Delay_ms( 5 );
- LCD_EN_Clr();
- }
-
- /******************************************************************************
- * 函数名称:void LCD1602_Write_Dat(u8 date) *
- * 函数功能:写数据函数 *
- * 输入参数: date 数据 *
- * 返回值 :无 *
- * 其他说明: *
- ******************************************************************************/
- void LCD1602_Write_Dat( u8 data )
- {
- LCD_RS_Set();
- LCD_RW_Clr();
- LCD_EN_Set();
-
- GPIO_Write( GPIOA, (GPIO_ReadOutputData( GPIOA ) & 0xff00) | data );//对电平的读取
-
- Delay_ms( 5 );
- LCD_EN_Clr();
- }
-
- /******************************************************************************
- * 函数名称:void LCD1602_ClearScreen() *
- * 函数功能:1602清屏函数 *
- * 输入参数:无 *
- * 返回值 :无 *
- * 其他说明: *
- ******************************************************************************/
- void LCD1602_ClearScreen(void)
- {
- LCD1602_Write_Cmd( 0x01 );
- }
-
- /******************************************************************************
- * 函数名称:void LCD1602_Set_Cursor(u8 x, u8 y) *
- * 函数功能:设置1602位置函数 *
- * 输入参数:x 横坐标 y 纵坐标 *
- * 返回值 :无 *
- * 其他说明: *
- ******************************************************************************/
- void LCD1602_Set_Cursor( u8 x, u8 y )
- {
- u8 addr;
-
- if ( y == 0 )
- addr = 0x00 + x;
- else
- addr = 0x40 + x;
- LCD1602_Write_Cmd( addr | 0x80 );
- }
-
- /******************************************************************************
- * 函数名称:void LCD1602_Show_Str( u8 x, u8 y, u8 *str ) *
- * 函数功能:指定位置显示字符串函数 *
- * 输入参数:x 横坐标 y 纵坐标 *str 字符串 *
- * 返回值 : 无 *
- * 其他说明: *
- ******************************************************************************/
- void LCD1602_Show_Str( u8 x, u8 y, u8 *str )
- {
- LCD1602_Set_Cursor( x, y );
- while ( *str != '\0' )
- {
- LCD1602_Write_Dat( *str++ );
- }
- }

AD处理模块搬运江科大自化协的教程,但是这里把校准函数屏蔽了,校准的第一个指令不返回RESET,一直没找到原因,屏蔽了好像也没什么影响
- #ifndef __AD_H
- #define __AD_H
-
- void AD_Init(void);
- uint16_t AD_GetValue(void);
-
- #endif
- #include "stm32f10x.h" // Device header
-
- void AD_Init(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
-
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72MHz/6
-
- 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(GPIOB,&GPIO_InitStructure);
-
- ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_55Cycles5);
-
- ADC_InitTypeDef ADC_InitStructure;
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_NbrOfChannel = 1;
- ADC_Init(ADC1,&ADC_InitStructure);
-
- ADC_Cmd(ADC1,ENABLE);
-
- //ADC_ResetCalibration(ADC2);
- //while (ADC_GetResetCalibrationStatus(ADC2));
- //ADC_StartCalibration(ADC2);
- //while (ADC_GetCalibrationStatus(ADC2));
-
-
-
- }
-
- uint16_t AD_GetValue(void)
- {
- ADC_SoftwareStartConvCmd(ADC1,ENABLE);
- while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
- return ADC_GetConversionValue(ADC1);
- }

因为PT100电阻随温度并非线性变化,这里采用插值法计算温度,本芯片ADC转换精度12位,即ADC输入端口0-5V电压转换为0-4095(2^12),程序中给出温度与0-4095的对应关系,本例只模拟0-100℃。
- #ifndef INTERPOLATION__H
- #define INTERPOLATION__H
-
- float calculateTemperature(float measuredVoltage);
-
- #endif
-
- // 定义温度-电压查表
- const float temperatureTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
- //const float voltageTable[] = {0.0656, 0.0686, 0.0717, 0.0751, 0.0788, 0.0828, 0.0871, 0.0918,
- // 0.0968, 0.1022, 0.1079, 0.1792, 0.2574, 0.3356, 0.4132, 0.4903,
- // 0.5668, 0.6427, 0.7181, 0.793};
- const float voltageTable[] = {54, 56, 59, 62, 65, 68, 71, 75, 79, 84, 88, 147, 211, 275, 338, 402, 464, 526, 588, 650};
-
- float calculateTemperature(float measuredVoltage)
- {
- int i;
- for (i = 0; i < sizeof(voltageTable)/sizeof(float); i++) {
- if (measuredVoltage <= voltageTable[i]) {
- break;
- }
- }
-
- if (i == 0) {
- return temperatureTable[0];
- } else if (i == sizeof(temperatureTable)/sizeof(float)) {
- return temperatureTable[sizeof(temperatureTable)/sizeof(float) - 1];
- } else {
- float voltage1 = voltageTable[i-1];
- float voltage2 = voltageTable[i];
- float temperature1 = temperatureTable[i-1];
- float temperature2 = temperatureTable[i];
- return temperature1 + (temperature2 - temperature1) * (measuredVoltage - voltage1) / (voltage2 - voltage1);
- }
- }

- #include "stm32f10x.h" // Device header
- #include "Delay.h"
- #include "LCD1602.h"
- #include "AD.h"
- #include "stdio.h"
- #include "Interpolation.h"
-
- u8 str[] = "Temp test!";
-
-
-
-
-
- int main(void)
- {
- char buf[16];
- uint16_t ADValue = 0;
- //float voltage = 0;
- float Temp;
-
- LCD1602_Init();
- AD_Init();
-
-
- while(1)
- {
- LCD1602_Show_Str(0,0,str); //(列,行)
- ADValue = AD_GetValue();
- Temp = (int16_t) calculateTemperature((float)ADValue);
- //voltage = (float) ADValue* (5.0/4096);
- //Temp = (350.0 /(2049.0 - 54.0)) *(float) ADValue - 9.47;
- sprintf((char *)buf,(const char *)"Temp:%5.1f%cC",Temp,0xdf);
- //sprintf(buf,"ADValue: %u",ADValue);
- LCD1602_Show_Str(0,1,(u8 *)buf);
-
- }
-
- }

本文是我在学习STM32阶段写的一个小Demo,,可能存在很多不完善的地方,欢迎各位交流指正!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。