验证过的STC12C5A60S2单片机AD程序

合集下载

STC12C5A60S2单片机各个模块程序代码

STC12C5A60S2单片机各个模块程序代码

//********************************************************************** ******// // STC12C5A60S2可编程时钟模块//////****************************************************************************//#include <STC12C5A60S2.H>#include <intrins.h>//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句 //若想测试CLKOUT1和CLKOUT0请注释此句#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*///*********************************//}#else /*条件编译CLKOUT0时钟输出*///*********************************//// CLKOUT0时钟和CLKOUT1初始化 ////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0 //T0工作在1T模式时的输出频率 =SYSclk/(256-TH0)/2倍倍AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下//T1定时器速度是普通8051的12倍,即工作在1T模式下TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数 //定时器1工作模式为方式2,自动装载时间常数TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL0 = 0xff;TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频//****************************************************************************//// STC12C5A60S2系统时钟模块////// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时钟// 出厂标准配置是使用外部晶体或时钟//4、8、#include <intrins.h>#define Bus_clk 12 //若要修改系统时钟直接在此处修改//12 为 12M 的sysclk//6 为 6M 的sysclk//3 为 3M 的sysclk //1500 为 1.5M 的sysclk //750 为 750kHz 的sysclk //375 为 375kHz 的sysclk //187500 为 187.5kHz 的sysclkCLK_DIV = 0x01;#elif( Bus_clk == 3 )CLK_DIV = 0x02;#elif( Bus_clk == 1500 )CLK_DIV = 0x03;#elif( Bus_clk == 750 )CLK_DIV = 0x04;#elif( Bus_clk == 375 )CLK_DIV = 0x05;#elif( Bus_clk == 187500 )//****************************************************************************//// STC12C5A60S2系统省电模块////// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式// 掉电模式//)#define uint unsigned intuchar Power_Down_Flag = 0; //进入掉电状态标志sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯sbit Power_Down_LED_INT0 = P0^1; //INT0口掉电唤醒指示灯sbit N_Power_Down_LED_INT0 = P0^2; //INT0口没有唤醒指示灯sbit Normal_Work_LED = P0^3; //正常工作指示灯sbit Power_Down_Wakeup_INT0= P3^2; //外中断唤醒输入口for( t = 0; t < 82; t++ );}}//***********************************//// 正常工作指示//***********************************// void Normal_work(void){Normal_Work_LED = 1;Delay_ms(500);}//***********************************// // 中断初始化 // //***********************************// void Intp_init(void){IT0 = 0; //外部中断源0为低电平触发 EX0 = 1; //允许外部中断EA = 1; //开总中断}wakeup_counter++;for( j = 0; j < 250; j++ ){Normal_work(); //系统正常工作指示}Power_Down_Flag = 1; //系统开始进入掉电状态PCON = 0x02;_nop_();_nop_();_nop_();while( Power_Down_Wakeup_INT0 == 0 ){_nop_(); //等待高电平}Power_Down_LED_INT0 = 0;}else //未掉电状态{N_Power_Down_LED_INT0 = 1; //不是掉电唤醒指示while( Power_Down_Wakeup_INT0 == 0 )////// 说明: STC12C5A60S2单片机有8路10位高速AD转换器,P1^0-P1^7//// 涉及寄存器:P1ASF(模拟功能控制寄存器)、ADC_CONTR(ADC控制寄存器)// ADC_RES、ADC_RESL(转换结果寄存器)//// 注意: 1、初次打开内部A/D模拟电源需适当延时等内部模拟电源稳定后,再启动A/D转换// 启动A/D后,在转换结束前不改变任何I/O口的状态,有利于高精#include <STC12C5A60S2.h>#include <intrins.h>#include "lcd.h"#define ADC_POWER 0x80 //AD电源控制#define ADC_START 0x08 //AD转换控制#define ADC_FLAG 0x10 //AD转换完成#define Speed_0 0x00 //540 clk#define Speed_1 0x20 //360 clk#define Speed_2 0x40 //180 clk// A/D初始化////**********************************//void AD_init(void){AUXR1 = 0x04; //转换结果高2位放在ADC_RES的低2位中,低8位放在ADC_RESL中P1ASF = 0x01; //P1.0口作为模拟功能A/D使用 ADC_RES = 0x00; //结果清零ADC_RESL = 0x00;ADC_CONTR = ADC_POWER|Speed_2|ADC0|ADC_START; //打开电源,180CLK周// 串口初始化 ////****************************************//void UART_init(void){SM0 = 0; //选择串口为方式1工作SM1 = 1; //8位数据波特率可变REN = 1;BRT = 0xDC;AUXR = 0x15; //选择独立波特率发生器为串行 //口的波特率发生器,模式为1T// 串口发送数据// //******************************************// void SendData( uchar byte ){SBUF = byte;while(!TI);TI = 0;}//******************************************//// 主程序//ADC_CONTR &= !ADC_FLAG; //清标志Printf_Decimal(Result_Calculate());ADC_RES = 0x00;ADC_RESL = 0x00;ADC_CONTR = ADC_POWER|Speed_2|ADC_START; //开始下一次转换_nop_();_nop_();_nop_();_nop_();}uchar Read_Date(void); //读数据void Write_Cmd( uchar cmd ); //写命令void Write_Date( uchar date );//写数据void Init_LCD(void);//初始化LCDvoid Location( uchar x, uchar y );//设定显示位置void Clear_Screen(void);//清屏void Write_str( uchar *p );void Printf_Decimal(double Num);#include "lcd.h"for( t = 0; t < 41; t++ );}}//**********************************////* 名称: Busy()//* 功能: 读取忙状态//* 输入: 无//* 输出: 1-忙 0-空闲//**********************************//uchar Busy(void)//* 功能: 读12864状态//* 输入: 无//* 输出: status-当前状态//**********************************// uchar Read_Status(void){uchar status;RS = 0;RW = 1;E = 0;//* 名称: Write_Cmd()//* 功能: 向12864写命令//* 输入: cmd - 命令参数//* 输出: 无//**********************************//void Write_Cmd( uchar cmd ){RS = 0;RW = 0;//**********************************// void Write_Date( uchar date ){while(Busy());RS = 1;E = 0;_nop_();_nop_();P2 = date;uchar Read_Date(void){uchar date;while(Busy()); //忙RS = 1;E = 0;_nop_();_nop_();_nop_();//**********************************// void Init_LCD(void){Delay_ms(4);PSB = 1;//并行方式Delay_ms(4);Write_Cmd(0x0c);//开显示关游标Delay_ms(4);Clear_Screen();//清屏}else if( x == 2 )x = 0x90;else if( x == 3 )x = 0x88;else if( x == 4 )x = 0x98;position = x + y;Write_Cmd(position);Delay_ms(2);}Delay_ms(10);}//**********************************// //* 名称: Write_str()//* 功能: 向12864里写字符串//* 输入: *p -- 字符串地址//* 输出: 无//**********************************// void Write_str( uchar *p ){{uchar s[6] = {0,0,46,0,0};uint t;t = (uint)(Num * 1000);s[0] = t/10000+48;s[1] = t%10000/1000+48;s[3] = t%1000/100+48;s[4] = t%100/10+48;s[5] = t%10+48;Location(1,2);// STC12C5A60S2 PCA/PWM模块////// 说明: STC12C5A60S2单片机有两路可编程计数器阵列(PCA)模块,可用于软件// 定时器,外部脉冲的捕捉、高速输出以及脉宽调制(PWM)输出//// 涉及寄存器:CMOD(PCA工作模式寄存器) CCON(PCA控制寄存器) // CCAPM0,CCAPM1(PCA比较/捕获寄存器)// CH,CL(PCA的16位计数器)、CCAPnL,CCAPnH(PCA捕捉/比较********//#include <STC12C5A60S2.H>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/*******高速模式变量更改*********/#define FOSC 12000000#define T100KHz (FOSC/2/100000) //高速脉冲输出频率计算: f = PCA模块的时钟源/(2*CCAP0L)//CCAP0L = PCA时钟源/2/f)#define CLK_6 0x0d //Sysclk/6#define CLK_8 0x0e //Sysclk/8/********模式选择********/#define H_model 0x4d //高速输出模式,中断模式#define T_model 0x49 //定时模式#define P_model 0x42 //无中断PWM模式#define PL_model 0x63 //由低变高可中断PWM模式#define PH_model 0x53 //由高变低可中断PWM模式#define PHL_model 0x73 //高低都可中断PWM模式#define CU_model 0x61 //16位捕获,上升触发中断模式//********************************//// H_model初始化 ////********************************//void HP_init(void){CMOD = CLK_4; //PCA时钟源为SysclkCCAPM0 = H_model; //高速输出模式CCAP0L = value;CCAP0H = value>>8;value += T100KHz;CR = 1; //开启PCA计数器//当不使用定时0溢出为时钟源时,PWM输出的频率=PCA的时钟源/256//使用定时器溢出的时钟源时,可设定定时器的值对输出频率的改变//分频为0-256分频}//********************************// // T_model初始化 // //********************************//void CD_init(void){CMOD = CLK_4;CCAPM0 = CD_model;CR = 1;EA = 1;}//********************************// // 主程序 // //********************************////*******************************// void CD_Service(void) interrupt 7{CCF0 = 0;LED = ~LED;/*void TP_Service(void) interrupt 7{CCF0 = 0; //清除PCA计数器溢出中断标志test++;CCAP0L = value;CCAP0H = value>>8;value += T100KHz;} *///****************************************************************************//// STC12C5A60S2串行通信模块// IP(中断优先级寄存器)IPH()SADEN()SADDR()WAKE_CLKO(时钟唤醒寄存器)// Bit1 - PD 控制单片机进入掉电模式// //// 程序说明:程序实现从PC端发送数据到单片机,单片机将接收到的数据通过12864// 显示出来////****************************************************************************//时需修//波特率为19200uchar Send_Bflag = 0; //正在发送标志uchar Receive_Bflag = 0; //正在接送标志uchar Re;sbit LED = P1^4;sbit LED1 = P1^5;void UART_init(void);void Delay( uint time );#elif( BTL == 4800 )BRT = 0xB8;#elif( BTL == 9600 )//波特率设置为9600BRT = 0xDC;#elif( BTL == 14400 )BRT = 0xE8;#elif( BTL == 19200 )BRT = 0xEE;#elif( BTL == 28800 )BRT = 0xF4;}//************************************************// // 发送一个字节数据 // //************************************************// void Send_byte( uchar byte ){SBUF = byte;while(!TI);TI = 0;// 接收函数 // //************************************************//void Receive( void ){Write_Date(SBUF);Re++;if( Re == 16 )Location(2,0); if( Re == 32 )Location(3,0); if( Re == 48 )Location(4,0);if( Re == 66 )UART_init();while(1){if( RI == 1 ){RI = 0;Receive();Printf("Success!");}EA = 1;}//****************************************************************************//// STC12C5A60S2 SPI接口模块////是数#include <STC12C5A60S2.H>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/************对SPCTL寄存器的设置位宏定义*************/#define SSIG 0x80 //SS引脚忽略#define SPEN 0x40 //SPI使能位#define DORD 0x20 //SPI数据发送LSB最先发送#define MSTR 0x10 //主从模式选择/************串口波特率设定*************************/#define BTL 9600 //若要更改波特率直接更改此处,当波特率大于9600时需修改相应的接收程序,//可选波特率有以下: 否则有可能出现乱码//波特率为2400 //波特率为28800//波特率为4800 //波特率为38400 //波特率为9600 //波特率为57600 //波特率为14400 //波特率为115200//波特率为19200void UART_init(void);#if( BTL == 2400 )BRT = 0x70; //波特率设置为9600 #elif( BTL == 4800 )BRT = 0xB8;#elif( BTL == 9600 )BRT = 0xDC;#elif( BTL == 14400 )BRT = 0xE8;#elif( BTL == 19200 )BRT = 0xEE;// IP = 0X10; //PS = 1;串口1中断为最高优先级中断// EA = 1; //开总中断}//************************************************// // 发送一个字节数据 ////************************************************// void Send_byte( uchar byte ){SBUF = byte;while(!TI);//************************************************// // 接收函数 // //************************************************//uchar Receive( void ){uchar byte;_nop_();_nop_();_nop_();_nop_();//***********************************//void Init_SPI(void){SPDAT = 0; //清空数据寄存器 SPSTAT = SPIF|WCOL; //清空SPI状态寄存器SPCTL = SPEN|MSTR; //SPI设置为主机模式IE2 = 0x02; //允许SPI中断}//***********************************////* 名称:mainif(flag) //当PC端有发送数据时才进行SPI传输数据{SPISS = 0;SPDAT = flag;flag = 0;。

