STC12C5A60S2单片机实现AD采样并液晶显示(数字燃油表)

合集下载

基于STC12C5A60S2单片机中的AD采样实时采样用于检测电路是否正常的设计

基于STC12C5A60S2单片机中的AD采样实时采样用于检测电路是否正常的设计

基于STC12C5A60S2单片机中的AD采样实时采样用于检测电路是否正常的设计
 基于STC12C5A60S2单片机中的AD采样实时采样用于检测电路是否正常,利用NRF24L01与主机通信,主单片机用12864显示电路是否正常,若主电路出现故障,自动切换到备用电路,当主电路修复完成后,电路自动从备用电路切换到主电路,还可以通过按键自由切换电路。

 硬件设计
 图一系统框图
 整体结构如图1所示,包括控制模块,12864显示屏,按键,NRF24L01通信系统以及AD采样模块。

检测模块通过AD采样检测主电路是否完好,通过NRF24L01将检测的结果不断发送给主控模块,主控模块通过12864显示结果,如果主电路出现问题,自动切换到备用电路,可以通过按键自由切换电路。

 软件设计。

STC12C5A60(32)S2单片机AD采样-LCD1602液晶显示程序

STC12C5A60(32)S2单片机AD采样-LCD1602液晶显示程序

STC12C5A60(32)S2单片机AD采样-LCD1602液晶显示程序/******************************************************STC12C5A32S2或STC12C5A60S2等单片机ADC采样功能示例**1、P1口为8路10位AD转换口2、用LCD1602显示:数据口为P0,RW接P2.5,RS接P2.6,EN接P2.73、亲手编写、亲自调试,完全可行*****************************************************/#include#include#define uchar unsigned char#define uint unsigned intvoid delay_ms(uint x); //ms延时子函数/*****stc12c5a32s2相关的寄存器说明*****/sfr P1ASF = 0x9D; //P1口模数转换功能控制寄存器sfr ADC_CONTR = 0xBC; //AD转换控制寄存器sfr ADC_RES = 0xBD; //AD转换结果寄存器高位sfr ADC_RESL = 0xBE; //AD转换结果寄存器低位sfr AURX1 = 0xA2; //AD转换结果存储方式控制位/***P1ASF寄存器:8位,对应P1口8根线,用于指定那根线用作ADC功能******哪根线用作ADC就应置相应的位为1,注意:不能位寻址******/#define ADC_POWER 0x80 //ADC电源开#define ADC_SPEED 0x40 //设置为180个周期,ADC一次#define ADC_START 0x08 //ADC启动控制位设为开#define ADC_FLAG 0X10 //ADC结束标志位//***第n通道ADC初始化函数***//void ADC_int(uchar n){n &= 0x07; //确保是第0~7通道AURX1 |= 0x04; //转换结果存储方式:高2位放ADC_RES,低8位放ADC_RESL P1ASF = 1<<="">}//***第n通道ADC采样函数***//uint ADC_GET(uchar n){uint adc_data;n &= 0x07; //确保是第0~7通道ADC_RES = 0; //清存放结果存储器ADC_RESL = 0; //清存放结果存储器ADC_CONTR = 0; //AD转换控制寄存器清0,以便重置ADC_CONTR |= (ADC_POWER|ADC_SPEED|n|ADC_START);//打开AD转换电源,设定转换速度,设定通道号,AD转换开始_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//延时4个时钟周期左右while(!((ADC_CONTR & ADC_FLAG) == 0x10)) //等待转换结束adc_data = (ADC_RES & 0x03) * 256 + ADC_RESL; //转换结果计算ADC_CONTR &= 0xef; // 转换结束标志清0return adc_data; //adc_data的值(0~1023)}/***如果需要释放P1口为普通IO口,则需要本函数***//*void ADC_END(){P1ASF = 0;P1_CONTR = 0;}*//********延时子函数:xms********/void delay_ms(uint x){uint y;for(;x>0;x--)for(y=0;y<125;y++);}/*****以下是与LCD1602显示相关的定义和函数声明*****/#define lcd_data_port P0 //1602数据口接P0sbit lcd_rs = P2^6; //RS接P2.6(=0,是命令;=1,是数据)sbit lcd_rw = P2^5; //RW接P2.5(=0,是写;=1,是读)sbit lcd_en = P2^7; //EN接P2.7void lcd_write_com(uchar lcd_com); //写命令子函数void lcd_write_data(uchar lcd_data);//写数据子函数void lcd_int(); //1602初始化void lcd_locate(uchar x,uchar y); //显示定位(行,列)void lcd_4_char(uint data_4char); //显示4位整型函数/********写命令子函数********/void lcd_write_com(uchar lcd_com){lcd_data_port = lcd_com; //指令送到数据接口lcd_rs = 0; //选择命令lcd_rw = 0; //选择写lcd_en = 0;delay_ms(1);lcd_en = 1;delay_ms(1);lcd_en = 0;}/********写数据子函数********/void lcd_write_data(uchar lcd_data){lcd_data_port = lcd_data; //数据送到数据接口lcd_rs = 1; //选择数据lcd_rw = 0; //选择写lcd_en = 0;delay_ms(1);lcd_en = 1;delay_ms(1);lcd_en = 0;}/********LCD1602液晶初始化********/void lcd_int(){lcd_rs = 0; //选择命令lcd_rw = 0; //选择写lcd_en = 0;lcd_write_com(0x38); //设1602工作于16*2、5*7,8位数据接口模式lcd_write_com(0x0c); //开显示,不显示光标lcd_write_com(0x06); //写一个字符后,光标自动加一lcd_write_com(0x01); //清屏}/******显示定位子函数(行,列)******/void lcd_locate(uchar x,uchar y){uchar add;if(x == 1) add = 0x80;if(x == 2) add = 0x80+0x40;lcd_write_com(add+y-1);}/*********显示4位整数子函数********/void lcd_4_char(uint data_4_char){uchar lcd_table[4];lcd_table[1] = data_4_char / 1000; //获得千位lcd_table[2] = data_4_char % 1000 /100;//获得百位lcd_table[3] = data_4_char % 100 / 10; //获得十位lcd_table[4] = data_4_char % 10; //获得个位lcd_write_data(lcd_table[1] + 0x30); //显示千位lcd_write_data(lcd_table[2] + 0x30); //显示百位lcd_write_data(lcd_table[3] + 0x30); //显示十位lcd_write_data(lcd_table[4] + 0x30); //显示个位}/**************主函数***************/void main(){lcd_int(); //液晶初始化lcd_write_com(0x01); //液晶清屏while(1){uint ad_0 = 0;ADC_int(0); //ADC的通道0初始化ad_0 = ADC_GET(0); //AD转换处理后的数据存放于ad_0中lcd_locate(1,1); //显示在液晶的第1行,第1列lcd_4_char(ad_0); //显示4位整数delay_ms(20); //延时}}。

