STC12C2052AD单片机0-9.9V电压表
单片机STC12C2052AD的比例遥控系统

引 言
远程控制技术又 、家用电器 、无线电运动以及儿童 玩具等领域都有非常广泛的应用 。遥控技术可以分为单 通道遥控和多通道遥控 ,也可以分为开关型遥控和比例型 遥控 。
本文主要介绍了使用到单片机部分的控制电路 ,包括 发射机电路和接收机电路 。发射机采用电位器分压作为 比例控制信号 ,由 4 路 A/ D 电路转换为数字信号 ,各个通 道数字信号连同两路开关量由单片机进行多通道编码 ,编 码信号由串行口送出 ,最后由发射模块发射 。接收机主要 负责把收到的信号放大并从中解调出编码信号 ,最后由伺 服机把接收机收到的电信号转换成相应的机械动作 ,由此 实现方向和速度的控制 。
接收机用接收模块将信号接收并解调 ,解调后的信号 送串行口由 STC12C2052AD 译码 ,最后驱动控制执行机 构 。由于本设计的任务简单 ,所以遥控系统对操作的响应 时间并没有严格的要求 ,在 A/ D 转换和串行通信程序设 计中可以采用查询方式 ,将读入的信号转换成相应的控制 信号 ,并用识别标志位的方法识别所对应的控制方式 。接 收单片机的串行口必须与发射机保持一致 。由于改变的 速度值可以直接转换成相应的电信号送入接收单片机的 P1 端口 ,单片机每响应一次外部中断 ,就会在对应的中断 服务程序中根据计算公式增加或减小速度 。当电机处于 正反向调速系统时 ,在正反向调速子程序中根据该速度通 过计算公式可以得到单片机内部定时/ 计数器的初值 。在 开始计数的同时 ,启动相应的控制程序驱动电动机驱动电 路 。定时时间结束的同时 ,停止对相应伺服电路的驱动 , 回到初始化状态 ,准备开始接收新的信号和数据 。相应的 程序流程如图 4 ( b) 所示 。
使用比例遥控的优点有很多 。例如 :控制灵活 ; 可以 调整遥控的距离且调整的最大距离比一般遥控远 ;可以根
由STC12C2052AD单片机控制的改进型调压电路

一种由STC12C2052AD单片机控制的改进型调压电路0 引言在ZXC10通信电源系统中,上位机输出的PWM调制信号的频率为1 kHz,而且系统要求电源能根据PWM信号的占空比进行调压。
即对电源输出电压在40 Vdc~60 Vdc范围内通过此PWM信号进行线性调节。
PWM信号5%占空比对应40±0.5 Vdc,95%的占空比对应60±0.5 Vdc。
以前此功能是用带有D/A的单片机来实现.即把PWM调制信号输入单片机,通过单片机来计算PWM信号的占空比,再根据PWM信号的占空比与输出电压的关系,并通过D/A转换来产生用于调节输出电压的偏移量,最后通过此偏移量和电源输出反馈量的共同作用来实现调压。
1 单片机调压系统通过带有D/A的单片机来实现调压系统的方框图如图1所示。
但是,由于带有D/A的单片机比较贵,因而会增加产品成本。
而如果把PWM 调制信号的频率提高,再经过一个简单的二阶有源低通滤波器来产生调压偏移量,则可用不带D/A转换的单片机来实现调压,这样可以大大节省成本。
其改进后的电路方框图如图2所示。
2 STC12C2052AD的PCA/PWM工作原理由于STC12C2052AD单片机是作于1个时钟/机器周期,且有增强型8051内核,故其速度比普通8051快8~12倍。
该单片机有2路可编程计数器阵列(PCA)/PWM,其中PCA1模块用作捕获模式,可识别输入的PWM调制信号,PCA0模块用作脉宽调节模式(PWM),可实现频率转换。
此外,由于该单片机价格比较便宜,故采用此单片机作为核心控制芯片。
2.1 STC12C2052AD单片机的PCA捕获模式STC12C2052AD系列单片机中的PCA可编程计数器阵列含有一个特殊的16位定时器,它可与2个16位捕获/比较模块相连。
每个模块可编程工作在4种模式下,即:上升/下降沿捕获、软件定时器、高速输出或可调制脉冲输出。
设计时,可将模块0连接到P3.7(CEX0/PCA0/PWM0),模块1连接到P3.5(CEX1/PCA1/PWM1)。
用STC12C2052AD及八位数码管(595)模块扩展模块组成的三键时钟资料讲解