STC12C5A60S2中的AD转换

STC12C5A60S2中的AD转换

STC12C5A60S2中的AD转换逐次逼近原理AD 里面包含da,当输入电压Vin时,da的最高位是1,即为0.5Vref与输入信号比较,如果输入大于0.5Vref则比较器输出为1,同时da的最高位为1,反之DA最高位则为0,通过8次比较后得到8个01数据即完成ad转换。

现在说下程序中用到stc12单片机两个寄存器ADC_CONTR;主要用来配置ad启动的工作模式;还有个result的寄存器程序中的注意点:配置完ADC_CONTR后要延时4个时钟周期先把程序附上#include &quot;stc12.h&quot;#include &quot;intrins.h&quot;#include &quot;ad.h&quot;uint ad;#define ADC_POWER 0X80 //ADC最高位给adc部分供电,类似于片选#define ADC_START 0X08 //模数转换启动控制位#define ADC_FLAG 0x10 //ad转换需要时间,这个是转换完成标志位#define ADC_SPEEDLL 0X00 //540 clock#define ADC_SPEEDL 0X20 //360 clock#define ADC_SPEEDH 0X40 //180 clock#define ADC_SPEEDHH 0X60 //90 clockuchar ADCresult(uchar aa) //这里的参数是哪个口来ad转换{P1ASF=0X01; //这里的选择和用哪一个P1口作为ad采样ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|aa;//ADC_CONTR=0X88|aa;_nop_();_nop_();_nop_();_nop_();//设置ADC_CONTR寄存器后需加4个CPU时钟周期的延时,才能保证值被写入ADC_CONTR寄存器while (!(ADC_CONTR & ADC_FLAG)); //等待ADC_CONTR,这里的ADC_FLAG相当于一个常数,不是寄存器里面的某个位//while(!ADC_FLAG);//ADC_FLAG=0;ADC_CONTR &= ~ADC_FLAG; //Close ADC 将标志位清零等待下次硬件置1ad=(ADC_RES<<2)+ADC_RESL; //打开10位AD采集功能如果用8位AD 屏掉这句把下一句改为Vo=(float)(ADC_RESL)*500/256; 即可//ADC_RES结果寄存器的高2位;ADC_RES结果寄存器的低8位ad=(float)(ad)*5*100/1024; //Return ADCresult(为显示整数,这里将电压值扩大了十倍)//10位AD采集即2的10次方满值为1024 这里用1024表示5伏的电压//那么用采集到的数量值除以1024 在乘以5 得到的值就是采集的电压数值//这里又*100 是为了扩大100倍显示小数位//ADC_RES*(5/256)为采集的电压值然后扩大10倍便于计算return ad;}这里只是个ad.c源文件,这里有几个问题想说一下1.怎么知道是10位还是8位的ad结果;你可以在ADCresult(uchar aa)最前面加一条AUXR1&=0x04;什么意思呢,转换结果的低2位放在ADC_RES,高8位ADC_RESL 中2为什么不用//while(!ADC_FLAG);//ADC_FLAG=0;这两条因为ADC_FLAG相当于常量前面用宏定义而头文件里只有ADC_CONTR的地址映射;但是如果在头文件中用sbit ADC_FLAG=ADC_CONTR^4会出现错误,具体原因还不清楚先说到这吧。