STC12C5A60S2AD采集12864显示程序

STC12C5A60S2AD采集12864显示程序

STC12C5A60S2AD采集12864显示程序/************************************************************** *************** 文件名:AD_CAIYANG.C* 功能:使用AD采集电压显示在LCD* 说明:本程序是STC12C5A60S2单片机自带AD的采集数据并通过12864液晶串行模式显示的程序*************************************************************** *************/#include//#include#define uint unsigned int#define uchar unsigned charsbit CS=P2^4; //LCD12864串行通信片选sbit SID=P2^5; //LCD12864串行通信数据口sbit SCLK=P2^6; //LCD12864串行通信同步时钟信号sbit PSB=P2^3; //LCD12864并/串选择:H并行 L串行sbit jd1=P2^0; //继电器1控制引脚sbit jd2=P2^1; //继电器2控制引脚sbit fengming=P2^7; //蜂鸣器控制引脚sbit start=P1^0; //开始信号控制引脚unsigned int temp1,sh1,ge1,n1,m1;unsigned char ad_result_data[10]; //AD转换高八位unsigned char ad_result_low2[10]; //AD转换低八位unsigned char ad_result_total[10]; //AD转换总十位unsigned char ad_average_result; //AD转换十次的平均值unsigned char Ain,Vin;unsigned char b,t,R;char tp=0;unsigned char code ma1[6]={0xb5,0xe7,0xd1,0xb9,0xa1,0xc3}; //电压:unsigned char code ma2[]={"."};uchar code disp1[]={" LG "};uchar code disp2[]={" 电压采集 "};uchar code disp3[]={"超级电容检测工装"};unsigned char code num0[]={0xa3,0xb0};unsigned char code num1[]={0xa3,0xb1};unsigned char code num2[]={0xa3,0xb2};unsigned char code num3[]={0xa3,0xb3};unsigned char code num4[]={0xa3,0xb4};unsigned char code num5[]={0xa3,0xb5};unsigned char code num6[]={0xa3,0xb6};unsigned char code num7[]={0xa3,0xb7};unsigned char code num8[]={0xa3,0xb8};unsigned char code num9[]={0xa3,0xb9};//-------模块延时程序---------------------------- 1msvoid delay1ms(uint delay1ms) //STC11F60XE,22.1184M,延时1ms{uint i,j;for(;delay1ms>0;delay1ms--)for(i=0;i<7;i++)for(j=0;j<210;j++);}void delay(uint delay) //STC11F60XE,22.1184M,延时170us{uint i,j;for(;delay>0;delay--)for(i=0;i<124;i++);for(j=0;j<124;j++);}/*******************************************************AD转换程序*******************************************************/void AD_initiate() //初始化函数{ES=0;TMOD=0x21; //定时计数器方式控制寄存器,"自动重装,16位计数器".SCON=0x50; //串行控制寄存器,方便在串口助手那观察TH1=0xfa;TL1=0xfa;TR1=1;}void ADC_Power_On() //AD转换电{ADC_CONTR|=0x80; //打开AD转换电源delay(5); //必要的延时延时一会儿等待AD供电电源稳定}void get_ad_result() //取AD结果函数,它是十位AD转换,每十次平均,最后取低八位作为AD采样数据{uint i,q=0;for(i=0;i<10;i++){tp=0;ADC_RES=0; //高八位数据清零,STC12C5A60S2 AD数据寄存名与STC12C54××系列不同ADC_RESL=0; //低两位清零ADC_CONTR|=0x08; //启动AD转换while(!tp) //判断AD转换是否完成{tp=0x10;tp&=ADC_CONTR;}ADC_CONTR&=0xe7;ad_average_result=ADC_RES;q=q+ad_average_result;}ad_average_result=q/10;//ad_average_result=ad_average_result*4*5000/1024;}/************************AD转换结束***********************/void send_ad_result() //取AD结果函数发送到串口,方便调试{SBUF=n1;while(TI==0) ;TI=0;delay1ms(100);//SBUF=R>>4;}//---------------------电压采样程序-------------------------void caiyangP10() //测电压{P1M0|=0x01; //设P1_0为开漏模式如: P1_0= #00000000B P1M1|=0x01;ADC_CONTR=0xe0; //设置P1.0为输入AD转换口delay(2);get_ad_result(); //取转换数据Vin=ad_average_result;// R=Vin;}/*-----------写控制字到LCD12864------------*/void write_cmd(uchar cmd){uchar i;uchar i_data;i_data=0xf8; //命令控制字:11111000写指令11111010写数据11111100读状态 11111110读数据CS=1; //片选置高,才能进行读写操作SCLK=0;/*----------写命令控制字-----------------*/for(i=0;i<8;i++) //循环八次,每次读取一位数据{SID=(bit)(i_data&0x80); //bit表示取其最高位SCLK=0;SCLK=1; //正跳变写入指令i_data=i_data<<1; //左移一位}/*---------------------------------------*//*----------写指令高四位-----------------*/i_data=cmd;i_data=i_data&0xf0; //把低四位置0for(i=0;i<8;i++) //循环八次,每次读取一位数据{SID=(bit)(i_data&0x80); //bit表示取其最高位SCLK=0;SCLK=1; //正跳变写入指令i_data=i_data<<1; //左移一位}/*---------------------------------------*//*----------写指令低四位-----------------*/i_data=cmd;i_data=i_data<<4; //左移四位,把低四位的数据移到高四位,再把低四位置0for(i=0;i<8;i++) //循环八次,每次读取一位数据{SID=(bit)(i_data&0x80); //bit表示取其最高位SCLK=0;SCLK=1; //正跳变写入指令i_data=i_data<<1; //左移一位}/*-----------------------------------------*/CS=0; //把片选置低delay1ms(5); //延时是因为没有进行忙检测,适当的延时可以不进行忙检测}/*-----------------------------------------*//*------------写数据到LCD12864-------------*/void write_dat(uchar dat){uchar i;uchar i_data;i_data=0xfa;CS=1;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=dat;i_data=i_data&0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=dat;i_data=i_data<<4;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;delay1ms(5);}/*-----------------------------------------*//*--------------显示坐标-------------------*/void lcd_pos(uchar x,uchar y) //汉字显示坐标,x为哪一行,y 为哪一列{uchar pos;if(x==0)x=0x80; //第一行else if(x==1)x=0x90; //第二行else if(x==2)x=0x88; //第三行else if(x==3)x=0x98; //第四行pos=x+y; //显示哪一行(总共有4行)哪一竖(总共有8竖,每16列为1竖)write_cmd(pos);}/*-----------------------------------------*//*--------------显示8个汉字-------------------*/void disp_hanzi(uchar code *chn){uchar i;write_cmd(0x30); //基本指令操作方式for(i=0;i<16;i++) //16列*8个汉字=128(刚好)write_dat(chn[i]);}/*-----------------------------------------*//*--------------显示数字-------------------*/void disp_num(uchar code *chn){uchar i;write_cmd(0x30); //基本指令操作方式for(i=0;i<2;i++) //1个数字write_dat(chn[i]);}void disp_number(uchar num){switch(num){case 0: disp_num(num0);break;case 1: disp_num(num1);break;case 2: disp_num(num2);break;case 3: disp_num(num3);break;case 4: disp_num(num4);break;case 5: disp_num(num5);break;case 6: disp_num(num6);break;case 7: disp_num(num7);break;case 8: disp_num(num8);break;case 9: disp_num(num9);break;default: break;}}/*----------- --LCD初始化------------------*/ void lcd_init(){PSB=0;write_cmd(0x30); //基本指令write_cmd(0x02); //地址归位write_cmd(0x06); //游标右移write_cmd(0x0c); //整体显示write_cmd(0x01); //清屏}/*-----------------------------------------*/ void displayP10(){float ad1;//unsigned int temp1,sh1,ge1,n1,m1;//uchar code dis2[]={0x01,0x02,0x00};//ad1=x*7.8125; //电压修正uchar i;// ad1=Vin*3.9608; //具体线性参数由输入电压值调整,该值的测量范围为0-10.00V,5V左右的测量比较准确,//两端的最大误差为70mv,其他一般在40mv以内ad1=Vin*2;temp1=(int)ad1;/* sh1=temp1/1000; //十位ge1=(temp1%1000)/100; //个位n1=((temp1%1000)%100)/10; //小数点后一位m1=((temp1%1000)%100)%10; //小数点后二位 */sh1=temp1/1000; //十位ge1=(temp1%1000)/100; //个位n1=(temp1%100)/10; //小数点后一位m1=temp1%10; //小数点后二位//write_cmd(0x01);write_cmd(0x30); //基本指令操作方式lcd_pos(0,0);for(i=0;i<6;i++)write_dat(ma1[i]);lcd_pos(0,3);disp_number(sh1);lcd_pos(0,4);disp_number(ge1);lcd_pos(0,5);for(i=0;i<2;i++) write_dat(ma2[i]);lcd_pos(0,6);disp_number(n1);lcd_pos(0,7);disp_number(m1);lcd_pos(1,0);disp_hanzi(disp1); lcd_pos(2,0);disp_hanzi(disp2);lcd_pos(3,0);disp_hanzi(disp3); delay1ms(5);}init ()start=1;jd1=0;jd2=0;fengming=0;}void main(){EA=1;AD_initiate(); //初始化ADC_Power_On(); //开AD电源init();lcd_init();delay(10);while(1){caiyangP10(); //测电压if(start==0){delay(10)if(start==0){if(Vin*2>1)jd1=1;else if(Vin*2<1)jd2=1;}send_ad_result(); //Vin=Vin*4007; displayP10(); delay(10);}}。

