STC12C5A60AD主板原理图
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); //延时}}。
STC12c5a60s2官方手册AD程序(中文注释)
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串行显示终极程序-带滤波
本程序是以电流采集为例的,采集的是电流传感器输出的电压,然后转换成电流,如果只需要采集电压的话将转化为电流的语句删除即可。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自带的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);}}。
第2章STC系列单片机的结构与原理全
SS
SPI同步串行接口的从机选择信号端
P1.4
CCP1
PCA模块1的外部捕获触发信号输入、脉 冲输出及PWM输出
P1.5
MISO
SPI同步串行接口的主入从出(主器件的 输入和从器件的输出)
P1.6
MOSI
SPI同步串行接口的主出从入(主器件的 输出和从器件的输入)
P1.7
SCLK
SPI同步串行接口的时钟信号
P3.1 TxD
P3.2
INT 0
P3.3
INT1
T0
P3.4 CLKOUT0
INT T1
P3.5 CLKOUT1
INT
P3.6
WR
P3.7
RD
功能
串行口1数据接收端 串行口1数据发送端 外部中断0触发端,低电平或下降沿有效 外部中断1触发端,低电平或下降沿有效 定时/计数器T0工作在计数状态时外部信号输入端 时钟输出端 T0外部引脚下降沿触发中断 定时/计数器T1工作在计数状态时外部信号输入端 时钟输出端 T1外部引脚下降沿触发中断
• (3)VCC:电源正极。 • (4)GND:电源负极
19
2.4程序状态字寄存器
• 程序状态字寄存器PSW
D7 D6 D5 D4 D3 D2 D1 D0
CY AC F0 RS1 RS0 OV F1 P
C当C当位A在有YY运运时O在超表C—=执进P用A偶算算,—V1执出示——行位寄—;于数结结—C行溢8进—加或存—位记 则Y果 果辅加 出位奇法 借器溢有=录清的的助法,或用0偶或位中出符A零最最。进或O借户校减,寄1标号。高高位V的减位标验法则存志置数只位位标个法标识标指A器位1表要产没志数,运志C位志令中。示A生有位置为否算位0R位时1寄的择进产。位奇的S则时。。,存范1位生,数个O,、若器围,或进工V否,数若RD中清-用者位作则1S则的运3的零20位来借或寄A奇P8算:数。C-置向选位者存偶的寄清据+位D择时借器性结存1零4发,2当,组位。果用器。7生为前,若户组改的标选识位1 变,就会影响奇偶校验位P。
STC12C5A60S2单片机引脚图
STC12C5A60S2单片机引脚图
STC12C5A60S2单片机引脚图
来源:21ic 作者:
关键字:STC12C5A60S2 单片机引脚图
P0。
0—P0。
7(39—32):P0口是一个漏极开路型准双向I/O口.在访问外部存储器时,它是分时
多路转换的地址(低8位)和数据总线,在访问期间激活了内部的上拉电阻.在EPROM编程时,它接收
指令字节,而在验证程序时,则输出指令字节。
验证时,要求外接上拉电阻。
P1。
0—P1。
7(1-8):P1口是带内部上拉电阻的8位双向I/O口.在EPROM编程和程序验证时,
它接收低8位地址。
P2.0—P2.7(21-28):P2口是一个带内部上拉电阻的8位双向I/O口。
在访问外部存储器时,它
送出高8位地址。
在对EFROM编程和程序验证期间,它接收高8位地址。
P3.0—P3。
7(10-17):P3口是一个带内部上拉电阻的8位双向I/O口。
stcc单片机开发板电路原理图
4
模拟量采集ADC
AD/DA转换 VCC
AD按键
AIN0
SW21
VCC
C5 10uF C6 0.1uF U6
AIN0
1
16
D3 LED
R37
SW SPST
R38 100_1%
AIN1 AIN2 AIN3
2 AIN0 3 AIN1 4 AIN2
VDD 15 AOUT 14 VREF 13
R34 2K VCC
10K
SW22
5 AIN3 AGND 12
6 A0
EXT 11
7 A1
OSC 10
SCL
8 A2
SCL 9
SDA
D
SW SPST
R40
GND SDA
100_1%
PCF8591 宽体,封装:SO16WB
SW23
VT SW24 SW SPST
R46 100_1%
R48 100_1%
R21 100
P33 C1 10uF
IR GND VCC
红外发送38KHz
VCC R49 1.25K
R52 2K P34
8 VCC
4 MR
U10
A
7
DIS
VCC
R50 1.25K
6 TH
3 R51 100 VO
D6 LED_IR
C16 0.01uF
1 GND
5 CO
2 TR
NE555
封装:SO8NB
R28 2K R29 2K R32 2K R33 2K
GND
B
电源输入
VCC
IN
C14 0.1uF
+ CE1 100uF/16v
宏晶科技 STC12C5A60AD STC12C5201AD 系列单片机 器件手册
STC12C5A60AD系列单片机器件手册 STC12C5201AD系列单片机器件手册 --- 1个时钟/机器周期8051 ---无法解密 ---低功耗,超低价 ---高速,高可靠 ---强抗静电,强抗干扰STC12C5A08, 12C5A08AD, 12C5A08S2STC12C5A16, 12C5A16AD, 12C5A16S2STC12C5A20, 12C5A20AD, 12C5A20S2STC12C5A32, 12C5A32AD, 12C5A32S2STC12C5A40, 12C5A40AD, 12C5A40S2STC12C5A48, 12C5A48AD, 12C5A48S2STC12C5A52, 12C5A52AD, 12C5A52S2STC12C5A56, 12C5A56AD, 12C5A56S2STC12C5A60, 12C5A60AD, 12C5A60S2STC12C5A62, 12C5A62AD, 12C5A62S2宏晶科技www.MCU-Memory.comUpdate date: 2008-11-22 STC12C5A60AD系列单片机器件手册 STC12C5201AD系列单片机器件手册 --- 1个时钟/机器周期8051 ---无法解密 ---低功耗,超低价 ---高速,高可靠 ---强抗静电,强抗干扰STC12C5201, 12C5201PWM, 12C5201ADSTC12C5202, 12C5202PWM, 12C5202ADSTC12C5204, 12C5204PWM, 12C5204ADSTC12C5205, 12C5205PWM, 12C5205ADSTC12C5206, 12C5206PWM, 12C5206ADSTC12LE5201,12LE5201PWM,12LE5201ADSTC12LE5202,12LE5202PWM,12LE5202ADSTC12LE5204,12LE5204PWM,12LE5204ADSTC12LE5205,12LE5205PWM,12LE5205ADSTC12LE5206,12LE5206PWM,12LE5206AD宏晶科技www.MCU-Memory.comUpdate date: 2008-11-22宏晶科技是新一代增强型8051单片机标准的制定者和领导厂商,致力于提供满足中国市场需求的世界级高性能单片机技术,在业内处于领先地位,销售网络覆盖全国。
STC12C5A60S2-AD电压高级采集
STC12C5A60S2-AD电压高级采集/*使用STC单片机内置10AD(仅用高八位,分辨率为5mV)做的简易电压表*//*本程序AD部分使用了深圳宏晶公司官方AD转换示范程序修改, 特此鸣谢*//*使用STC12C5A60S2 1T单片机,12M外部晶振,Keil V3编译通过,AD转换脚定义为P1.1, *//*使用芯片本身5V电源为基准,在深圳精创电子的51/AVR开发板实现。
8位共阳LED字符码*//*接P0口,位线接在P2口,均为低电平显示,使用右4位。
本显示程序摘自网上,一并感谢。
*//*----2010.07.04 written by autopccopy() */#include <intrins.H>#include <stc12c5a60s2.H> //STC的新头文件0X6D,/*5*/0X7D,/*6*/0X07,/*7*/0X7F,/*8*/0X6F,/*9*/0xFF};void led(int n) //数码管显示及数据处理程序{P0 = 0xFF;P0 = DATA_LED[n % 10]; //个位P20 = 0;delay(1);P20 = 1;P0 = 0xFF;P0 = DATA_LED[n / 10 % 10]; //十位P21 = 0;delay(1);P21 = 1;P0 = 0xFF;P0 = DATA_LED[n / 100 % 10]; //百位 P22 = 0;delay(1);P22 = 1;P0 = 0xFF;P0 = DATA_LED[n / 1000 % 10]; //千位 P23 = 0;P07=0; //千位显示小数点delay(1);P23 = 1;}//---------------------------------------------------------------------INT8U get_AD_result(INT8U channel) //AD 转换部分{INT8U AD_finished=0; //存储 A/D 转换标志ADC_RES = 0; //高八ADC_RESL = 0; //低二位(本例未使用)channel &= 0x07; //0000,0111 清0高5位ADC_CONTR = AD_SPEED;_nop_();ADC_CONTR |= channel; //选择A/D 当前通道_nop_();ADC_CONTR |= 0x80; //启动A/D 电源delay(1); //使输入电压达到稳定ADC_CONTR |= 0x08; //0000,1000 令 ADCS = 1, 启动A/D转换,AD_finished = 0;while (AD_finished ==0 ) //等待A/D转换结束{AD_finished = (ADC_CONTR & 0x10);//0001,0000 测试A/D转换结束否ADC_CONTR &= 0xE7; //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,return (ADC_RES); //返回 A/D 高 8 位转换结果}void delay(INT8U delay_time) // 延时函数{INT16U n;while(delay_time--){n = 100;while(--n);}}//---------------------------同道选择------------------------------------------void ADzhuanhuan1(INT8U zh){INT16U ADC_result;P1ASF = 0x02; //0000,0010, 将 P1.1 置成模拟口AUXR1 &= ~0x04; //0000,0100, 令 ADRJ=0 : 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器ADC_CONTR |= 0x80; //1000,0000 打开 A/D 转换电源while(1){ADC_result =get_AD_result(zh);//P1.1 为 A/D 当前通道,测量并发送结果led(ADC_result*19.53); //显示数值。
单片机原理与应用-基于汇编、C51及混合编程第9章STC12C5A60S2单片机的片内AD转换器
9.1 A/D转换器的内部结构 9.2 A/D转换器的相关寄存器 9.3 A/D转换器的应用
第9章 STC12C5A60S2单片机的片 内A/D转换器
• 传统的单片机只能处理数字量信息,但在应用中 经常需要处理一些连续变化的模拟量,例如温度、 流量、电压、频谱等,这就需要先经过A/D转换转 变成单片机可以处理的数字量。 • STC90C58AD、STC12C5A60S2、STC12C5410AD等单 片机内部集成了8路10位A/D转换电路,转换速度 可达到250KHz(25万次/秒),即转换周期为4μs。
9.2 A/D转换器的相关寄存器
与A/D转换器相关的寄存器有: P1口模拟功能控制寄存器P1ASF A/D转换器控制寄存器ADC_CONTR A/D转换结果寄存器ADC_RES、ADC_RESL 辅助寄存器AUXR1 与A/D中断有关的寄存器IE、IPH和IP
• • • • •
1.P1口模拟功能控制寄存器P1ASF(地址9DH)
情况如表 - 1 所示 选择9 P1 口不同的引脚作为模拟输入通道, 清 0 。 转换时,必须再次将该位置 1。 0 360个时钟周期转换一次 0 1 1 具体情况如表 1 A/D P1.3 作为 A/D 输入 9-2所示。 0 A/D转换之前一定要保证 540 个时钟周期转换一次 1 0 0 0 P1.4 作为 A/D输入 •启动 A/D 转换器的电源已打开,并且 首次开启内部 转换电源时,需要适当的延时,等内部电源 1 A/D 0 1 P1.5作为A/D输入 稳定后,再启动 A/D 转换结束后关闭 1 1 转换。 0 A/D P1.6 作为A/D输入 A/D转换器的 电源可降低功耗。 1 1 1 P1.7作为A/D输入
解读STC12C5A系列单片机
1、capture/PWM 功能!解读—p303为什么频率是256等份呢?因为是 1T单片机,所以,定时器计数当然是以一个时钟周期为计数单位呢!而何时溢出呢?因为是 8位计数器,所以,2^8=256!由于周期与频率成反比,sCLK<sCLK/256意思为前者计时比较快,后者比较慢,也即前者周期小后者周期大,使用1T单片机,相对于传统12T单片机来说,假如1T计数快点。
由f=SYSclk/256 ,得T=256/SYSclk。
即,最大可以计数 256次!!!!每隔 1/SYSclk 计数一次!也即计满256个数就溢出!假如为 12M晶振,则 1/12M =1us/12约为0.084us (传统单片机是 12 * 1/12M=1us),,是不是很快啊!!!CMOD 为PCA 工作模式寄存器。
要说明的是由 CMOD中的 ECF 置位后允许CF溢出标志中断,如果 PCA 产生计数溢出,则硬件置CF=1,此时,即刻产生CF中断(如果ECF=0,则即使溢出也不产生CF中断,即硬件虽置位CF,但不能产生计数中断),虽然 CF 可以硬件或软件置位,但是只能软件清零!!~~~简而言之,CF仅仅是个计数中断溢出标志,可否中断有ECF(类似中断允许位)决定!CR(类似传统51的TRX)是启动计数阵列,也就是计数器摆了!以上是用于计数器时!!但是要注意的是 CR 清零会关闭计数阵列!那有两路捕获中断,究竟是哪一个呢?请看中断标志CCFX 来判断是那一路中断!!! CCFX 硬件置位但要软件清零咯(类似串口的RI 和 TI 哈哈)!!而下面的ECCFX用来使能CCFX 中断标志的(如果ECCFX=0则即使捕获到信号,产生了CCFX置位同时申请中断,可是,ECCFX 不允许中断的话,有申请但不允许还是中断不了啊!)。
(可以这么说,要做什么动作或者申请做什么事,需要得到允许才可以做,正如某件事发生了,你提出了一个申请(比如硬件置位了某个标志),可是我没有批准你做这件事(没有“使能”标志的申请),即使事情发生了,你也做不了什么,因为我不允许,所以你做不了!!!只有我允许了,你才可以为之!!!进行下一步的工作!!!我们这里只需要捕获脉宽,所以用到CAPPX和ECCFX!!!这里要明白,ECCFX不允许的话,系统是捕获不了CCFX中断的!!从图可以看到,ECCFn 为X 是因为你是否允许在中断取决于你的设置,这里作者仅仅是提供一种解释,告诉你这是一种怎样的工作方式!!为与不为,取决于你的ECCFX的设置!!CL 、CH 其实为计数寄存器,就是说,你要计数,那你也可以设置一个基准让计数器从那开始计数咯!!反正溢出了,他就会把这些值放到CCAPX L/H 处!!CCAPX L/H 是保存计数捕获的值!!!且CCAPX L/H 还用于占空比输出的定值呢!!这个就不解释了,太勒个呢~~!@@你懂的!!辅助寄存器,改变端口,用于当你画PCB时,可以通过改变引脚来使布线更为完美!!这个是他的结构咯~!计数器结构图:下面是捕获模式的介绍:主要看看他是怎么计数及如何保存这些数值的!!看到值是放到哪里去了吧~~!!哈哈,采集到边沿信号就把计数值从CH/L放到了另外的寄存器CCAPnL/H 咯!!虽然你获得了计数值但是中不中断去处理这些数据呢?不是你说了算,由CCON中的CCFn 和 CCAPMn 中的 ECCFn 来决定,也就是说,当捕获到这个信号时,这个信号只是充当一个开关,把CH/L的值放到的另外的寄存器,而要不要处理是另外的两个大哥(CCFX 和 ECCFX)说了算!这里还教你怎么判断究竟是哪个中断呢,还提醒你要软件清零。