4.2 主程序流程图
系统程序固化在STC12C5A60S2内部的flash存储器中,分为主程序和若干子程序。主程序的功能是系统初始化,管理和调用各个子程序。本设计的程序流程图如图11所示。
图11 程序流程图
4.3 AD采样程序块
本文设计的STC12C5A60S2片内AD程序如下: #include \
//--------------------------------------------------------------------- // 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 个时钟周期转换一次
15
//#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; ADC_RESL = 0;
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);//返回转换后的结果 }
//A/D 转换结果高8位 //A/D 转换结果低2位
4.4 液晶显示程序块
本文设计的1602液晶操作程序如下:
/***************************************************** 函 数 名:WriteDataLCD() 功 能:向1602写数据 说 明: 入口参数:WDLCD
16
返 回 值:无
*****************************************************/ void WriteDataLCD(unsigned char WDLCD) { }
/***************************************************** 函 数 名:WriteCommandLCD() 功 能:向1602写指令 说 明:
入口参数:WDLCD,BuysC 返 回 值:无
*****************************************************/
void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测 { }
/***************************************************** 函 数 名:ReadDataLCD() 功 能:从1602读数据
17
ReadStatusLCD(); //检测忙 LCD_Data = WDLCD; LCD_RS = 1; LCD_RW = 0;
LCD_E = 0; //若晶振速度太高可以在这后加小的延时 LCD_E = 0; LCD_E = 0; //延时 LCD_E = 1;
if (BuysC) ReadStatusLCD(); //根据需要检测忙 LCD_Data = WCLCD; LCD_RS = 0; LCD_RW = 0; LCD_E = 0; LCD_E = 0; LCD_E = 0; LCD_E = 1;
说 明: 入口参数:无 返 回 值:LCD_Data
*****************************************************/ unsigned char ReadDataLCD(void) { }
/***************************************************** 函 数 名:ReadStatusLCD() 功 能:读取1602状态
说 明:如果为忙,则一直等到非忙为止 入口参数:无 返 回 值:LCD_Data
*****************************************************/ unsigned char ReadStatusLCD(void) { }
18
LCD_RS = 1; LCD_RW = 1; LCD_E = 0; LCD_E = 0; LCD_E = 0; LCD_E = 1; return(LCD_Data);
LCD_Data = 0xFF; LCD_RS = 0; LCD_RW = 1; LCD_E = 0; LCD_E = 0; LCD_E = 0; LCD_E = 1;
delay_18B20(200);
//检测忙信号 proteus仿真时,延迟5MS,关闭while循环
//硬件使用时,不延迟,打开while循环
// Delay5Ms();
while (LCD_Data&Busy) return(LCD_Data);
/***************************************************** 函 数 名:LCDInit() 功 能:1602初始化 说 明: 入口参数:无 返 回 值:无
*****************************************************/ void LCDInit(void) { }
/***************************************************** 函 数 名: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
19
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); // 显示开及光标设置