stc12c5a60s2 AD 程序

stc12c5a60s2  AD 程序
//AD速度设置。
#define ADC_SPEEDLL 0x00 //540 clocks
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define uchar unsigned char
#define uint unsigned int
/*LCD 各种端口的设置 */
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit LCD_PSB=P2^3;
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC开始标志位。
/*可写入 4*8 汉字,x的范围是1到4,y的范围是1到8*/
void lcd_string(uchar x,uchar y,char*str)
{
static uchar flag = 0;
uchar i = 0;
if(!flag)
{
lcd_init();
flag = 1;
case 3 : temp = 0x88;
break;
case 4 : temp = 0x98;
break;
default : temp = 0x80;
break;
}
pos = temp + col-1;
LCD_0(0,pos);
}
}
/*字符位置的选定*/

stc12c5a60s2_AD采集_12864串行显示终极程序_带滤波

stc12c5a60s2_AD采集_12864串行显示终极程序_带滤波

stc12c5a60s2 AD采集12864串行显示终极程序带滤波作者:电子工程师(天津)由于AD采集电压并在12864上显示的程序很常用,然而网上很多程序各种各样,又有很多缺点,所以就利用工作之余的时间对用到的程序进行了整理,调试,优化以方便各位电子爱好者使用。

这段程序已经调试通过,改下io即可直接应用。

最后有两张效果图。

LCD_PSB=0;(并串选择口)LCD_RST =1;(复位口)注意:本程序用的是12864串行显示,将PSB引脚接地,RST拉高、片选口RS接高之后除了电源和地线,只用2根线就可以显示了,接线很方便,最大程度的节省了io口。

本程序是以电流采集为例的,采集的是电流传感器输出的电压,然后转换成电流,如果只需要采集电压的话将转化为电流的语句删除即可。

AD是stc12c5a60s2 自带的10位AD。

使用很方便。

