视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
压力传感器软件设计
2025-09-29 16:40:14 责编:小OO
文档
2软件设计

2.1 系统应用程序组成

本设计采用C语言编程,编译环境为keil UV3。

keil c51 是美国Keil Software 公司出品的51 系列兼容单片机C 语言软件开发系统,和汇编相比,C 在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。

Keil c51 软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows 界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到keil c51 生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。

Keil C51 可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE 本身或其它编辑器编辑C 或汇编源文件,然后分别有C51 及A51 编辑器编译连接生成单片机可执行的二进制文件(.HEX),然后通过单片机的烧写软件将HEX 文件烧入单片机内。

软件主要三个方面:一是初始化系统;二是按键检测;三是数据采集、数据处理并进行显示。这三个方面的操作分别在主程序中来进行。程序采用模块化的结构,这样程序结构清楚,易编程和易读性好,也便于调试和修改。程序结构如图10所示。

图10 程序结构

2.2 主程序流程图

系统程序固化在STC12C5A60S2内部的flash存储器中,分为主程序和若干子程序。主程序的功能是系统初始化,管理和调用各个子程序。本设计的程序流程图如图11所示。

图11 程序流程图

2.3 AD采样程序块

本文设计的STC12C5A60S2片内AD程序如下:

#include "config.h"

//---------------------------------------------------------------------

                        //            SPEED1 SPEED0  A/D转换所需时间

#define AD_SPEED   0x60 //  0110,0000   1      1   90 个时钟周期转换一次, 

                        //  CPU工作频率21MHz时 A/D转换速度约 300KHz

//#define AD_SPEED   0x40 //0100,0000   1      0     140 个时钟周期转换一次

//#define AD_SPEED   0x20 //0010,0000   0      1     280 个时钟周期转换一次

//#define AD_SPEED   0x00 //0000,0000   0      0     420 个时钟周期转换一次

//---------------------------------------------------------------------

unsigned int get_AD_result(unsigned char channel)

{

    unsigned char AD_finished=0;            //存储 A/D 转换标志

    ADC_RES = 0;          //A/D 转换结果高8位

    ADC_RESL = 0;          //A/D 转换结果低2位

    channel &= 0x07;                //0000,0111 清0高5位

    ADC_CONTR = AD_SPEED;

    _nop_();

    ADC_CONTR|=0xE0;    //1110,0000清ADC_FLAG,ADC_START位和低三位

    ADC_CONTR |= channel;           //选择 A/D 当前通道

    _nop_();

    ADC_CONTR |= 0x80;              //启动 A/D 电源

    delay(1);                       //使输入电压达到稳定

    ADC_CONTR |= 0x08;              //0000,1000 令 ADCS = 1, 启动A/D转换

    AD_finished = 0;

    while (AD_finished == 0 )        //等待A/D转换结束

    {

        AD_finished = (ADC_CONTR & 0x10); //0001,0000 测试A/D转换结束否

    }

    ADC_CONTR &= 0xE7;              //1111,0111 清 ADC_FLAG 位, 关闭A/D转换

return (ADC_RES<<2|ADC_RESL);//返回转换后的结果

}

2.4 液晶显示程序块

本文设计的1602液晶操作程序如下:

/***************************************************** 

 函 数 名:WriteDataLCD()

 功    能:向1602写数据

 说    明:

 入口参数:WDLCD

 返 回 值:无 

 *****************************************************/

void WriteDataLCD(unsigned char WDLCD)

{

    ReadStatusLCD(); //检测忙

    LCD_Data = WDLCD;

    LCD_RS = 1;

    LCD_RW = 0;

    LCD_E = 0; //若晶振速度太高可以在这后加小的延时

    LCD_E = 0;

    LCD_E = 0; //延时

    LCD_E = 1;

}

/***************************************************** 

 函 数 名:WriteCommandLCD()

 功    能:向1602写指令

 说    明:

 入口参数:WDLCD,BuysC

 返 回 值:无 

 *****************************************************/

void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测