(完整word版)STC12C5A60S2ADPWM应用例程

(完整word版)STC12C5A60S2ADPWM应用例程

#include”stc12c5a.h" //头文件在STC公司主页上下载#include"stdio.h"#include”intrins。

h”#define uchar unsigned char//—-—————---—————-----———————-—-——-————---—-—————————--————-————--—-—---—-—-—---void AD_init();//AD初始化函数void delay(unsigned int a); //延时函数float AD_work(unsigned char channel); //AD数值处理函数unsigned int AD_get(unsigned char channel);//AD转换函数unsigned char sh1,ge1,n1,m1,aa;int num,pwm,V,temp1;sbit PWM=P0^0; //定义PWM输出口为P0^0sbit key1=P0^1;sbit key2=P0^2;//--—---—----—----——---—-—-—————---—----——--———---———-———-———-—-—--————--—-——-—-void send(uchar data1){ES=0; //关闭中断TI=0;SBUF=data1;while(!TI); //等待发送完成TI=0;//中断标志位清0ES=1;//打开中断}void display() //串口发送AD{temp1=V;sh1=temp1/1000;ge1=(temp1%1000)/100;n1=((temp1%1000)%100)/10;send(sh1+48);send(’.');send(ge1+48);send(n1+48);send(’V');send(' ');}//--——-——-----—--—--———------———--————-—-——-—-——----———-—-—--—-—-———--—-—-——---—unsigned int AD_get(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 AD_work(unsigned char channel){double AD_val,AD_vale; //定义处理后的数值AD_val为浮点数unsigned char i;for(i=0;i<100;i++)AD_val+=AD_get(channel); //转换100次求平均值(提高精度)AD_val/=100;AD_vale=(AD_val*5000)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值V=AD_vale;return V;}//--—-—----——--—------—--—-—---—----—----———-—--—---—————-———---—--—————---—————void delay(unsigned int a)//延时约1ms{unsigned int i;while (-—a!=0)for(i=600;i>0;i-—);}//-—--——-—----——--——--————-——-—-—-—--—--——-————---—-—----—-—--——-—----———-—-——-—//------—-———-——-—--—--——---————-————-—-——-—--—————-—-—--——-—————-—--———--——----void AD_init(){P1ASF=0xff;//P1口全部作为模拟功能AD使用ADC_RES=0;//清零转换结果寄存器高8位ADC_RESL=0;//清零转换结果寄存器低2位ADC_CONTR=0x80;//开启AD电源delay(2);//等待1ms,让AD电源稳定}void anjian(){if(pwm!=100) //加到100不继续加{if(key1==0){delay(10);if(key1==0){pwm++;aa=1;while(!key1);}}}if(pwm!=0) //减到0不继续减{if(key2==0){delay(10);if(key2==0){aa=1;pwm-—;while(!key2);}}}}void main(){AD_init(); //AD初始化TMOD=0x21;TH1=0xfd;TL1=0xfd; //设置9600波特率SCON=0x50; //串口方式1,允许接收TH0=(65536—7)/256; //装初值,设定PWM频率TL0=(65536—7)%256;ET0=1;TR0=1;TR1=1;SM0=0;SM1=1;REN=1;ES=1;EA=1;pwm=50;//占空比为50%while(1){unsigned char i;i=0;//发送P1^i的转换数值(P10口)AD_work(i); //读取AD电压display();if(V〉=3000){aa=0;pwm=0;//占空比为0}if(V〈3000){if(aa==0)pwm=50;anjian();}}}void T0_time()interrupt 1 //中断时间为0.01ms,因PWM输出口输出高低电平共100次为1个周期,所以PWM的周期为1ms,频率为1KHZ{TH0=(65536—7)/256;TL0=(65536-7)%256;num++;if(num〈=pwm)PWM=1;elsePWM=0;if(num==100)num=0;}。