有不明白的可以qq联系我,1264136841#include"stc12c5a60s2.h"#include"intrins.h"float ADvalue = 0;unsigned int volage = 0;unsigned int current = 0;void InitializeDisplay();void InitializeLcd12864();void displaystring(unsigned char add,unsigned int num);void WriteCommandLcd12864(unsigned char temp);void InitializeDisplay();void InitializeAD();unsigned int ReadADvalue(unsigned char channel);float SmoothingFilter(unsigned int temp);void Delay_us(unsigned int xus);void Delay_ms(unsigned int xms);sbit LCD_SID = P2^5;//即RW口sbit LCD_CLK = P2^6;//即E口code unsigned char name1[] = {"escrewdriver"};code unsigned char name2[] = {"电流采集显示"};code unsigned char name3[] = {"电流: A "};code unsigned char name4[] = {"参数:mm "};"};void main(){// InitializeAD();// InitializeTimer0();// InitializeUart();InitializeLcd12864();InitializeDisplay();while(1){ADvalue = ReadADvalue(0); //读回AD值ADvalue = ADvalue*5000/1024; //转换成电压值/* if(ADvalue > 2500) //防止电压浮动在2.5V以上ADvalue = 2500;ADvalue = 2500-ADvalue; //电流反方向流过传感器,输出电压值小于2.5V,*/current = (ADvalue*8); //计算电流,每0.625V代表7.5A 即每1V代表12Acurrent = SmoothingFilter(current); //进行一下平滑滤波displaystring(0x8b,current);displaystring(0x9b,0.5*current);}}/*********************延时函数******************************/void Delay_us(unsigned int xus) //@11.0592MHz{while(xus-->0){_nop_();_nop_();_nop_();}}void Delay_ms(unsigned int xms) //@11.0592MHz{unsigned int y=0;for(;xms>0;xms--)for(y=0;y<600;y++);}/*******************延时函数*****************************//*******************************************************//********************lcd12864显示部分*******************//*******************************************************/void InitializeLcd12864()WriteCommandLcd12864(0x30);//基本功能WriteCommandLcd12864(0x0c);//显示开,光标关WriteCommandLcd12864(0x01);//清屏}void WriteByteLcd12864(unsigned char temp){unsigned char i;LCD_CLK = 0;for(i=0;i<8;i++){if(temp&0x80)LCD_SID = 1;elseLCD_SID = 0;LCD_CLK = 1;Delay_us(10);temp <<= 1;LCD_CLK = 0;Delay_us(10);}}void WriteCommandLcd12864(unsigned char temp){WriteByteLcd12864(0xf8);WriteByteLcd12864(temp&0xf0);WriteByteLcd12864(temp<<4);}void WriteDataLcd12864(unsigned char temp){WriteByteLcd12864(0xfa);WriteByteLcd12864(temp&0xf0);WriteByteLcd12864(temp<<4);}void WriteStringAddress(unsigned char add,unsigned char length,unsigned char *temp) {WriteCommandLcd12864(add);for(;length>0;length--){WriteDataLcd12864(*temp);temp++;}/***显示电压和电流***/void displaystring(unsigned char add,unsigned int num){unsigned char buf[10],i;buf[0] = num/10000;buf[1] = num%10000/1000;buf[2] = num%1000/100;buf[3] = num%100/10;buf[4] = num%10;WriteCommandLcd12864(add);for(i=0;i<5;i++){WriteDataLcd12864(buf[i]+0x30);if(i == 1) WriteDataLcd12864('.');}}/***显示内容初始化***/void InitializeDisplay(){WriteStringAddress(0x81,12,name1);WriteStringAddress(0x91,12,name2);WriteStringAddress(0x88,16,name3);WriteStringAddress(0x98,16,name4);Delay_ms(100);// WriteStringAddress(0x98,6,name5);}/********************lcd12864显示部分*******************/ /*******************************************************//*******************************************************/ /********************AD采集部分*************************/ /*******************************************************/ /***AD初始化***/void InitializeAD(){P1ASF=0xff ; //P1口全部作为模拟功能AD使用ADC_RES=0; //清零转换结果寄存器高8位ADC_RESL=0; //清零转换结果寄存器低2位ADC_CONTR=0x80;//开启AD电源Delay_ms(1); //等待1ms,让AD电源稳定}/***读对应通道AD值***/unsigned int ReadADvalue(unsigned char channel){ADC_CONTR=0x88|channel; //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0_nop_();_nop_();_nop_();_nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器while(!(ADC_CONTR&0x10)); //等待转换完成ADC_CONTR&=0xe7; //关闭AD转换,ADC_FLAG位由软件清0return(ADC_RES*4+ADC_RESL); //返回AD转换完成的10位数据(16进制)}/***实时平滑滤波***/float SmoothingFilter(unsigned int temp){static unsigned int i=0;static unsigned int buf[10];float average = 0;if(i>=10)i=0;buf[i++] = temp;average = (average+buf[0]+buf[1]+buf[2]+buf[3]+buf[4]+buf[5]+buf[6]+buf[7]+buf[8]+buf[9])/10;return average;}/*******************************************************//*******************************************************/。

STC12C5A60S2的1602液晶屏显示【

STC12C5A60S2的1602液晶屏显示【

#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit lcdrs=P2^7;sbit lcden=P2^6;uchar code stringtable[4]={'a','b','c','d'};void delay(uint z) //1ms延时子程序{uint x,y;for(x=z;x>0;x--){for(y=240;y>0;y--);}}void write_com(com) //1602lcd写命令子程序{lcdrs=0;delay(2);//为开启写入命令的时间>后面程序执行时间和延长时间之和才行。

P0=com;lcden=1;delay(2);lcden=0;}void write_data(date) //1602lcd写数据子程序{lcdrs=1;delay(2);P0=date;lcden=1;delay(2);lcden=0;}void lcd_init(){delay(15);//读取子程序所用大约时间write_com(0x38);write_com(0x0e);write_com(0x06);}void main() //先让内容显示出来,在让它整体移动。