{

    if (BuysC) ReadStatusLCD(); //根据需要检测忙

    LCD_Data = WCLCD;

    LCD_RS = 0;

    LCD_RW = 0; 

    LCD_E = 0;

    LCD_E = 0;

    LCD_E = 0;

    LCD_E = 1; 

}

/***************************************************** 

 函 数 名:ReadDataLCD()

 功    能:从1602读数据

 说    明:

 入口参数:无

 返 回 值:LCD_Data

 *****************************************************/

unsigned char ReadDataLCD(void)

{

    LCD_RS = 1; 

    LCD_RW = 1;

    LCD_E = 0;

    LCD_E = 0;

    LCD_E = 0;

    LCD_E = 1;

    return(LCD_Data);

}

/***************************************************** 

 函 数 名:ReadStatusLCD()

 功    能:读取1602状态

 说    明:如果为忙,则一直等到非忙为止

 入口参数:无

 返 回 值:LCD_Data

 *****************************************************/

unsigned char ReadStatusLCD(void)

{

    LCD_Data = 0xFF; 

    LCD_RS = 0;

    LCD_RW = 1;

    LCD_E = 0;

    LCD_E = 0;

    LCD_E = 0;

    LCD_E = 1;

    delay_18B20(200);     

//    Delay5Ms();              //检测忙信号  proteus仿真时,延迟5MS,关闭while循环

    while (LCD_Data&Busy)     //硬件使用时,不延迟,打开while循环

    return(LCD_Data);

}

/***************************************************** 

 函 数 名:LCDInit()

 功    能:1602初始化

 说    明:

 入口参数:无

 返 回 值:无

 *****************************************************/

void LCDInit(void)

{

    LCD_Data = 0;

    WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号

    Delay5Ms(); 

    WriteCommandLCD(0x38,0);

    Delay5Ms(); 

    WriteCommandLCD(0x38,0);

    Delay5Ms(); 

    

    WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号

    WriteCommandLCD(0x08,1); //关闭显示

    WriteCommandLCD(0x01,1); //显示清屏

    WriteCommandLCD(0x06,1); // 显示光标移动设置

    WriteCommandLCD(0x0C,1); // 显示开及光标设置

}

/***************************************************** 

 函 数 名:DisplayOneChar()

 功    能:按指定位置在1602显示一个字符

 说    明:X为列,Y为行,DData为字符

 入口参数:X,Y,DData

 返 回 值:无

 *****************************************************/

//按指定位置显示一个字符

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)

{

    Y &= 0x1;

    X &= 0xF; //X不能大于15,Y不能大于1

    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;

    X |= 0x80; //算出指令码

    WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码

    WriteDataLCD(DData);

}

/***************************************************** 

 函 数 名:DisplayListChar()

 功    能:按指定位置在1602显示一串字符

 说    明:X为列,Y为行,*DData为字符串

 入口参数:X,Y,DData

 返 回 值:无

 *****************************************************/

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)

{

    unsigned char ListLength;

    ListLength = 0;

    Y &= 0x1;

    X &= 0xF; //X不能大于15,Y不能大于1

    while (DData[ListLength]!='\\0') //若到达字串尾则退出

    {

     if (X <= 0xF) //X坐标应小于0xF

        {

            DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符

            ListLength++;

            X++;

        }

    }

}

/***************************************************** 

 函 数 名:Delay5Ms()

 功    能:5ms延时

 说    明:

 入口参数:无

 返 回 值:无

 *****************************************************/

void Delay5Ms(void)

{

    unsigned int TempCyc = 5552;

    while(TempCyc--);

}

/***************************************************** 

 函 数 名:Delay400Ms()

 功    能:400ms延时

 说    明:

 入口参数:无

 返 回 值:无

 *****************************************************/

void Delay400Ms(void)

{

    unsigned char TempCycA = 5;

    unsigned int TempCycB;

    while(TempCycA--)

    {

        TempCycB=7269;

        while(TempCycB--);

    }

}下载本文

显示全文
专题