else
{P00=0;}
P26=1;//给一个上升沿
_nop_;
date=date<<1;//8位依次进行判断
}
P25=1;//给rclk一个上升沿
_nop_;
P25=0;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
else hc595(0xff);
delay(4);
hc595(0xff);
hc595(0xff);
}
/********************************************************************
*名称: Time0_Init()
*功能:定时器的初始化,11.0592MZ晶振,50ms
void Time0_Int() interrupt 1
{
TH0 = 0xf6-uTH0; //预置产生时基信号
TL0 = 0x3c;
Time_temp++;
if(Time_temp == t_buf )//1秒,
{
time_buf[2]=time_buf[2]+1;//秒
if ( time_buf[2]>59 ){ time_buf[1]=time_buf[1]+1;time_buf[2]=0;ist=ist+1;}//分
sbit P25=P3^1;//CLK存储寄存器时钟输入
sbit P24=P3^2; //OE使能端
//74hc595函数
void hc595(uchar date)
LCD显示的电压表

LCD显示的电压表#include <STC12C5A.h>#define data P0#define data1 P3#define ge 0x80+0x45#define yi 0x80+0x47 //小数点后一位#define er 0x80+0x48#define san 0x80+0x49/*定义ADC操作控制位,ADC_CONTR:ADC控制寄存器*/#define ADC_POWER 0x80 //ADC 电源控制位#define ADC_FLAG 0x10 //ADC 转换结束标志位#define ADC_START 0x08 //ADC 启动转换位#define ADC_SPEEDLL 0x00 //0010,0000,SPEED1=0,SPEED0=0,420个时钟周期转换一次#define ADC_SPEEDL 0x20 //0010,0000,SPEED1=0,SPEED0=1,280个时钟周期转换一次#define ADC_SPEEDH 0x40 //140个时钟周期转换一次#define ADC_SPEEDHH 0x60 //70个时钟周期转换一次sbit bf=P0^7;sbit rs=P2^0;sbit rw=P2^1;sbit en=P2^2;sbit test3=P3^1;sbit test1=P2^4;/*声明ADC相关特殊功能寄存器*/sfr ADC_LOW2 = 0xBE; //ADC 结果低2位/*----------------------------软件延时函数----------------------------*/void delay500ms (void){unsigned char i,j,k;for(i=15;i>0;i--)for(j=202;j>0;j--)for(k=81;k>0;k--);}void tiaoshi(unsigned char x){ P3=x;while(test1);while(!test1);P3=0xff;}/*----------------------------初始化ADC特殊功能寄存器函数----------------------------*/void InitADC(){ void _nop_(void);P1ASF = 0x01; //将P1所有口线设置成模拟口ADC_RES = 0; //清除上一次的转换结果ADC_LOW2=0;ADC_CONTR = 0x00;ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START ; //设置ADC控制寄存器,包括接通电源、设置转换速度、转换通道、启动A/D转换等_nop_();_nop_();_nop_();_nop_(); //延时}void busy(void){ void _nop_(void);unsigned char x;do{data=0xff;en=1;rs=0;rw=1;_nop_();x=data;en=0;_nop_();}while(x&0x80);}void lcd_wcom(unsigned char com){ busy();rs=0;rw=0;en=1;data=com;en=0;}void lcd_wdat(unsigned char dat){ busy();rs=1;rw=0;en=1;data=dat;en=0;}void lcd_init(){ lcd_wcom(0x38);lcd_wcom(0x0c);lcd_wcom(0x06);lcd_wcom(0x01);}void main(){ void _nop_(void);unsigned char code str0[]="Channel 0:";unsigned char code str1[]=" Vio= . V";unsigned char i;unsigned int temp;unsigned long int temp1;float result;lcd_init();lcd_wcom(0x80);for(i=0; str0[i];i++)lcd_wdat( str0[i] );lcd_wcom(0x80+0x40);for(i=0; str1[i] ;i++)lcd_wdat( str1[i] );while(1){ for(i=100,temp1=0;i>0;i--){ InitADC(); //初始化ADC相关特殊功能寄存器,启动A/D 转换while(!(ADC_CONTR&ADC_FLAG));ADC_CONTR&=~ADC_FLAG;temp=ADC_RES;temp=temp<<2;temp=temp+ADC_LOW2;temp1=temp1+temp;}result=(float)temp1/100;result=result*5/1023;temp=result*1000;i=temp/1000;temp=temp%1000;i=i+0x30;lcd_wcom(ge);lcd_wdat(i);i=temp/100;temp=temp%100;i=i+0x30;lcd_wcom(yi);lcd_wdat(i);i=temp/10;temp=temp%10;i=i+0x30;lcd_wcom(er);lcd_wdat(i);i=temp;i=i+0x30;lcd_wcom(san);lcd_wdat(i);/* delay500ms (); */ }}。
STC12C2052AD之数字电压表099V

STC12C2052AD之数字电压表0-99V做了N个ICL7107的数字电压表头都没有成功,今天改为带AD的单片机了。
AD部分代码来看网络。
电路就不发了。
数码管用四位共阳。
小数点后面有一点跳动,不过对于用面包板搭建的电路,应该算不错吧。
基准电压采用TL431.电压在2.61和2.37之间跳动。
/************************************************ **********************基于STC12C4052AD单片机的0-99V数字电压表程序数码之家首发。
ID:abenyaoP1.6口为0-5V模拟量输入端,P1.5口连接TL431l输出的2.5V基准电源,4位串行LED数码管显示************************************************* *********************/#include ; //单片机头文件#include ; //51基本运算(包括_nop_空函数)#define uchar unsigned char#define uint unsigned int#define LEDBus P3//a3.0-b3.1-c3.2-d3.3-e3.4-f3.5-g3.7-dp1.0#define ON 1//定义0为打开#define OFF 0//定义1为关闭sbit ge=P1^4;//个位位选sbit shi=P1^3;//十位位选sbit bai=P1^2;//百位位选sbit qian=P1^1;//千位位选sbit db=P1^0;char d[5];uint R,M,N;//若定义成uchar型就只能显示2.5V以下的数值uchar codeLEDTab[]={0xc0,0xf9,0x64,0x70,0x59,0x52,0x42,0xf8 ,0x40,0x58};/************************************************ *****************函数名:毫秒级CPU延时函数调用:delay (?);参数:1~65535(参数不可为0)返回值:无结果:占用CPU方式延时与参数数值相同的毫秒时间备注:应用于1T单片机时i;0;t--)//如果t大于0,t减1(外层循环)for(i=600;i>;0;i--);//i等于124,如果i大于0,i减1}/************************************************ *******************函数名:ADC初始化及8位A/D转换函数返回值:8位的ADC数据结果:读出指定ADC接口的A/D转换值,并返回数值备注:适用于STC12C2052AD系列单片机(必须使用STC12C2052AD.h头文件)************************************************* ******************/uchar Read (uchar CHA){uchar AD_FIN=0; //存储A/D转换标志;若在函数外定义此变量则不能得到连续变化的模拟量的显示/******以下为ADC初始化程序****************************/CHA &= 0x07;//选择ADC的8个接口中的一个(0000 0111 清0高5位)ADC_CONTR = 0x60; //ADC转换的速度(0XX0 0000 其中XX控制速度,请根据数据手册设置)_nop_();ADC_CONTR |= CHA;//选择A/D当前通道_nop_();ADC_CONTR |= 0x80;//启动A/D电源delay(1);//使输入电压达到稳定(1ms即可?/******以下为ADC执行程序****************************/ADC_CONTR |= 0x08;//启动A/D转换(0000 1000 令ADCS = 1)_nop_();_nop_();_nop_();_nop_();while (AD_FIN ==0){//等待A/D转换结束AD_FIN = (ADC_CONTR & 0x10); //0001 0000测试A/D转换结束否}ADC_CONTR &= 0xE7;//1111 0111 清ADC_FLAG位, 关闭A/D转换, return (ADC_DATA);//返回A/D转换结果(8位)}/************************************************ ******************显示函数转换函数:M=模拟量采样值,N=基准电压源采样值(本例为2.5V),R=模拟量输入值(待显示值)N=256*2.5/Vcc;变形后得Vcc=256*2.5/N;代入M=256*R/Vcc;得到M=R*N/2.5;变形后得R=M*2.5/N 1.105为输入端分压比。
STC12C2052AD做的频率计