{uchar number,k;lcd_init();//主程序中须先声明屏幕的显示设置就像未知数须先定义一样。

while(1){write_com(0x80+0x09);//要先写明显示的初始地址,才能写入数据。

上行显示for(number=0;number<4;number++){write_data(stringtable[number]);}delay(3000);write_com(0x01); //清屏delay(10);write_com(0x80+0x40+0x09);//要先写明显示的初始地址,才能写入数据。

STC12C5A60S2自带10位AD测量电压值LCD1602显示(C程序)教学文稿

STC12C5A60S2自带10位AD测量电压值LCD1602显示(C程序)教学文稿
void lcd_char_write(uint x_pos,y_pos,lcd_dat);//LCD1602字符写入
void lcd_bad_check();//LCD1602坏点检查
void Num_to_Disp(uchar i, uint Num);//显示数据处理
void LcdDisp(uchar j, uint num);//液晶显示函数
/*--************************芯片:【STC12C5A60S2】******************************--*/
/*--************************液晶:【LCD1602】***********************************--*/
sfr ADC_RESL = 0xBE; //ADC low 2-bit result register
sfr P1ASF = 0x9D; //P1口功能控制寄存器P1ASF
/************定义相应操作位***************/
#define ADC_POWER 0x80 //ADC电源控制位,0:关闭,1:打开
typedef unsigned char uchar;
typedef unsigned int uint;
#define _Nop() _nop_()
/*------------------------以下为LCD1602显示模块定义-----------------------*/
unsigned char data_char_table[]= {"0123456789ABCDEF"};//LCD数据
/*---------------------------------------------------------------------------------------------------------------------------*/

STC12C5A60S2的AD转换,PWM电压控制,液晶显示程序

STC12C5A60S2的AD转换,PWM电压控制,液晶显示程序

/*---------------------------------------------------------------------------------------------------------------------------*//*--************************功能【AD转换,PWM电压控制,液晶显示】**************************--*/ /*--************************芯片:【STC12C5A60S2】******************************--*//*--************************液晶:【LCD1602】***********************************--*//*--************************ADC管脚:【P1.7 】***************************--*//*--************************检测范围:【0.00~12.5V】***************************--*//*---------------------------------------------------------------------------------------------------------------------------*/#include "stc12c5a60s2.h"#include "intrins.h"#define uint unsigned int#define uchar unsigned char#define _Nop() _nop_()/*------------------------以下为LCD1602显示模块定义-----------------------*/unsigned char data_char_table[]= {"0123456789ABCDEF"}; //LCD数据unsigned char Lcd_Dis1_table[] = {"Setvalue: V"}; //第一行显示框架unsigned char pos_char_table[] = {" 9A.C0 "}; // 显示位置unsigned char Lcd_Dis2_table[] = {"V oltage : V"}; //第二行显示框架unsigned char num_char_table[] = {" 9A.CD V"}; // 显示位置float show;float NUM;static uchar ldata=50; //作为显示的数据sbit lcd_rs_port = P2^0; //定义LCD控制端口,根据硬件调整sbit lcd_rw_port = P2^1;sbit lcd_en_port = P2^2;#define lcd_data_port P0sbit key1 = P3^7; //定义按键1sbit key2 = P3^6; //定义按键2sbit key3 = P3^5; //定义按键3sbit key4 = P3^4; //定义按键4sbit key5 = P3^3; //定义按键5sbit key6 = P3^2; //定义按键6/************定义相应操作位***************/#define ADC_POWER 0x80 //ADC电源控制位,0:关闭,1:打开#define ADC_FLAG 0x10 //ADC结束标志位#define ADC_START 0x08 //ADC启动控制位#define ADC_SPEEDLL 0x00 //540 clocks___________选择转换速度/*------------------------以下为相关函数声明------------------------------*/void InitADC(); //ADC初始化uint GetADCResult(uchar ch);void Delay(uint n); //延时程序void delay_1ms(uchar x);void lcd_delay(uchar ms); //LCD1602 延时void lcd_busy_wait(); //LCD1602 忙等待void lcd_command_write(uint command); //LCD1602 命令字写入void lcd_system_reset(); //LCD1602 初始化void lcd_char_write(uint x_pos,y_pos,lcd_dat); //LCD1602 字符写入void lcd_bad_check(); //LCD1602 坏点检查void Num_to_Disp(uint i, uint Num); //显示数据处理void LcdDisp(uint j, uint num); //液晶显示函数void DelayMs(uchar ms);void init_PWM();void PWM1_change(uchar type,uchar change);void PWM1_set(uchar empty);/*-------------------------------- ADC 取值------------------------------*/uint GetADCResult(uchar ch){ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;_nop_(); //Must wait before inquiry_nop_();_nop_();_nop_();while (!(ADC_CONTR & ADC_FLAG)); //Wait complete flagADC_CONTR &= ADC_FLAG; //Close ADCreturn (ADC_RES*4 + ADC_RESL); //Return ADC result}/*---------------------------- 初始化ADC特殊功能寄存器-------------------*/void InitADC( ){P1ASF = 0x80; //Set P1.7 as input portADC_RES = 0; //Clear previous resultADC_RESL = 0;ADC_CONTR = ADC_POWER | ADC_SPEEDLL ;Delay(20); //ADC power-on delay and Start A/D conversion}/*---------------------------- LCD1602相应函数---------------------------*////////////////以下为LCD显示数据处理/////////////////void Num_to_Disp(uint i, uint Num){int xx, yy, zz;NUM = (Num * 4.68/ 1024.0); //计算公式:10-bit A/D Conversion Result = 1024 x (Vin / Vcc) NUM =NUM *29.1/9.9;xx = (int)NUM;yy = (int)((NUM - (float)(xx)) * 10);zz = (int)((NUM - (float)(xx)) * 100)%10;/********************第一行数字*******************************/pos_char_table[9]= data_char_table[i/100]; //输入值十位pos_char_table[10]= data_char_table[i%100/10]; //输入值个位pos_char_table[12]= data_char_table[i%10]; //输入值小数点后一位/********************第二行数字*******************************/num_char_table[9] = data_char_table[xx / 10]; //电压值十位num_char_table[10]= data_char_table[xx % 10]; //电压值个位num_char_table[12]= data_char_table[yy]; //电压值小数点后一位num_char_table[13]= data_char_table[zz]; //电压值小数点后两位}//////////////////以下为LCD显示////////////////////void LcdDisp(uint j, uint num){uint i=0;for (i=0;i<16;i++){lcd_char_write(i,0,Lcd_Dis1_table[i]);lcd_char_write(i,1,Lcd_Dis2_table[i]); //显示框架(固定文字)}Num_to_Disp(j, num);for(i = 9; i < 14; i++){lcd_char_write(i,0,pos_char_table[i]); //显示输入值}for(i = 9; i < 14; i++){lcd_char_write(i,1,num_char_table[i]); //显示电压}delay_1ms(100);}//////////////以下是LCD1602驱动程序////////////////void lcd_delay(uchar ms) /*LCD1602 延时*/{uchar j;while(ms--){for(j=0;j<250;j++){;}}}void lcd_busy_wait() /*LCD1602 忙等待*/{lcd_rs_port = 0;lcd_rw_port = 1;lcd_en_port = 1;lcd_data_port = 0xff;while (lcd_data_port&0x80);lcd_en_port = 0;}void lcd_command_write(uint command) /*LCD1602 命令字写入*/ {lcd_busy_wait();lcd_rs_port = 0;lcd_rw_port = 0;lcd_en_port = 0;lcd_data_port = command;lcd_en_port = 1;lcd_en_port = 0;}void lcd_system_reset() /*LCD1602 初始化*/{lcd_delay(20);lcd_command_write(0x38);lcd_delay(100);lcd_command_write(0x38);lcd_delay(50);lcd_command_write(0x38);lcd_delay(10);lcd_command_write(0x08);lcd_command_write(0x01);lcd_command_write(0x06);lcd_command_write(0x0c);}void lcd_char_write(uint x_pos,y_pos,lcd_dat) /*LCD1602 字符写入*/ {x_pos &= 0x0f; /* X位置范围0~15 */y_pos &= 0x01; /* Y位置范围0~ 1 */if(y_pos==1) x_pos += 0x40;x_pos += 0x80;lcd_command_write(x_pos);lcd_busy_wait();lcd_rs_port = 1;lcd_rw_port = 0;lcd_en_port = 0;lcd_data_port = lcd_dat;lcd_en_port = 1;lcd_en_port = 0;}void lcd_bad_check() /*LCD1602 坏点检查*/{char i,j;for(i=0;i<2;i++){for(j=0;j<16;j++) {lcd_char_write(j,i,0xff);}}lcd_delay(200);lcd_delay(200);lcd_delay(200);lcd_delay(100);lcd_delay(200);lcd_command_write(0x01); /* clear lcd disp */}//////////////////以上是LCD1602驱动程序/////////////////*----------------------------- 延时程序---------------------------*/ void Delay(uint n){uint x;while (n--){x = 500;while (x--);}}/*1MS为单位的延时程序*/void delay_1ms(uchar x){uchar j;while(x--){for(j=0;j<125;j++){;}}}void DelayMs(uchar ms) //延时程序{uint i;while(ms--){for(i = 0; i < 850; i++);}}void init_PWM(){CCON=0X00;CH=0;CL=0;CMOD=0X02; //0X00:以系统时钟/12 为时钟源,0X02:系统时钟/2,0x08:系统时钟PWM1_set(0X80);//起始占空比,0XC0:占空比为25%,0X80:占空比为50%,0X40:占空比为75% CCAPM1=0X42; //0X42:8位PWM P1.4输出,无中断;0X53:8位PWM输出,下降沿产生中断;0X63:上升沿产生中断;0X73:跳变沿产生中断CR=1; //计时器开始工作}void PWM1_set(uchar empty) //直接设置占空比{CCAP1L=empty;CCAP1H=empty;}void PWM1_change(uchar type,uchar change) //type=0减占空比,1增加占空比change: 0X0C约5%,0X05约2%{if(type==0){CCAP1L+=change;CCAP1H+=change;}else{CCAP1L-=change;CCAP1H-=change;}}void main(){init_PWM(); //初始化,PWM输出lcd_system_reset(); //LCD1602 初始化lcd_bad_check(); //LCD1602 坏点检查InitADC(); //初始化ADC特殊功能寄存器while(1) //按键增减PWM占空比{if(key1==0) //按键1按下{DelayMs(1); //按键消抖while(key1==0); //按键释放才跳出执行下一步ldata++; //显示数据加0.1}else if(key2==0) //按键2按下{DelayMs(1); //按键消抖while(key2==0); //按键释放才跳出执行下一步ldata--; //显示数据减0.1}else if(key3==0) //按键3按下{DelayMs(1); //按键消抖while(key3==0); //按键释放才跳出执行下一步ldata+=10; //显示数据加1}else if(key4==0) //按键4按下{DelayMs(1); //按键消抖while(key4==0); //按键释放才跳出执行下一步ldata-=10; //显示数据减1}else if(key5==0) //按键5按下{DelayMs(1); //按键消抖while(key5==0); //按键释放才跳出执行下一步ldata=0; //清0}LcdDisp(ldata,GetADCResult(7)); //液晶1602显示输入电压值和AD采集电压值(P1.7)NUM=10*NUM;show=ldata;if((NUM<(show-0.1))||(NUM>(show+0.1))){if(NUM<(show-0.1)){if((show-0.1)-NUM>1)PWM1_change(1,0X05);elsePWM1_change(1,0X01);}else{if(NUM-(show+0.1)>1)PWM1_change(0,0X05);elsePWM1_change(0,0X01);}Delay(500);}else{Delay(2000);}}}。

STC12C5A60S2两路AD采集用LCD1602显示

STC12C5A60S2两路AD采集用LCD1602显示

STC12C5A60S2两路AD采集用LCD1602显示#include#include#include "stdio.h"#define ulong unsigned long#define uint unsigned int#define uchar unsigned charuchar data adc _at_ 0x30;uchar data adc1 _at_ 0x31;sbit E=P2^7; //1602使能引脚sbit RW=P2^6; //1602读写引脚sbit RS=P2^5; //1602数据/命令选择引脚void SendByte(unsigned char dat);void SendStr(unsigned char *s);void L1602_string(uchar hang,uchar lie,uchar *p);void L1602_char(uchar hang,uchar lie,char sign);uchar AD();uchar AD1();void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}void delay(){_nop_();_nop_();}void Delay(uint del){uint i,j;for(i=0;i<del;i++)< p="">for(j=0;j<=148;j++){}}/************************************************************** ******* 名称: bit Busy(void)* 功能: 这个是一个读状态函数,读出函数是否处在忙状态* 输入: 输入的命令值* 输出: 无*************************************************************** ********/ void Busy(void){bit busy_flag = 1;P0 = 0xff;RS = 0;delay();RW = 1;delay();E = 1;//Delay(1);while(1){busy_flag = (bit)(P0 & 0x80);if(busy_flag == 0){break;}}E = 0;}/************************************************************** ******* 名称: wcmd(uchar del)* 功能: 1602命令函数* 输入: 输入的命令值* 输出: 无*************************************************************** ********/ void wcmd(uchar del){RS = 0;delay();RW = 0;delay();E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/************************************************************** ******* 名称: wdata(uchar del)* 功能: 1602写数据函数* 输入: 需要写入1602的数据* 输出: 无*************************************************************** ********/void wdata(uchar del){delay();RS = 1;delay();RW = 0;delay();E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/************************************************************** ******* 名称: L1602_init()* 功能: 1602初始化,请参考1602的资料* 输入: 无* 输出: 无*************************************************************** ********/ void L1602_init(void){Delay(15);wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);wcmd(0x38);Busy();wcmd(0x08);Busy();wcmd(0x01);Busy();wcmd(0x06);Busy();wcmd(0x0c);}/************************************************************** ******* 名称: L1602_char(uchar hang,uchar lie,char sign)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下L1602_char(1,5,'b')* 输入: 行,列,需要输入1602的数据* 输出: 无*************************************************************** ********/void L1602_char(uchar hang,uchar lie,char sign){uchar a;if(hang == 1){a = 0x80;}if(hang == 2){a = 0xc0;}a = a + lie - 1;Busy();wcmd(a);Busy();wdata(sign);}/************************************************************** ******* 名称: L1602_string(uchar hang,uchar lie,uchar *p)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下L1602_string(1,5,"ab cd ef;")* 输入: 行,列,需要输入1602的数据* 输出: 无*************************************************************** ********/ void L1602_string(uchar hang,uchar lie,uchar *p) {uchar a;if(hang == 1){a = 0x80;}if(hang == 2){a = 0xc0;}a = a + lie - 1;while(1){Busy();wcmd(a);Busy();wdata(*p);a++;p++;if((*p == '\0')||(a==0x90)||(a==0xd0)){break;}}}uchar AD(){ulong i;uchar star;ADC_CONTR|=0x80;for(i=0;i<10000;i++);P1ASF=0x01;ADC_CONTR|=0XE1;for(i=0;i<10000;i++); while(1){ADC_CONTR|=0x08; star=0;while(star==0){star=ADC_CONTR&0x10; }ADC_CONTR&=0x00; adc=ADC_RES;//adc<<=2;//adc+=ADC_RESL; return adc;}}uchar AD1(){ulong i;uchar star;ADC_CONTR|=0x80;for(i=0;i<10000;i++);P1ASF=0;ADC_CONTR|=0XE0;for(i=0;i<10000;i++);while(1){ADC_CONTR|=0x08;star=0;while(star==0){star=ADC_CONTR&0x10; }ADC_CONTR&=0x00;adc1=ADC_RES;// adc1<<=2;// adc1+=ADC_RESL; return adc1;}}void main(){float i,j;unsigned char a[16]; unsigned char b[16];L1602_init();while(1){{i=AD()*5/256;sprintf(a," DA1=%4.2f v",i); L1602_string(2,0,a); DelayMs(1);j=AD1()*5/256;sprintf(b," DC2=%4.2f v",j);L1602_string(1,0,b); }}}</del;i++)<>。

STC12C5A60S2单片机实现AD采样并液晶显示

STC12C5A60S2单片机实现AD采样并液晶显示

rw=0; lcden=0; delay(10); lcden=1; delay(10); lcden=0; } void LCD_init() //液晶显示初始化 { write_com(0x38); _nop_(); write_com(0x0f); _nop_(); write_com(0x06); _nop_(); write_com(0x01); _nop_(); } void channel1() //采集通道1函数 { uchar num1; AD_init1(); for(i=20;i>0;i--) { AD_sample(); ver1+=AD_sample(); } ver1=ver1/22; write_com(0X80); display(ver1); if(ver1>3) num1--; else if(ver1<3) num1++; if(num1==1||num1==7) num1=4; } void channel2() //采集通道2函数 { uchar num2; AD_init2(); for(j=20;j>0;j--) { AD_sample();
uint a,b; for(a=x;a>0;a--) for(b=200;b>0;b--); } void AD_init1() //通道1初始化 { P1M0|=0x10; P1M1|=0x10; P1ASF=0x10; ADC_RES=0; ADC_RESL=0; ADC_CONTR=0xEC; _nop_(); _nop_(); _nop_(); _nop_(); }
TH1=(65536-5)/256; TL1=(6-5)%256; a++; pwm(); } 头文件 stc12c5a60s2.h 可以到官网下载。