STC12c5a60s2官方手册AD程序(中文注释)

STC12c5a60s2官方手册AD程序(中文注释)
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC的高8位结果寄存器
sfr ADC_LOW2 = 0xBE; //ADC的低2位结果寄存器
sfr P1ASF = 0x9D; //P1辅助功能控制寄存器
/*ADC操作定义常量*/
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define ADC_SPEEDHH 0x60 //90 clocks
void InitUart();
void SendData(BYTE dat); void Delay(WORD n);
}
/*----------------------------
Uart初始化
----------------------------*/
void InitUart()
{
SCON = 0x5a; //8位数据,无校验位
TMOD = 0x20; //T1为8位自动重载
void InitADC( )
{
P1ASF = 0xff; //设置所有P1为模拟输入端口
ADC_RES = 0; //清除先前的结果
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
Delay(2); //ADC 延迟启动和启动/转换的电源
while (1);
}
/*----------------------------
ADC函数中断服务例程

stc12c5a60s2-AD采集-12864串行显示终极程序-带滤波

stc12c5a60s2-AD采集-12864串行显示终极程序-带滤波
注意:本程序用的是12864串行显示,将PSB引脚接地,RST拉高、片选口RS接高之后除了电源和地线,只用2根线就可以显示了,接线很方便,最大程度的节省了io口。
本程序是以电流采集为例的,采集的是电流传感器输出的电压,然后转换成电流,如果只需要采集电压的话将转化为电流的语句删除即可。AD是stc12c5a60s2自带的10位AD。使用很方便。有不明白的可以qq联系我,1264136841
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;
else
LCD_SID = 0;
}
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;

stc12C5A60S2内部AD应用

stc12C5A60S2内部AD应用

系统说明:本人想用STC12C5A60S2自带的A/D对电源电压进行检测(暂定3.3V),晶振:12M,电压从P1.0口输入,检测后的电压值在1602上进行显示,附上硬件大致原理图,硬件部分是照STC12C5A60S2芯片资料上设计,大家看看有错没?硬件原理简图(原文件名:clip_image001.gif)程序的A/D部分也是从官网资料上搬下来的,只自己稍微改了一下对读取到的A/D转换结果的数据处理,液晶部分是前阵子写的搬过来的。

大家帮我看看哪出问题了?程序如下:#include<reg51.h>#include "intrins.h"#define uchar unsigned char#define uint unsigned intuchar Vo; //A/D转换后换算的电压值/*Declare SFR associated with the ADC */sfr ADC_CONTR = 0xBC; //ADC control registersfr ADC_RES = 0xBD; //ADC high 8-bit result registersfr ADC_RESL = 0xBE;//sfr ADC_LOW2 = 0xBE; //ADC low 2-bit result registersfr P1ASF = 0x9D; //P1 secondary function control register/*Define ADC operation const for ADC_CONTR*/#define ADC_POWER 0x80 //ADC power control bit#define ADC_FLAG 0x10 //ADC complete flag 模数转换结束标志位#define ADC_START 0x08 //ADC start control bit 模数转换启动控制位//转换速度控制位SPEED0和SPEED1,共四种状态,对应四种转换速度#define ADC_SPEEDLL 0x00 //540 clocks#define ADC_SPEEDL 0x20 //360 clocks#define ADC_SPEEDH 0x40 //180 clocks#define ADC_SPEEDHH 0x60 //90 clocksuchar tCount;sbit RS = P0^4;sbit RW = P0^5;sbit EN = P0^6;void DelayMS(uint ms){uint i;while(ms--){for(i=0;i<120;i++);}}/*----------------------------Software delay function----------------------------*/void Delay(uint n){uint x;while (n--){x = 5000;while (x--);}}/*----------------------------Initial ADC sfr----------------------------*/void InitADC(){P1ASF = 0x01; //选择P1.0作为A/D输入通道ADC_RES = 0; //清0ADC_CONTR = ADC_POWER | ADC_SPEEDLL; //0x10|0x00=0x10:开电源和设置A/D转换速度Delay(2); //ADC power-on and delay}/*----------------------------Get ADC result----------------------------*/uchar GetADCResult(uchar ch){ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;//0x00|0x00|ch|0x08:选择A/D输入通道,开始A/D转换_nop_(); //Must wait before inquiry ,_nop_(); //设置ADC_CONTR寄存器后需加4个CPU时钟周期的延时,才能保证值被写入ADC_CONTR寄存器_nop_();_nop_();while (!(ADC_CONTR & ADC_FLAG));//Wait complete flagADC_CONTR &= ~ADC_FLAG; //Close ADCVo=ADC_RES*5*10/256; //Return ADC result(为显示整数,这里将电压值扩大了十倍)return Vo;}uchar Read_LCD_State(){uchar state;RS=0;RW=1;EN=1;DelayMS(1);state=P2;EN = 0;DelayMS(1);return state;}void LCD_Busy_Wait(){while((Read_LCD_State()&0x80)==0x80);DelayMS(5);}void Write_LCD_Data(uchar dat) //写数据到1602{LCD_Busy_Wait();RS=1;RW=0;EN=0;P2=dat;EN=1;DelayMS(1);EN=0;}void Write_LCD_Command(uchar cmd) //写命令{LCD_Busy_Wait();RS=0;RW=0;EN=0;P2=cmd;EN=1;DelayMS(1);EN=0;}void Init_LCD() //1602 初始化{Write_LCD_Command(0x38);DelayMS(1);Write_LCD_Command(0x01); //清屏DelayMS(1);Write_LCD_Command(0x06); //DelayMS(1);Write_LCD_Command(0x0c);DelayMS(1);}void Set_LCD_POS(uchar p){Write_LCD_Command(p|0x80);}void Display_LCD_String(uchar p,uchar *s) //1602显示{uchar i;Set_LCD_POS(p);for(i=0;i<16;i++){Write_LCD_Data(s);DelayMS(1);}}void Format_DateTime(uchar d,uchar *a){a[0]=d/10+'0';a[1]=d%10+'0';}//写入液晶第二行void display(uchar add,uchar date){uchar shi,ge;shi=date/10+'0';ge=date%10+'0';Write_LCD_Command(0x80+0x40+add);Write_LCD_Data(shi);Write_LCD_Data(ge);}//写入液晶第一行void display1(uchar add,uchar date){uchar shi,ge;shi=date/10;ge=date%10;Write_LCD_Command(0x80+add);Write_LCD_Data(0x30+shi); //0x30即48(十进制)对应的ASCAII码为字符‘0’ Write_LCD_Data(0x30+ge);}void main(){Init_LCD();InitADC();while (1){GetADCResult(0);Display_LCD_String(0,"dianya:");display1(7,Vo);Display_LCD_String(9,"V ");DelayMS(1000);}}程序二:* 文件名:AD_CAIYANG.C* 功能:使用AD采集电压显示在LCD* 说明:转自网络,本人验证通过****************************************************************************/ #include<STC12C5A60S2.H>#define uint unsigned int#define uchar unsigned charsbit CS=P2^0; //LCD12864串行通信片选sbit SID=P2^1; //LCD12864串行通信数据口sbit SCLK=P2^2; //LCD12864串行通信同步时钟信号sbit PSB=P2^5; //LCD12864并/串选择:H并行 L串行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[]={"提示: 按1 键进入"};uchar code disp2[]={"功能选择界面. "};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;delay(5); //必要的延时}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= #00000000BP1M1|=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; //左移四位,把低四位的数据移到高四位,再把低四位置0 for(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以内temp1=(int)ad1;sh1=temp1/1000; //十位ge1=(temp1%1000)/100; //个位n1=((temp1%1000)%100)/10; //小数点后一位m1=((temp1%1000)%100)%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(2,0);disp_hanzi(disp1);lcd_pos(3,0);disp_hanzi(disp2);*/}void main(){EA=1;AD_initiate(); //初始化ADC_Power_On(); //开AD电源//init();lcd_init();delay(10);while(1){caiyangP10(); //测电压 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内部ADC转换串口显示程序

STC12C5A60S2内部ADC转换串口显示程序

STC12C5A60S2内部ADC转换串口显示程序STC12C5A60S2 内部ADC转换串口显示程序(已经验证成功)#include <>#include ""typedef unsigned char uchar;typedef unsigned int uint;/************* 设置ADC_CONTRL 控制寄存器 *************/#define ADC_POWER 0x80 // ADC电源控制为 0:关闭AD转换电源 1:打开AD转换电源#define ADC_FLAG 0x10 // ADC转换结束标志位,AD转换后自动置1,// 由软件清零(这里作取反使用)#define ADC_START 0x08 // ADC转换启动控制位,设置为1时开始AD转换,// 转换结束后为0#define ADRJ_ 0x04 // AUXR1寄存器的ADRJ位是转换结果寄存器(ADC_RES,ADC_RESL)的数据格式调整控制位// ADRJ为0时,10位AD转换结果的高8位存放在ADC_RES 中,低2位存放在ADC_RESL的低2位// ADRJ为1时,10位AD转换结果的高2位存放在ADC_RES低2位中,低8位存放在ADC_RESL#define ADC_SPEEDLL 0x00 // 540个时钟周期转换一次(最低速) #define ADC_SPEEDL 0x20 // 360个时钟周期转换一次(低速) #define ADC_SPEEDH 0x40 // 180个时钟周期转换一次(高速) #define ADC_SPEEDHH 0x60 // 90个时钟周期转换一次(最高速) uchar ch = 0; // 模拟通道uchar code num[]={'0','1','2','3','4','5','6','7','8','9'};// 字符数组,输出到串口显示void delay2ms(void) //误差{unsigned char a,b;for(b=129;b>0;b--)for(a=45;a>0;a--);}void delay2s(void) //误差{unsigned char a,b,c,n;for(c=142;c>0;c--)for(b=168;b>0;b--)for(a=250;a>0;a--);for(n=2;n>0;n--);_nop_(); //if Keil,require use}//************************ 串口通信部分******************************uchar wj_uun = '!'; // 用于存放串口1接收的字符void bt_uart_init(void) // 单片机串口初始化{//SCON=0X50; // SM0=0 SM1=1 SM2=0 REN=1SM0 = 0; // 串口工作方式1:1位起始位,8位数据位,1位停止位允许串口接收SM1 = 1;REN = 1; // 允许串口接收//RI=1; // 接收标志位,0:正在接收 1:接收完毕 (如果RI=1就一直执行串口中断)TMOD = 0X20; // 定时器T1工作方式2TH1 = 0XFD; // 9600bit/s下的定时器初值TL1 = 0XFD;TR1 = 1; // 启动定时器T1EA = 1; // 开总中断ES = 1; // 开串行口中断}/************** 串口1发送函数 *****************/void s1_send_char(uchar dat) { // 发送端(发送的是字符) SBUF = dat; // 将字符送入发送缓冲寄存器while(!TI); // TI为发送状态标志位,0:发送中 1:发送结束TI = 0; // 手动清零标志位}void s1_send_string(uchar *pt) { // 通过调用发送字符函数来发送字符数组while(*pt != '\0') {s1_send_char(*pt++);}}void ADC_Init(void) {// P1ASF = 0x01; // 设置P1口的0为模拟输入端口(经过测试这句写不写P1口都能模拟输入)ADC_RES = 0; // 先清空两个寄存器ADC_RESL = 0;AUXR1 &= ~ADRJ_; // ADRJ为0的存储格式(参考技术手册)ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch; // 开启ADC电源并且启动ADC// 经过最少四个时钟周期之后才能够正确读取到ADC_CONTR的值delay2ms();EADC = 1; // 允许ADC中断}//***************** 主函数 *****************void main()P4SW = 0x70; // P4端口的4、5、6脚可作为通用I/O 口bt_uart_init(); // 串口初始化ADC_Init(); // ADC初始化while(1) {;}}//***************** ADC中断函数 *****************void ADC_(void) interrupt 5 // ADC中断编号为5{uint adc_result = 0;// while(!(ADC_CONTR & ADC_FLAG)); // 如果未转换结束,等待ADC_CONTR寄存器ADC_FLAG位置1// ADC_CONTR &= ~ADC_FLAG; // 清零ADC转换结束标志位(这句可以不写,因为下面有覆盖)if(ADC_CONTR & ADC_FLAG) {ADC_RESL &= 0x03;adc_result = ADC_RES*4 + ADC_RESL;// 获取到10AD转换值s1_send_string(" 通道号:");s1_send_char(num[ch]); // 通过串口发送通道号s1_send_string(" 转换值:"); // 一共四位数s1_send_char(num[adc_result/1000]);s1_send_char(num[adc_result%1000/100]);s1_send_char(num[adc_result%100/10]);s1_send_char(num[adc_result%10]);if(++ch>3) ch = 0; // 不断切换通道号0、1、2、3// 再次设置 ADC_CONTR 寄存器ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;delay2s();}/************** 串口1中断程序 *****************/void bt_serial_1() interrupt 4 // 中断编号4为串行口1中断{if(RI) // 接收标志位,0:正在接收1:接收完毕 (如果RI=1就一直执行中断){RI = 0; // 同样需要手动清零wj_uun = SBUF; // 将接收缓冲器接收的字符送入变量中}}。

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采样并液晶显示

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采样并液晶显示(数字燃油表)

■Z3¥ in L=*2»1I ■:EG IE*£*柑壬陶肾数字燃油表模拟电路设计可实现以下功能:1、推动滑动变阻器,能使 LCD从0显示到1002、档显示数字低于 10时,灯亮,LCD显示"oil low ”LCMUUEQt以下为C程序:#in clude<reg52.h>#in clude< intrin s.h>#defi ne uchar un sig ned char#defi ne uint un sig ned int#defi ne Delay4us(){_ nop_();_no p_( );_n op_( );_n op_();}sbit LED=P1A0;sbit LCD_RS=P2A6;sbit LCD_RW=P2A5;□1!£□:!a.7HU3KKI 常F3L1TC-J _"P3SWT0 :Fzawrr —J1•IFZH^H'S.TWifl 3几山口m II1A1IZ■ ir•TECWRD7sbit LCD_EN=P2^7;sbit SCL=P2A0;sbit SDA=P2A1;uchar Recv_Buffer[4];uint Voltage[]={'0','0','0','0'}; bit bdata IIC_ERROR; uchar LCD_Line_1[]={"//I2C 时钟引脚//I2C 数据输入输出引脚//数据接收缓冲//数据分解为电压x.xx//I2C 错误标志位"};//延时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);//最大值为 255,对应 100L,255/100=2.55 // //}//设置显示位置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; 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;SCL=0;Delay4us();}//接收一字节uchar IIC_ReceiveByte() {uchar i,rd=0x00; //释放总线并准备读取应答//IIC_ERROR=1 表示无应答for(i=0;i<8;i++){SCL=1;rd<<=1;rd|=SDA;Delay4us();SCL=0;Delay4us();}SCL=0;Delay4us();return rd;}//连续读入 4 路通道的 A/D 转换结果并保存到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// 发送写地址//发送控制字节//重新发送开始命令// 发送读地址// 空读一次 ,调整读顺序//收到一字节后发送一个应答位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);}}(注:表格素材和资料部分来自网络,供参考。

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采样后的结果。

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

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

最新STC12C5A60S2单片机的10位AD转换程序

最新STC12C5A60S2单片机的10位AD转换程序

STC12C5A60S2单片机的10位AD转换程序#include"stc12c5a.h" //头文件在STC公司主页上下载#include"stdio.h" //输入输出函数#include"intrins.h"//------------------------------------------------------------------------------void AD_init(); //初始化ADvoid serial_init();void delay(unsigned int a);float AD_work(unsigned char channel);unsigned int AD_get(unsigned char channel);//------------------------------------------------------------------------------void main() //主程序{AD_init(); //A/D转换初始化serial_init(); //串口初始化while(1){unsigned char i;for(i=0;i<8;i++) //循环发送P1.0-P1.7的转换数值{TI=1; //使用printf函数前须先将发送标志位TI置1printf("The P1.%bd voltage is %f\n",i,AD_work(i));TI=0;delay(1000); //延时约1s}}}//------------------------------------------------------------------------------unsigned int AD_get(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 AD_work(unsigned char channel){float AD_val; //定义处理后的数值AD_val为浮点数unsigned char i;for(i=0;i<100;i++)AD_val+=AD_get(channel); //转换100次求平均值(提高精度)AD_val/=100;AD_val=(AD_val*5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值return AD_val;}//------------------------------------------------------------------------------void delay(unsigned int a) //延时约1ms{unsigned int i;while (--a!=0)for(i=600;i>0;i--); //1T单片机i=600,若是12T单片机i=125}//------------------------------------------------------------------------------void serial_init(){TMOD=0x20;TH1=0xfd;TL1=0xfd; //设置9600波特率SCON=0x50; //串口方式1,允许接收TR1=1;}//------------------------------------------------------------------------------void AD_init(){P1ASF=0xff; //P1口全部作为模拟功能AD使用ADC_RES=0; //清零转换结果寄存器高8位ADC_RESL=0; //清零转换结果寄存器低2位ADC_CONTR=0x80;//开启AD电源delay(2); //等待1ms,让AD电源稳定}/* 酱炒牛柳条:Sautéed Beef Filet in XO Sauce阿香婆石头烤肉:Beef BBQ with Spicy Sauce八宝菠菜:Spinach with Eight Delicacies白菜豆腐焖酥肉:Braised Pork Cubes with Tofu and Chinese Cabbage白菜心拌蜇头:Marinated Jellyfish and Chinese Cabbage in Vinaigrette白灵菇扣鸭掌:Mushrooms with Duck Feet白灵菇牛柳:Stir-Fried Beef Filet with Mushrooms白切鸡:Boiled Chicken with Sauce白灼肥牛:Scalded Beef百叶结烧肉:Stewed Pork Cubes and Tofu Skin in Brown Sauce 板栗红烧肉:Braised Pork with Chestnuts拌八爪鱼:Spicy Cuttlefish拌豆腐丝:Shredded Tofu with Sauce拌海螺:Whelks and Cucumber拌苦菜:Mixed Bitter Vegetables拌茄泥:Mashed Eggplant with Garlic拌双耳:Tossed Black and White Fungus拌爽口海苔:Sea Moss with Sauce拌香椿苗:Chinese Toon with Sauce包子:Baozi鲍鱼红烧肉:Braised Pork with Abalone鲍汁扣东坡肉:Braised Dongpo Pork with Abalone Sauce。

STC12C5A60S2双串口使用程序

STC12C5A60S2双串口使用程序

STC12C5A60S2 双串口使用程序(已经验证成功)#include <stc12c5a60s2.h>#include "intrins.h"#define uchar unsigned char#define S2RI 0x01 // 串口2接收中断请求标志位#define S2TI 0x02 // 串口2发送中断请求标志位//================================================// 对于将P4.4、P4.5当做I/O口使用必须添加的定义||//================================================sfr p4sw=0xbb; // 需在主函数文件中做相应设置4、5、6为1(作为I/O口使用)/*sbit button1=P4^3;sbit button2=P4^4;sbit button3=P4^5;sbit button4=P4^6;*/uchar code temp1[]={" 白云:“我可是个名人”"};uchar code temp2[]={" 黑土:“啥名人啊,你就是个人名”"};uchar code temp3[]={" 小崔:“诶,大叔大妈,你俩都冷静冷静”"};uchar code temp4[]={" 观众:“哈哈哈哈”"};/*void delay_1ms(uchar ii) // 误差-0.018084490741us{unsigned char a,b;for(; ii>0; ii--)for( b = 18; b>0; b--)for( a = 152; a>0; a--);_nop_(); //if Keil,require use intrins.h}void delay1s(void) //误差-0.000000000125us{unsigned char a,b,c;for( c = 212; c>0; c--)for( b = 160; b>0; b--)for( a = 80; a>0; a--);_nop_(); //if Keil,require use intrins.h_nop_(); //if Keil,require use intrins.h}*///************************ 串口通信部分******************************uchar wj_uun = '!'; // 用于存放串口1接收的字符uchar wj_uun2 = '?'; // 用于存放串口2接收的字符void bt_uart_init() // 单片机双串口初始化{//SCON=0X50; // SM0=0 SM1=1 SM2=0 REN=1SM0 = 0; // 串口工作方式1:1位起始位,8位数据位,1位停止位允许串口接收SM1 = 1;REN = 1; // 允许串口接收//RI=1; // 接收标志位,0:正在接收1:接收完毕(如果RI=1就一直执行串口中断) TMOD = 0X20; // 定时器T1工作方式2TH1 = 0XFD; // 9600bit/s下的定时器初值TL1 = 0XFD;TR1 = 1; // 启动定时器T1EA = 1; // 开总中断ES = 1; // 开串行口中断S2CON = 0x50; // 串口2工作在方式1 10位异步收发S2SM0=0 S2SM1=1 S2REN=1允许接收BRT = 0XFD; // 9600bit/s下的独立波特率发生器初值AUXR = 0x10; // 辅助寄存器:0001 0000 ->BRTR=1:独立波特率发生器开始计数,S2SMOD=0:波特率不加倍,BRTx12=0:独立波特率每12个时钟计数一次IE2 = 0x01; // 开串口2中断0000 0001->ES2=1// AUXR1 = 0x10; // 0001 0000->S2_P4=1:UART2从P1口(RxD2:P1.2 TxD2:P1.3)切换到P4口(RxD2:P4.2 TxD2:P4.3) 否则默认都为P1口}/************** 串口1发送函数*****************/void s1_send_char(uchar dat) // 发送端(发送的是字符){SBUF = dat; // 将字符送入发送缓冲寄存器while(!TI); // TI为发送状态标志位,0:发送中1:发送结束TI = 0; // 手动清零标志位}void s1_send_string(uchar *pt) // 通过调用发送字符函数来发送字符数组{while(*pt != '\0'){s1_send_char(*pt++);}}/************** 串口2发送函数*****************/void s2_send_char(uchar dat2) // 发送端(发送的是字符){S2BUF = dat2; // 将字符送入串口2的发送缓冲寄存器while(!(S2CON&S2TI)); // 判断发送是否结束:S2CON.bit2 = 0:发送中1:发送结束S2CON &= ~S2TI; // 手动清零标志位,令S2CON.bit2 = 0}void s2_send_string(uchar *pt2) // 通过调用发送字符函数来发送字符数组{while(*pt2!='\0'){s2_send_char(*pt2++);}}/************** 串口1中断程序*****************/void bt_serial_1() interrupt 4 // 中断编号4为串行口1中断{if(RI) // 接收标志位,0:正在接收1:接收完毕(如果RI=1就一直执行中断){RI = 0; // 同样需要手动清零wj_uun = SBUF; // 将接收缓冲器接收的字符送入变量中}}/************** 串口2中断程序*****************/void bt_serial_2() interrupt 8 // 中断编号8为串行口2中断{if(S2CON&S2RI) // 接收标志位: S2CON.bit1 = 0:正在接收1:接收完毕(如果RI=1就一直执行中断){S2CON &= ~S2RI; // 同样需要手动清零,令S2CON.bit1 = 0wj_uun2 = S2BUF; // 将串口2接收到的字符送入变量中}}void main(void){bt_uart_init(); // 串口初始化p4sw = 0x70; // 0111 0000 对应的4、5、6脚设置成功通用I/O口while(1){/*if(wj_uun != '!') // 串口1接收{s1_send_char(wj_uun); // 串口1发送wj_uun = '!';}*/if(wj_uun2 != '?') // 串口2接收{s2_send_char(wj_uun2); // 串口2发送wj_uun2 = '?';}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
x=0x90; //第二行
else if(x==2)
x=0x88; //第三行
else if(x==3)
x=0x98; //第四行
pos=x+y; //显示哪一行(总共有4行)哪一竖(总共有8竖,每16列为1竖)
#include<STC12C5A60S2.H>
#define uint unsigned int
#define uchar unsigned char
sbit CS=P2^0; //LCD12864串行通信片选
sbit SID=P2^1; //LCD12864串行通信数据口
*******************************************************/
void AD_initiate() //初始化函数
{
ES=0;
TMOD=0x21; //定时计数器方式控制寄存器,"自动重装,16位计数器".
SCON=0x50; //串行控制寄存器,方便在串口助手那观察
sbit SCLK=P2^2; //LCD12864串行通信同步时钟信号
sbit PSB=P2^5; //LCD12864并/串选择:H并行 L串行
unsigned int temp1,sh1,ge1,n1,m1;
unsigned char ad_result_data[10]; //AD转换高八位
write_cmd(pos);
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;
/****************************************************************************
* 文件名:AD_CAIYANG.C
* 功能:使用AD采集电压显示在LCD
* 说明:转自网络,本人验证通过
****************************************************************************/
void caiyangP10() //测电压
{
P1M0|=0x01; //设P1_0为开漏模式 如: P1_0= #00000000B
P1M1|=0x01;
ADC_CONTR=0xe0; //设置P1.0为输入AD转换口
delay(2);
get_ad_result(); //取转换数据
SCLK=0;
SCLK=1; //正跳变写入指令
i_data=i_data<<1; //左移一位
}
/*---------------------------------------*/
/*----------写指令高四位-----------------*/
q=q+ad_average_result;
}
ad_average_result=q/10;
//ad_average_result=ad_average_result*4*5000/1024;
}
/************************AD转换结束***********************/
for(i=0;i<8;i++) //循环八次,每次读取一位数据
{
SID=(bit)(i_data&0x80); //bit表示取其最高位
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);
}
/*-----------------------------------------*/
CS=1; //片选置高,才能进行读写操作
SCLK=0;
/*----------写命令控制字-----------------*/
for(i=0;i<8;i++) //循环八次,每次读取一位数据
{
SID=(bit)(i_data&0x80); //bit表示取其最高位
while(!tp) //判断AD转换是否完成
{
tp=0x10;
tp&=ADC_CONTR;
}
ADC_CONTR&=0xe7;
ad_average_result=ADC_RES;
{
uint i,j;
for(;delay>0;delay--)
for(i=0;i<124;i++);
for(j=0;j<124;j++);
}
/*******************************************************
AD转换程序
unsigned char code num7[]={0xa3,0xb7};
unsigned char code num8[]={0xa3,0xb8};
unsigned char code num9[]={0xa3,0xb9};
//-------模块延时程序---------------------------- 1ms
TH1=0xfa;
TL1=0xfa;
TR1=1;
}
void ADC_Power_On() //AD转换电
{
ADC_CONTR|=0x80;
delay(5); //必要的延时
}
void get_ad_result() //取AD结果函数,它是十位AD转换,每十次平均,最后取低八位作为AD采样数据
void send_ad_result() //取AD结果函数发送到串口,方便调试
{
SBUF=n1;
while(TI==0) ;
TI=0;
delay1ms(100);
//SBUF=R>>4;
}
//---------------------电压采样程序-------------------------
void 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
i_data=i_data<<1; //左移一位
}
/*---------------------------------------*/
/*----------写指令低四位-----------------*/
i_data=cmd;
i_data=i_data<<4; //左移四位,把低四位的数据移到高四位,再把低四位置0
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 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[]={"提示: 按1 键进入"};
}
/*-----------------------------------------*/
CS=0; //把片选置低
delay1ms(5); //延时是因为没有进行忙检测,适当的延时可以不进行忙检测
}
/*-----------------------------------------*/
/*--------------显示坐标-------------------*/
相关文档
最新文档