6.
频率测量,頻率信號從 P3.3 口(INT1)輸入,用下降沿觸發方式.產生中斷,開關 定時器 0,測量方波信號周期來計算頻率.定時器 0 工作在 12T 模式下(16 位). N1 計數個數. 頻率=1/周期=1000000/(N1*1/12)=1000000/N1.
流程圖如下: n++ n=1 Time0 關閉 Time0 取數 Time0 清 0 N清0 n=21 Time0 開啟 INT1 中斷
IT1=1; EA=1; ET0=1; TMOD=0x01; EX1=1; TL0=0; TH0=0; T=0; while(1) { xianshi(); cishu++;
/*INT1 為下降沿觸發方式*/ /*開總中斷*/ /*開 Time0 中斷*/ /*設置 Time0 位 16 位計數模式*/ /*開 INT1 中斷*/
電路圖如下:
R 12 10K R 11 10K R 10 10K +5V S8550 R 9 R 17 R 13 20K 10K 10uF /50V R ST P3.0/RXD P3.1/TXD XTAL2 XTAL1 P3.2/INT0 P3.3/INT1 P3.4/T0 P3.5/T1 GND 1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11 VDD P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 P3.7 +5V R 8 150R R 7 150R R 6 150R 12 V1 11 A 9 V2 10 F 7B R 5 150R R 4 150R R 3 150R STC 12C 2052AD R 16 4.7K C 7 100pF/16V R 18 10K Y1 12M 1E 2D 5G 4C C 3 C 5 30P 0.1uF/25V/0603 C 2 50V/22uF C 1 50V/22uF D1 VDD S1060 3 DP 6 V4 C 6 30P R 2 150R R 1 150R F E D A B G C dp F E D A B G C dp F E D A B G C dp F E D 8 V3 10K C 9 Q1 S8550 Q2 S8550 Q3 S85550 Q4
GYJ-0057 STC12C2052AD四位数码管显示可编程单路输入输出继电器工控板

【接线说明】【输入控制设备】【输出控制设备】【NPN输人开关接线方式举例说明】【PNP输人开关接线方式举例说明】【输出举例说明】【输出举例说明】(开关量输出、干接点输出)【UART通信说明】也可以通过TTL下载【原理图】提供PDF格式/******************************************************************** 程序说明:1、P1.7口输入开关信号控制数码管开始延时。
2、当数码管延时时间达到59分99秒时继电器吸合并保持吸合状态。
********************************************************************/#include<STC12C2052AD.h> //库文件#include<intrins.h>#define uchar unsigned char //宏定义字符型变量#define uint unsigned int //宏定义整型变量/********************************************************************IO口定义********************************************************************/uint playdate;uint datef=0;uint datem=0;uint sec; //定义计数值,每过1/10 秒,sec 加一uchar biaozhi=0;//按下次数值uint tcnt; //键值判断sbit P10=P1^0;//数码管段sbit P11=P1^1;//数码管段sbit P12=P1^2;//数码管段sbit P13=P1^3;//数码管段sbit P14=P1^4;//数码管段sbit P15=P1^5;//数码管段sbit P16=P1^6;//数码管段sbit P17=P1^7;//AD信号输入sbit P30=P3^0;//按键输入sbit P31=P3^1;//按键输入sbit P32=P3^2;//数码管位sbit P33=P3^3;//数码管位sbit P34=P3^4;//数码管位sbit P35=P3^5;//数码管位sbit OUT=P3^7; //继电器输出/********************************************************************初始定义*********************************************************************/code uchar seg7code[10]={ 0x84,0xf6,0x8a,0xa2,0xf0,0xa1,0x81,0xb6,0x80,0xa0}; //显示段码数码管字跟/********************************************************************延时函数*********************************************************************/void delay1(uchar t){uchar i,j;for(i=0;i<t;i++){for(j=13;j>0;j--);{ ;}}}/********************************************************************延时函数*********************************************************************/ void delay()//延时程序0.1秒{uchar m,n,s;for(m=10;m>0;m--)for(n=20;n>0;n--)for(s=248;s>0;s--);}/********************************************************************显示函数*********************************************************************/ void Led() //显示函数{/*****************数据转换*****************************/uint z,x,c,v;z=datef%100/10;; //求分十位x=datef%10; //求分个位c=datem%100/10; //求秒十位v=datem%10; //求秒个位P1M0=0X00;P1M1=0XFF;P3M0=0X00;P3M1=0XFF;P32=0;P33=0;P34=0;P35=0;P1=seg7code[z];P32=1;P33=0;P34=0;P35=0;delay1(80);P32=0;P33=0;P34=0;P35=0;P1=seg7code[x];P32=0;P33=1;P34=0;P35=0;delay1(80);P32=0;P33=0;P34=0;P35=0;P1=seg7code[c];P32=0;P33=0;P34=0;P35=1;delay1(80);P32=0;P33=0;P34=0;P35=0;P1=seg7code[v];P32=0;P33=0;P34=1;P35=0;delay1(80);P32=0;P33=0;P34=0;P35=0;}/********************************************************************按键函数*********************************************************************/void key(){if((P17==0)&&(biaozhi==0)){ delay1(250);if(P17==0){TR0=1;sec=0; OUT=1;biaozhi=1;}} }/********************************************************************定时中断服务函数*********************************************************************/ void t0(void) interrupt 1 using 0 //定时中断服务函数{tcnt++; //每过250ust tcnt 加一if(tcnt==3694) //计满400 次(1/10 秒)时4000为秒{tcnt=0; //重新再计sec++;if(sec==3600) //单位为秒60分00秒{OUT=0;TR0=0;//sec=0;}}}/********************************************************************主函数*********************************************************************/ void main(){TMOD=0x02; //定时器工作在方式2TH0=0x06; //对TH0 TL0 赋值TL0=0x06;TR0=0; //开始定时ET0=1;EA=1;sec=0;OUT=1;biaozhi=0;while(1){key();Led();datef=sec/60;datem=sec%60;}}/********************************************************************程序结束*********************************************************************/#include<STC12C2052AD.h> //库文件#include<intrins.h>#define uchar unsigned char //宏定义字符型变量#define uint unsigned int //宏定义整型变量/*声明SFR 相关与的IAP*/sfr IAP_DATA = 0xE2;sfr IAP_ADDRH = 0xE3;sfr IAP_ADDRL = 0xE4;sfr IAP_CMD = 0xE5;sfr IAP_TRIG = 0xE6;sfr IAP_CONTR = 0xE7;/********************************************************************定义ISP/IAP/EEPROM 命令*********************************************************************/ #define CMD_IDLE 0#define CMD_READ 1#define CMD_PROGRAM 2#define CMD_ERASE 3#define ENABLE_IAP 0x83//SYSCLK<12MH#define IAP_ADDRESS 0x0000 //存储地址/********************************************************************IO口定义********************************************************************/ bit write=0;uchar biaozhi=6;//按下次数值uint tcnt,sec; //键值判断uint datA,datB; //接通和断开存储值uchar tg,ts,tb; //接通个十百标志uchar dg,ds,db; //断开个十百标志uchar TDbz=0;//通断标志bit bz1=0;//输入标志sbit P10=P1^0;//数码管段sbit P11=P1^1;//数码管段sbit P12=P1^2;//数码管段sbit P13=P1^3;//数码管段sbit P14=P1^4;//数码管段sbit P15=P1^5;//数码管段sbit P16=P1^6;//数码管段sbit P17=P1^7;//AD信号输入sbit P30=P3^0;//按键输入sbit P31=P3^1;//按键输入sbit P32=P3^2;//数码管位sbit P33=P3^3;//数码管位sbit P34=P3^4;//数码管位sbit P35=P3^5;//数码管位sbit OUT=P3^7; //继电器输出/********************************************************************初始定义*********************************************************************/code uchar seg7code[10]={0xfB,0x89,0xf5,0xDD,0x8F,0xdE,0xfE,0xc9,0xfF,0xdF}; //显示段码数码管字跟/********************************************************************延时函数*********************************************************************/void delay1(uchar t){uchar i,j;for(i=0;i<t;i++){for(j=13;j>0;j--);{ ;}}}/********************************************************************延时函数*********************************************************************/ void delay()//延时程序0.1秒{uchar m,n,s;for(m=10;m>0;m--)for(n=20;n>0;n--)for(s=248;s>0;s--);}/********************************************************************接通显示函数*********************************************************************/ void LedT() //显示函数{/*****************数据转换*****************************/uint x,c,v;x=datA/100; //求百位c=datA%100/10; //求十位v=datA%10; //求个位P32=1;P33=1;P34=1;P35=1;P1=0Xef; //显示字母AP32=0;P33=1;P34=1;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;P1=seg7code[x];P32=1;P33=0;P34=1;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;P1=seg7code[c];P32=1;P33=1;P34=1;P35=0;delay1(80);P32=1;P33=1;P34=1;P35=1;P1=seg7code[v];P32=1;P33=1;P34=0;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;}/********************************************************************断开显示函数*********************************************************************/ void LedD() //显示函数{/*****************数据转换*****************************/uint x,c,v;x=datB/100; //求百位c=datB%100/10; //求十位v=datB%10; //求个位P32=1;P33=1;P34=1;P35=1;P1=0Xbe; //显示字母BP32=0;P33=1;P34=1;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;P1=seg7code[x];P32=1;P33=0;P34=1;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;P1=seg7code[c];P32=1;P33=1;P34=1;P35=0;delay1(80);P32=1;P33=1;P34=1;P35=1;P1=seg7code[v];P32=1;P33=1;P34=0;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;}/********************************************************************显示A函数*********************************************************************/ void LedA() //显示函数{/*****************数据转换*****************************/P32=1;P33=1;P34=1;P35=1;P1=0Xef; //显示字母BP32=0;P33=1;P34=1;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;}/********************************************************************显示B函数*********************************************************************/ void LedB() //显示函数{/*****************数据转换*****************************/P32=1;P33=1;P34=1;P35=1;P1=0Xbe; //显示字母BP32=0;P33=1;P34=1;P35=1;delay1(80);P32=1;P33=1;P34=1;P35=1;}/********************************************************************按键函数*********************************************************************/void key(){if(P30==0){delay();if(P30==0){TR0=0;biaozhi++;if(biaozhi>6){biaozhi=0;}datA=tb*100+ts*10+tg;datB=db*1 00+ds*10+dg;while(!P30);write=1;}}if(biaozhi==0){LedA();P1=seg7code[tb];P32=1;P33=0;P34=1;P35=1;delay1(80);if(P31==0){delay();if(P 31==0){tb++; if(tb>9)tb=0;}while(!P31);}}if(biaozhi==1){LedA();P1=seg7code[ts];P32=1;P33=1;P34=1;P35=0;delay1(80);if(P31==0){delay();if(P 31==0){ts++; if(ts>9)ts=0;}while(!P31);}}if(biaozhi==2){LedA();P1=seg7code[tg];P32=1;P33=1;P34=0;P35=1;delay1(80);if(P31==0){delay();if(P 31==0){tg++; if(tg>9)tg=0;}while(!P31);}}if(biaozhi==3){LedB();P1=seg7code[db];P32=1;P33=0;P34=1;P35=1;delay1(80);if(P31==0){delay();if( P31==0){db++; if(db>9)db=0;}while(!P31);}}if(biaozhi==4){LedB();P1=seg7code[ds];P32=1;P33=1;P34=1;P35=0;delay1(80);if(P31==0){delay();if(P 31==0){ds++; if(ds>9)ds=0;}while(!P31);}}if(biaozhi==5){LedB();P1=seg7code[dg];P32=1;P33=1;P34=0;P35=1;delay1(80);if(P31==0){delay();if( P31==0){dg++; if(dg>9)dg=0;}while(!P31);datA=tb*100+ts*10+tg;datB=db*100+ds*10+dg;}}if(biaozhi==6){if(TDbz==0){LedT();}if(TDbz==1){LedD();}}/********************************************************************定时中断服务函数*********************************************************************/ void t0(void) interrupt 1 using 0 //定时中断服务函数{tcnt++; //每过250ust tcnt 加一if(tcnt==3810) //计满400 次(1/10 秒)时4000为秒{tcnt=0; //重新再计if(TDbz==0){datA--;if(datA==0){TDbz=1;OUT=0;}}if(TDbz==1){datB--;if(datB==0){TDbz=0;OUT=1;TR0=0;}}}}/******************************************************************** 禁用ISP/IAP/EEPROM functionmake 单片机在一安全状态*********************************************************************/ void IapIdle(){IAP_CONTR = 0; //IAP_CMD = 0; //IAP_TRIG = 0; //IAP_ADDRH = 0x80; //IAP_ADDRL = 0; //}/********************************************************************读数据*********************************************************************/uchar IapReadByte(uint addr){uchar dat;IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_READ;IAP_ADDRL = addr;IAP_ADDRH = addr >> 8;IAP_TRIG = 0x46;IAP_TRIG = 0xb9;_nop_();dat = IAP_DATA;IapIdle();return dat;}/********************************************************************写数据*********************************************************************/void IapProgramByte(uint addr, uchar dat){IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_PROGRAM;IAP_ADDRL = addr;IAP_ADDRH = addr >> 8;IAP_DATA = dat;IAP_TRIG = 0x46;IAP_TRIG = 0xb9;_nop_();IapIdle();}/********************************************************************擦除数据*********************************************************************/void IapEraseSector(uint addr){IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_ERASE;IAP_ADDRL = addr;IAP_ADDRH = addr >> 8;IAP_TRIG = 0x46;IAP_TRIG = 0xb9;_nop_();IapIdle();}/********************************************************************主函数*********************************************************************/ void main(){TMOD=0x02; //定时器工作在方式2TH0=0x06; //对TH0 TL0 赋值TL0=0x06;TR0=0; //定时开关ET0=1;EA=1;sec=0;OUT=1;P1M0=0X00;P1M1=0X7F;P3M0=0X00;P3M1=0XFF;tb = IapReadByte(0x01); //读取0x01中的数据ts = IapReadByte(0x02); //读取0x02中的数据tg = IapReadByte(0x03); //读取0x03中的数据db = IapReadByte(0x04); //读取0x02中的数据ds = IapReadByte(0x05); //读取0x03中的数据dg = IapReadByte(0x06); //读取0x03中的数据datA=tb*100+ts*10+tg;datB=db*100+ds*10+dg;P17=1;while(1){if((P17==0)&&(bz1==0)){delay1(180);if(P17==0){bz1=1;TR0=1;OUT=1;tcnt=0;datA=tb*100+ts*10+tg;datB=db*100+ds*10+dg;}}if((P17==1)&&(bz1==1)){bz1=0;}key();if(write==1){write=0;IapEraseSector(0); //擦除扇区IapProgramByte(0x01,tb);//写入数据IapProgramByte(0x02,ts);//写入数据IapProgramByte(0x03,tg);//写入数据IapProgramByte(0x04,db);//写入数据IapProgramByte(0x05,ds);//写入数据IapProgramByte(0x06,dg);//写入数据}}}/********************************************************************程序结束*********************************************************************/ #include<STC12C2052AD.h>#include<intrins.h>#include<math.h>#include "INTRINS.H"#define uchar unsigned char //宏定义字符型变量#define uint unsigned int //宏定义整型变量sfr IAP_DATA = 0xE2;sfr IAP_ADDRH = 0xE3;sfr IAP_ADDRL = 0xE4;sfr IAP_CMD = 0xE5;sfr IAP_TRIG = 0xE6;sfr IAP_CONTR = 0xE7;#define CMD_IDLE 0#define CMD_READ 1#define CMD_PROGRAM 2#define CMD_ERASE 3#define ENABLE_IAP 0x83//SYSCLK<12MH#define IAP_ADDRESS 0x0000 //存储地址void IapEraseSector(uint addr);//擦除数据void IapProgramByte(uint addr, uchar dat);//写数据uchar IapReadByte(uint addr);//读数据void IapIdle();//禁用ISP/IAP/EEPROM functionmake 单片机在一安全状态bit flag_eeprom1=0;//掉电存储的标志位sbit P32=P3^2;//数码管位sbit P33=P3^3;//数码管位sbit P34=P3^4;//数码管位sbit P35=P3^5;//数码管位sbit pa = P1^6;sbit pb = P1^0;sbit pc = P1^3;sbit pd = P1^4;sbit pe = P1^5;sbit pf = P1^1;sbit pg = P1^2;uint tcnt1=0;//用于刷新数码管uint g_uistopwatch1=0;//全局变量,在数码管上显示的一个变量uint qiannum1,bainum1,shinum1,genum1;unsigned int qiannum11,bainum11=0,shinum11=0,genum11=0;//用于传到数码管上显示sbit key1=P3^0;//key1sbit key2=P3^1;//key2sbit in=P1^7;//insbit out=P3^7;//outunsigned int innum=0;void seg7code(unsigned char num);void P3t1();void timer0_1init(void);//定时配置static unsigned char presstime=0;//时间值按键用到的unsigned int kf0=1;//按键用的标志位unsigned int kt0=0;//按键用的标志位void keyflag();//按键结束调用unsigned int if0=1,if1=1;unsigned int keynum=0;//数码管的位unsigned int inum1=0;unsigned char inum11=0,inum12=0,innum1=0,innum2=0;void displaynums(){//将数字传到数码管上显示if(if0==1){g_uistopwatch1=innum;if(innum>=inum1){out=0;}else{out=1;}}else{inum1=qiannum11*1000+bainum11*100+shinum11*10+genum11; //将num1三个数码管的值付给inumg_uistopwatch1=inum1;}}void keycan(){//按键if(key1==0){//当按键1按下if(kf0){//当标志位kf0=1的时候进行if(presstime>80){//当时间值大于一百的时候kf0=0;//标志位kf0=0kt0=1;//标志位kt0=0presstime=0;//时间清零,重新进行if0=0;if1=1;keynum++;//数码管的位if(keynum==5){//当位到4则置位0keynum=0;if0=1;}}}}else{//当按键松开keyflag();}//按键1结束if(key2==0){if(kf0){if(presstime>80){kf0=0;kt0=1;presstime=0;flag_eeprom1=1;if(keynum==0){if1++;if(if1==2){if0=0;}if(if1==3){innum=0;if1=1;if0=1;}}else{switch(keynum){case 1:qiannum11++;//数码管一加加if(qiannum11>9){//当数码管一加加到9时置为1qiannum11=0;}break;case 2:bainum11++;if(bainum11>9){bainum11=0;}break;case 3:shinum11++;if(shinum11>9){shinum11=0;}break;case 4:genum11++;if(genum11>9){genum11=0;}break;default:break;}}}}}else{keyflag();}//松开按键进行显示}void main(){P1M0=0X00;P1M1=0XFF;timer0_1init();inum11 = IapReadByte(0x01); //读取0x01中的数据inum12 = IapReadByte(0x02); //读取0x01中的数据innum1 = IapReadByte(0x03); //读取0x01中的数据innum2 = IapReadByte(0x04); //读取0x01中的数据inum1=inum11*100+inum12;innum=innum1*100+innum2;g_uistopwatch1=innum;qiannum11=inum1/1000;bainum11=inum1/100%10;shinum11=inum1/10%10;genum11=inum1%10;while(1){keycan();//按键displaynums();if(in==0){//in按下if(kf0){//当标志位kf0=1的时候进行if(presstime>80){//当时间值大于一百的时候kf0=0;//标志位kf0=0kt0=1;//标志位kt0=0presstime=0;//时间清零,重新进行flag_eeprom1=1;innum++;}}}else{//当按键松开keyflag();}//in结束if(flag_eeprom1==1){//加掉电存储,必需加到这,不然有一些小问题flag_eeprom1=0;inum11=inum1/100;//把int型的值拆分到char型inum12=inum1%100;innum1=innum/100;//把int型的值拆分到char型innum2=innum%100;IapEraseSector(0); //擦除扇区IapProgramByte(0x01,inum11);//写入数据IapProgramByte(0x02,inum12);//写入数据IapProgramByte(0x03,innum1);//写入数据IapProgramByte(0x04,innum2);//写入数据}}}void timer0(void)interrupt 1 {//500等于1秒TL0 = 0xCD; //重新设置定时器0时间为2msTH0 = 0xF8; //重新设置定时器0的初始值tcnt1++;presstime++;genum1=g_uistopwatch1%10;//个位shinum1=g_uistopwatch1%100/10;//十位bainum1=g_uistopwatch1%1000/100;//百位qiannum1=g_uistopwatch1/1000;//qian位switch(tcnt1){case 1:P3t1();seg7code(qiannum1);if(keynum==1 || keynum==0){P32=0;}break;case 2:P3t1();seg7code(bainum1); if(keynum==2 || keynum==0){P33=0;}break;case 3:P3t1();seg7code(shinum1); if(keynum==3 || keynum==0){P35=0;}break;case 4:P3t1();seg7code(genum1); if(keynum==4 || keynum==0){P34=0;}break;default:tcnt1=0;break;}}void timer0_1init(void){//定时配置TMOD=0x11;//将定时器0,1都设置为模式1TL0 = 0xCD;//设置定时器0时间为2msTH0 = 0xF8;//设置定时器0的初始值TR0=1;//开启定时器0TR1=1;//开启定时器1EA=1;//开总中断ET0=1;//开定时器0的中断}void s0(){pa = 1;pb = 1;pc = 1;pd = 1;pe = 1;pf = 1;pg = 0;} void s1(){pb = 1;pc = 1;pa = 0;pg = 0;pd = 0;pe = 0;pf = 0;} void s2(){pa = 1;pb = 1;pg = 1;pe = 1;pd = 1;pf = 0;pc = 0;} void s3(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 0;pe = 0;} void s4(){pb = 1;pg = 1;pc = 1;pf = 1;pa = 0;pd = 0;pe = 0;} void s5(){pa = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 0;pb = 0;} void s6(){pa = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 1;pb = 0;} void s7(){pa = 1;pb = 1;pc = 1;pf = 0;pe = 0;pd = 0;pg = 0;} void s8(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 1;} void s9(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 0;} void s10(){pa =0;pb = 0;pc = 0;pf = 0;pe = 0;pd = 0;pg = 0;} void seg7code(unsigned char num){if(num == 0){s0();}else if(num == 1){s1();}else if(num == 2){s2();}else if(num == 3){s3();}else if(num == 4){s4();}else if(num == 5){s5();}else if(num == 6){s6();}else if(num == 7){s7();}else if(num == 8){s8();}else if(num == 9){s9();}}void P3t1(){P32=1;P33=1;P34=1;P35=1;}void keyflag(){//按键结束调用,按键的建议使用,这样可以减小code,但是触发的不建议if(kt0){//当标志位kt0=1的时候进行if(presstime>50){//当时间值大于一百的时候kf0=1;//标志位kf0=1kt0=0;//标志位kt0=0presstime=0;//时间清零,重新进行}}}/********************************************************************禁用ISP/IAP/EEPROM functionmake 单片机在一安全状态*********************************************************************/void IapIdle(){IAP_CONTR = 0; //IAP_CMD = 0; //IAP_TRIG = 0; //IAP_ADDRH = 0x80; //IAP_ADDRL = 0; //}/********************************************************************读数据*********************************************************************/uchar IapReadByte(uint addr){uchar dat;IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_READ;IAP_ADDRL = addr;IAP_ADDRH = addr >> 8;IAP_TRIG = 0x46;IAP_TRIG = 0xb9;_nop_();dat = IAP_DATA;IapIdle();return dat;}/********************************************************************写数据*********************************************************************/void IapProgramByte(uint addr, uchar dat){IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_PROGRAM;IAP_ADDRL = addr;IAP_ADDRH = addr >> 8;IAP_DATA = dat;IAP_TRIG = 0x46;IAP_TRIG = 0xb9;_nop_();IapIdle();}/********************************************************************擦除数据*********************************************************************/void IapEraseSector(uint addr){IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_ERASE;IAP_ADDRL = addr;IAP_ADDRH = addr >> 8;IAP_TRIG = 0x46;IAP_TRIG = 0xb9;_nop_();IapIdle();}【尺寸图】【图片展示】【加装配套外壳效果】。
STC12C2052做的多路AD测语言

sendbyte(MM_G);wela3=ON;
delayms(3);
wela3=OFF;
sendbyte(HH_D);wela2=ON;
delayms(3);
wela2=OFF;
if(HH_G==0)//如果第1位数码管是0,不显示
num>>=1;
}
}
//这是我用STC12C2052AD做的多路测试电压,一共八路AD不同电压显示不同值;
void display(uint z)//显示子函数
{
HH_G=z/1000;
HH_D=z%1000/100;
while (1) //等待A/D转换结束
{
if(ADC_CONTR&0x10) //0001,0000 测试A/D转换结束否
{ break;}
}
ADC_CONTR=0xe7; //ADC_CONTR &= 0xE7;1111,0111 清 ADC_FLAG 位, 关闭A/D转换,
return ADC_DATA; //返回 A/D 10 位转换结果
}
void ()
{
W=0;
InitADC();
while(1)
{uint ADC();
//V=ADC(); W=ADC();
if(176<ADC()&&ADC()<182)//************3.5V
{
z=2222;delayms(50);
x=2;
if(151<ADC()&&ADC()<155)//********3.0V
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
case 6:A=0;B_B=1;C=0;D=0;E=0;F=0;G=0;H=1;break;
case 7:A=0;B_B=0;C=0;D=1;E=1;F=1;G=1;H=1;break;
case 8:A=0;B_B=0;C=0;D=0;E=0;F=0;G=0;H=1;break;
由STC12C2052AD单片机制作的0-9.9V电压表
这款由电子乐屋原创的电路简单制作容易的STC12C2052AD单片机的0-9.9V电压表,电路简单,元件少,容易制作,PCB板为单面板,下面是制作好的实物。
#include <STC12C2052AD.H>//单片机头文件
#include <intrins.h>//51基本运算(包括_nop_空函数)
sbit A=P1^1;
sbit B_B=P1^5;
sbit C=P3^2;
sbit D=P3^4;源自sbit E=P3^5;sbit F=P1^2;
sbit G=P3^1;
sbit H=P3^3; //小数点
char d[5];
uint R,M,N,h;//若定义成uchar型就只能显示2.5V以下的数值
d[2]=R/100;
R=R%100;
d[1]=R/10;
d[0]=R%10;
}
/**********显示函数(未优化)************************************************/
void xian_shi (void)
{
if(h>999)
{
d[3]=10;
d[2]=10;
d[1]=10;
d[0]=10;
}
if(d[3]==0)
d[3]=11;
dm(d[3]);
LED3=1;
delayus(5);
LED3=0;
delayus(30);
dm(d[2]);
LED2=1;
delayus(5);
LED2=0;
delayus(30);
dm(12);
LED2=1;
delayus(1);
void transfer(void)
{
M=Read(6);//P1.6口模拟量转换
N=Read(7);//P1.7口2.5V基准电压源采样(转换)
R=((M*2.5)/N)*198;//输入模拟量换算并放大500倍;
/***以下为3位显示转换***/
h=R;
d[3]=R/1000;
R=R%1000;
{
AD_FIN = (ADC_CONTR & 0x10);//0001 0000测试A/D转换结束否
}
ADC_CONTR &= 0xE7;//1111 0111清ADC_FLAG位,关闭A/D转换,
return (ADC_DATA);//返回A/D转换结果(8位)
}
/******************************************************************
/******以下为ADC执行程序****************************/
ADC_CONTR |= 0x08; //启动A/D转换(0000 1000令ADCS = 1)
_nop_();
_nop_();
_nop_();
_nop_();
while (AD_FIN ==0)//等待A/D转换结束
LED3=0;
while(1)
{
uint i;
i++;
if (i==500)
{
transfer();
i=0;
}
xian_shi();
}
}
void dm(mz);
void delayus(uint x)//(x+1)*6微
{
while(x--);
}
/*****************************************************************
函数名:毫秒级CPU延时函数
调用:delay (?);
参数:1-65535(参数不可为0)
for(;t>0;t--)//如果t大于0,t减1(外层循环)
for(i=600;i>0;i--); //i等于124,如果i大于0,i减1
}
/*******************************************************************
函数名:ADC初始化及8位A/D转换函数
case 12:A=1;B_B=1;C=1;D=1;E=1;F=1;G=1;H=0;break; //小数点
}
}
/******************************************************************
函数名:主函数
调用:无
参数:无
返回值:无
结果:程序开始处,无限循环
case 1:A=1;B_B=0;C=0;D=1;E=1;F=1;G=1;H=1;break;
case 2:A=0;B_B=0;C=1;D=0;E=0;F=1;G=0;H=1;break;
case 3:A=0;B_B=0;C=0;D=0;E=1;F=1;G=0;H=1;break;
case 4:A=1;B_B=0;C=0;D=1;E=1;F=0;G=0;H=1;break;
返回值:无
结果:占用CPU方式延时与参数数值相同的毫秒时间
备注:应用于1T单片机时i<600,应用于12T单片机时i<125
/******************************************************************/
void delay(uint t)
{
uint i;//定义变量
#define uchar unsigned char
#define uint unsigned int
sbit temp=P1^7;
sbit LED3=P3^0; //C
sbit LED0=P1^4; //小数点后一位
sbit LED1=P1^3; //个位
sbit LED2=P1^0; //十位
返回值:8位的ADC数据
结果:读出指定ADC接口的A/D转换值,并返回数值
备注:适用于STC12C2052AD系列单片机(必须使用STC12C2052AD.h头文件)
*******************************************************************/
ADC_CONTR = 0x60;//ADC转换的速度(0XX0 0000其中XX控制速度,请根据数据手册设置)
_nop_();
ADC_CONTR |= CHA; //选择A/D当前通道
_nop_();
ADC_CONTR |= 0x80;//启动A/D电源
delay(1);//使输入电压达到稳定(1ms即可?
备注:
******************************************************************/
void main (void)
{
P1M0 = 0xC0;
P1M1 = 0x19;
P3M0=0x00;
P3M1=0x01;
LED0=0;
LED1=0;
LED2=0;
显示函数转换函数:
M=模拟量采样值,N=基准电压源采样值(本例为2.5V),R=模拟量输入值(待显示值)
N=256*2.5/Vcc;变形后得Vcc=256*2.5/N;代入M=256*R/Vcc;得到M=R*N/2.5;变形后得R=M*2.5/N
1.105为输入端分压比。
******************************************************************/
LED2=0;
delayus(400);
dm(d[1]);
LED1=1;
delayus(5);
LED1=0;
delayus(30);
dm(d[0]);
LED0=1;
delayus(5);
LED0=0;
delayus(30);
}
void dm(mz)
{
switch(mz)
{
case 0:A=0;B_B=0;C=0;D=0;E=0;F=0;G=1;H=1;break;
uchar Read (uchar CHA)
{
uchar AD_FIN=0;//存储A/D转换标志;若在函数外定义此变量则不能得到连续变化的模拟量的显示
/******以下为ADC初始化程序****************************/
CHA &= 0x07; //选择ADC的8个接口中的一个(0000 0111清0高5位)
case 9:A=0;B_B=0;C=0;D=0;E=1;F=0;G=0;H=1;break;
case 10:A=0;B_B=1;C=1;D=0;E=0;F=0;G=1;H=1;break; //C
case 11:A=1;B_B=1;C=1;D=1;E=1;F=1;G=1;H=1;break; //不显示