STC12C5A60S2单片机实现AD采样并液晶显示(数字燃油表)

STC12C5A60S2单片机实现AD采样并液晶显示(数字燃油表)

数字燃油表模拟电路设计可实现以下功能:1、推动滑动变阻器,能使LCD从0显示到1002、档显示数字低于10时,灯亮,LCD显示“oil low”以下为C程序:#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define Delay4us(){_nop_();_nop_();_nop_();_nop_();}sbit LED=P1^0;sbit LCD_RS=P2^6;sbit LCD_RW=P2^5;sbit LCD_EN=P2^7;sbit SCL=P2^0; //I2C时钟引脚sbit SDA=P2^1; //I2C数据输入输出引脚uchar Recv_Buffer[4]; //数据接收缓冲uint Voltage[]={'0','0','0','0'}; //数据分解为电压x.xxbit bdata IIC_ERROR; //I2C错误标志位uchar LCD_Line_1[]={" "};//延时void delay(int ms){uchar i;while(ms--) for(i=0;i<250;i++) Delay4us();}//LCD忙检测bit LCD_Busy_Check(){bit Result;LCD_RS=0;LCD_RW=1;LCD_EN=1;Delay4us();Result=(bit)(P0&0x80);LCD_EN=0;return Result;}//写指令void LCD_Write_Command(uchar cmd){while(LCD_Busy_Check());LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();P0=cmd;Delay4us();LCD_EN=1;Delay4us();LCD_EN=0;}// 写数据void LCD_Write_Data(uchar dat){while(LCD_Busy_Check());LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;Delay4us();LCD_EN=1;Delay4us();LCD_EN=0;}//初始化void LCD_Initialise(){LCD_Write_Command(0x38);delay(5);LCD_Write_Command(0x0c);delay(5);LCD_Write_Command(0x06);delay(5);LCD_Write_Command(0x01);delay(5);}//设置显示位置void LCD_Set_Position(uchar pos){LCD_Write_Command(pos|0x80);}//显示一行void LCD_Display_A_Line(uchar Line_Addr,uchar s[]){uchar i;LCD_Set_Position(Line_Addr);for(i=0;i<16;i++)LCD_Write_Data(s[i]);}// 将模数转换后得到的值分解存入缓存void Convert_To_Voltage(uchar val){uchar Tmp; //最大值为255,对应100L,255/100=2.55 val=val*0.393;Voltage[2]=val/100+'0'; //Tmp=val%100; //Voltage[1]=Tmp/10+'0';Tmp=Tmp%10;Voltage[0]=Tmp+'0';}//启动I2C总线void IIC_Start(){SDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;}//停止I2C总线void IIC_Stop(){SDA=0;SCL=1;Delay4us();SDA=1; Delay4us();SCL=0;}// 从机发送应答位void Slave_ACK(){SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;}// 从机发送非应答位void Slave_NOACK(){SDA=1;SCL=1;Delay4us();SCL=0;SDA=0;//发送一字节void IIC_SendByte(uchar wd){uchar i;for(i=0;i<8;i++) //循环移入8位{SDA=(bit)(wd&0x80);_nop_();_nop_();SCL=1;Delay4us();SCL=0;wd<<=1;}Delay4us();SDA=1; //释放总线并准备读取应答SCL=1;Delay4us();IIC_ERROR=SDA; //IIC_ERROR=1表示无应答SCL=0;Delay4us();}//接收一字节uchar IIC_ReceiveByte(){uchar i,rd=0x00;for(i=0;i<8;i++){SCL=1;rd<<=1;rd|=SDA;Delay4us();SCL=0;Delay4us();}SCL=0;Delay4us();return rd;}//连续读入4路通道的A/D转换结果并保存到Recv_Buffervoid ADC_PCF8591(uchar CtrlByte){uchar i;IIC_Start();IIC_SendByte(0x90); // 发送写地址if(IIC_ERROR==1)return;// IIC_SendByte(CtrlByte); //发送控制字节//if(IIC_ERROR==1)return;IIC_Start(); //重新发送开始命令IIC_SendByte(0x91); // 发送读地址if(IIC_ERROR==1)return;IIC_ReceiveByte(); //空读一次,调整读顺序Slave_ACK(); //收到一字节后发送一个应答位for(i=0;i<4;i++)Recv_Buffer[i++]=IIC_ReceiveByte();Slave_ACK(); //收到一个字节后发送一个应答位}Slave_NOACK();IIC_Stop(); //收到一个字节后发送一个非应答位}// 向PCF8591发送1字节进行AD转换//主程序void main(){LED=0;LCD_Initialise();while(1){ADC_PCF8591(0x04);if(Recv_Buffer[0]<26){LCD_Display_A_Line(0x00, "Oil Low! ");LED=1;}else{Convert_To_Voltage(Recv_Buffer[0]);LCD_Line_1[2]=Voltage[2];LCD_Line_1[3]=Voltage[1];LCD_Line_1[4]=Voltage[0];LCD_Display_A_Line(0x00, LCD_Line_1);LED=0;}delay(50);}}如有侵权请联系告知删除,感谢你们的配合!。

STC12C5A60S2单片机实现AD采样并液晶显示

STC12C5A60S2单片机实现AD采样并液晶显示

STC12C5A60S2单片机实现AD采样并液晶显示STC12C5A60S2是一款高性能、低功耗的8051内核单片机。

以下是一种基于该单片机进行AD采样并液晶显示的实现方案。

请注意,由于字数限制,以下内容是基本的框架和步骤,具体细节还需要根据具体需求进行调整。

1.准备材料和设备:-STC12C5A60S2单片机主控板-16x2液晶显示屏-AD转换器(例如MCP3008)-电压传感器模块-连接线、电阻、电容等2.连接硬件:-将液晶显示屏的VCC、GND和信号线(如RS、R/W、EN、D0-D7等)连接到STC12C5A60S2单片机对应的引脚。

-将AD转换器的VCC、GND和信号线(如CLK、DOUT、DIN、CS等)连接到STC12C5A60S2单片机对应的引脚。

-将电压传感器模块的输出引脚连接到AD转换器的输入引脚。

3.编写代码:-使用C语言编写STC12C5A60S2单片机的代码,包括初始化设置、AD 采样、数据处理和液晶显示等部分。

-在初始化设置中,设置AD转换器的引脚和时钟,配置液晶显示屏的引脚和参数。

-在AD采样部分,通过SPI通信协议与AD转换器进行通信,获取电压传感器模块的输出电压值。

-在数据处理部分,将采样到的原始数据经过相应的处理,如校正、换算等。

-在液晶显示部分,将处理后的数据显示到液晶屏上,并通过适当的界面设计和显示格式展示结果。

4.烧录程序:-使用相应的编程工具将编写好的代码烧录到STC12C5A60S2单片机。

-确保烧录成功,并断开编程工具的连接。

5.调试测试:-连接好硬件后,给电压传感器模块供电,确保电压输入正常。

-上电运行STC12C5A60S2单片机,液晶显示屏应显示出AD采样后的结果。

-对不同的输入电压进行测试,观察液晶屏上的显示结果是否与实际输入电压相符。

请注意,以上仅是基本的框架和步骤,实际应用中还需要根据具体需求和应用场景进行相应的优化和调整。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数字燃油表模拟电路设计可实现以下功能:
1、推动滑动变阻器,能使LCD从0显示到100
2、档显示数字低于10时,灯亮,LCD显示“oil low”
以下为C程序:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define Delay4us(){_nop_();_nop_();_nop_();_nop_();}
sbit LED=P1^0;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
sbit SCL=P2^0; //I2C时钟引脚
sbit SDA=P2^1; //I2C数据输入输出引脚uchar Recv_Buffer[4]; //数据接收缓冲
uint Voltage[]={'0','0','0','0'}; //数据分解为电压x.xx
bit bdata IIC_ERROR; //I2C错误标志位
uchar LCD_Line_1[]={" "};
//延时
void delay(int ms)
{
uchar i;
while(ms--) for(i=0;i<250;i++) Delay4us();
}
//LCD忙检测
bit LCD_Busy_Check()
{
bit Result;
LCD_RS=0;LCD_RW=1;
LCD_EN=1;Delay4us();Result=(bit)(P0&0x80);
LCD_EN=0;
return Result;
}
//写指令
void LCD_Write_Command(uchar cmd)
{
while(LCD_Busy_Check());
LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();
P0=cmd;Delay4us();
LCD_EN=1;Delay4us();LCD_EN=0;
}
// 写数据
void LCD_Write_Data(uchar dat)
{
while(LCD_Busy_Check());
LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;Delay4us();
LCD_EN=1;Delay4us();LCD_EN=0;
}
//初始化
void LCD_Initialise()
{
LCD_Write_Command(0x38);delay(5);
LCD_Write_Command(0x0c);delay(5);
LCD_Write_Command(0x06);delay(5);
LCD_Write_Command(0x01);delay(5);
}
//设置显示位置
void LCD_Set_Position(uchar pos)
{
LCD_Write_Command(pos|0x80);
}
//显示一行
void LCD_Display_A_Line(uchar Line_Addr,uchar s[])
{
uchar i;
LCD_Set_Position(Line_Addr);
for(i=0;i<16;i++)LCD_Write_Data(s[i]);
}
// 将模数转换后得到的值分解存入缓存
void Convert_To_V oltage(uchar val)
{
uchar Tmp; //最大值为255,对应100L,255/100=2.55 val=val*0.393;
V oltage[2]=val/100+'0'; //
Tmp=val%100; //
V oltage[1]=Tmp/10+'0';
Tmp=Tmp%10;
V oltage[0]=Tmp+'0';
}
//启动I2C总线
void IIC_Start()
{
SDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;
}
//停止I2C总线
void IIC_Stop()
{
SDA=0;SCL=1;Delay4us();SDA=1; Delay4us();SCL=0;
}
// 从机发送应答位
void Slave_ACK()
{
SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;
}
// 从机发送非应答位
void Slave_NOACK()
{
SDA=1;SCL=1;Delay4us();SCL=0;SDA=0;
}
//发送一字节
void IIC_SendByte(uchar wd)
{
uchar i;
for(i=0;i<8;i++) //循环移入8位
{
SDA=(bit)(wd&0x80);_nop_();_nop_();
SCL=1;Delay4us();SCL=0;wd<<=1;
}
Delay4us();
SDA=1; //释放总线并准备读取应答SCL=1;
Delay4us();
IIC_ERROR=SDA; //IIC_ERROR=1表示无应答SCL=0;
Delay4us();
}
//接收一字节
uchar IIC_ReceiveByte()
{
uchar i,rd=0x00;
for(i=0;i<8;i++)
{
SCL=1;rd<<=1;rd|=SDA;Delay4us();SCL=0;Delay4us();
}
SCL=0;Delay4us();
return rd;
}
//连续读入4路通道的A/D转换结果并保存到Recv_Buffer
void ADC_PCF8591(uchar CtrlByte)
{
uchar i;
IIC_Start();
IIC_SendByte(0x90); // 发送写地址
if(IIC_ERROR==1)return;
// IIC_SendByte(CtrlByte); //发送控制字节
//if(IIC_ERROR==1)return;
IIC_Start(); //重新发送开始命令
IIC_SendByte(0x91); // 发送读地址
if(IIC_ERROR==1)return;
IIC_ReceiveByte(); //空读一次,调整读顺序
Slave_ACK(); //收到一字节后发送一个应答位for(i=0;i<4;i++)
{
Recv_Buffer[i++]=IIC_ReceiveByte();
Slave_ACK(); //收到一个字节后发送一个应答位}
Slave_NOACK();
IIC_Stop(); //收到一个字节后发送一个非应答位}
// 向PCF8591发送1字节进行AD转换
//主程序
void main()
{
LED=0;
LCD_Initialise();
while(1)
{
ADC_PCF8591(0x04);
if(Recv_Buffer[0]<26)
{
LCD_Display_A_Line(0x00, "Oil Low! ");
LED=1;
}
else
{
Convert_To_V oltage(Recv_Buffer[0]);
LCD_Line_1[2]=V oltage[2];
LCD_Line_1[3]=V oltage[1];
LCD_Line_1[4]=V oltage[0];
LCD_Display_A_Line(0x00, LCD_Line_1);
LED=0;
}
delay(50);
}
}。

相关文档
最新文档