STC12C5A60S2单片机c语言程序代码调试例程
基于STC12C5A60S2单片机测电压的c代码
//------------------------------------------------------------------------------
void display(void)
{ char i,scan;
char times=20;
whlie(--time>=0)
serial_init(); //串口初始化
while(1)
{
unsigned char i;
for(i=0;i<8;i++) //循环发送P1.0-P1.7的转换数值
{
TI=1; //使用printf函数前须先将发送标志位TI置1
printf("The P1.%bd voltage is %f\n",i,AD_work(i));
void dataproc(unsigned char);
void display();
void delay1ms(char);
void AD_init();
void serial_init();
void delay(unsigned int a);
float AD_work(unsigned char channel);
#include"stc12c5a.h" //头文件在STC公司主页上下载
#include"stdio.h"
#include"intrins.h"
#include<reg51.h>
char code TAB[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98};
STC12C5A60S2编程
ADC#include<STC12C5A60S2.H>#include<intrins.h>//51基本运算(包括_nop_空函数)#include"ad.h"#include"uart.h"unsigned char code dispcode[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f};void AD_Configurate (uchar ChannelNum){uchar AD_FLAG=0; //存储A/D转换标志ChannelNum &= 0x0f; //选择ADC的个接口中的一个(0111 清高位)ADC_CONTR = 0x40; //ADC转换的速度(XX0 0000 其中XX控制速度,请根据数据手册设置)_nop_();ADC_CONTR |= ChannelNum; //选择A/D当前通道_nop_();ADC_CONTR |= 0x80; //启动A/D电源delay(1); //使输入电压达到稳定(ms即可)}unsigned int ReadADV alue (void){unsigned char AD_FLAG=0; //存储A/D转换标志ADC_CONTR |= 0x08; //启动A/D转换(1000 令ADCS = 1)_nop_();_nop_();_nop_();_nop_();while (AD_FLAG ==0)//等待A/D转换结束{AD_FLAG = (ADC_CONTR & 0x10); //0001 0000测试A/D转换结束否}ADC_CONTR &= 0xE7; //1111 0111 清ADC_FLAG位, 关闭A/D转换,return(ADC_RES*4+ADC_RESL);//返回A/D转换结果(位ADC数据高位在ADC_RES中,低位在ADC_RESL中)}void DigitalTube(unsigned long number){P2=0xef; //1110 1111P0=dispcode[number%10]; //显示number的个位delay(7);P2=0xdf; //1101 1111P0=(dispcode[number/10%10]); //显示number的十位delay(7);P2=0xbf; //1011 1111P0=(dispcode[number/100%10]); //显示number的百位delay(7);P2=0x7f; //1011 1111P0=(dispcode[number/1000]); //显示number的千位delay(7);}void delay (unsigned int a ){unsigned int i;while (--a != 0){for (i = 0; i < 600; i++);}}void GPIO_init (void){P2M0 = 0x0F; //0000 1111 //I/O接口的设置P2M1 = 0x00; //0000 0000 //I/O接口的设置P1M1 = 0x01; //P1.0作为ad功能}PWM#include<STC12C5A60S2.H>#include"pwm.h"#include"uart.h"unsigned int xdata FirstData=0; //上升沿捕捉数据unsigned int xdata SeconedData=0; //下降沿捕捉数据高电平时间=SeconedData-FirstData unsigned int xdata HighLevel=0; // 保存被测波形高电平时间对于测方波即使半个周期//采用半个周期的测法主要是提高可被测波形的频率范围unsigned int xdata Frequency=0; // 保存频率的变量bit Capture_over = 0; //捕获完成标志位void pwm_init(void){CMOD=0x80; //0000 0010 PCA工作模式寄存器系统时钟/12 计数器溢出中断CF CCAP0H =(CCAP0L = 254); //PCA捕捉/比较寄存器127 高低点CCAPM0=0x42; //0100 0010// CCAP1H =(CCAP1L = 0x7f);// CCAPM1=0x42;CCAPM1 = 0x21;//16位捕获模式,上升沿触打开捕获中断CCF1CCAP1L = 0x00;CCAP1H = 0x00;EA = 1;CCON=0x40; //0100 0000 PCA控制寄存器CR=1 启动PCA计数器阵列计数}void SetPwm0DutyCycle(unsigned int x) //占空比设置函数{unsigned int h=0,l=0;l=x&0xff;h=x>>8;CCAP0L=l;CCAP0H=h; //设置比较值}void PCA_Interrupt(void) interrupt 7{if (CCF1) //PCA模块中断{CCF1 = 0;if(FirstData == 0) // 上升沿中断{FirstData = CCAP1H; //获得捕捉数据的高位//高位<<8+低位构成位整数FirstData = (FirstData << 8) + CCAP1L;CCAPM1 = 0x11;// 下降沿捕获}else// 下降沿中断{CCF1 = 0; // 清CCF中断标志SeconedData = CCAP1H; //获得捕捉数据的高位//高位<<8+低位构成位整数SeconedData = (SeconedData << 8) + CCAP1L;HighLevel = SeconedData - FirstData; //计数值单位为usFrequency = (long)456000/ HighLevel; // 得到周期CR = 0;//停止PCA计数器计数CCAPM1 = 0x10;//停止捕获中断CCF0产生FirstData=0; // 为下一次捕捉设定初始条件CCAP1L = 0x00;//清零CCAP1H = 0x00;CL = 0x00; //清PCA计数器CH = 0x00;CCAPM1 = 0x21;Capture_over = 1;//捕获完成标志位}}// if(CF == 1) //PCA溢出中断// {// USART_Send_Str(" ;;;;;;;");// CF = 0; //清PCA溢出中断标志// CCAPM1 = 0x21;// FirstData=0; // 为下一次捕捉设定初始条件// CCAP1L = 0x00;//清零// CCAP1H = 0x00;// }}UART#include<STC12C5A60S2.H>#include<stdio.h>#include<string.h>#include"uart.h"//void uartinit(void)//{//// SCON = 0x50; //REN=1允许串行接受状态,串口工作模式// TMOD|= 0x20; //定时器工作方式// PCON|= 0x80;// //TH1 = 0xFD; //baud*2 /* reload value 19200、数据位、停止位。
单片机STC12C5A60S2控制AT24C04的程序(C语言)
void Delay5ms()
{
WORD n = 2500;
while(n--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/**************************************
起始信号
**************************************/
void AT24C04_Start()
{
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 0; //产生下降沿
Delay5us(); //延时
SCL = 0; //拉低时钟线
SDA = 1; //产生上升沿
*******************************
发送应答信号
入口参数:ack(0:ACK 1:NAK)
**************************************/
void AT24C04_SendACK(bit ack)
{
SDA = ack; //写应答信号
SCL = 1; //拉高时钟线
Delay5us(); //延时
SCL = 0; //拉低时钟线
Delay5us(); //延时
}
/**************************************
接收应答信号
**************************************/
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;*/页脚内容1uchar 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--)页脚内容2for( 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; // 允许串口接收页脚内容3//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发送函数*****************/页脚内容4void 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) // 发送端(发送的是字符){页脚内容5S2BUF = 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() i nterrupt 4 // 中断编号4为串行口1中断{if(RI) // 接收标志位,0:正在接收1:接收完毕(如果RI=1就一直执行中断){页脚内容6RI = 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接收到的字符送入变量中}}页脚内容7void 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 = '?';}}页脚内容8}页脚内容9。
STC12C5A60S2控制温度传感器DS18B20 c程序
STC12C5A60S2 控制温度传感器DS18B20 c 程序STC12C5A60S2 控制温度传感器DS18B20 c 程序工作频率:12.000MHz #include”REG51.H”#include”INTRINS.H”typedefunsignedcharBYTE; sbitDQ=P3;//DS18B20的数据口位P3.3BYTETPH;//存放温度值的高字节BYTETPL;//存放温度值的低字节voidDelayXus(BYTEn); voidDS18B20_Reset(); voidDS18B20_WriteByte(BYTEdat); BYTEDS18B20_ReadByte(); voidmain() { DS18B20_Reset();//设备复位DS18B20_WriteByte(0xCC);//跳过ROM 命令DS18B20_WriteByte(0x44);//开始转换命令while(!DQ);//等待转换完成DS18B20_Reset();//设备复位DS18B20_WriteByte(0xCC);//跳过ROM 命令DS18B20_WriteByte(0xBE);//读暂存存储器命令TPL=DS18B20_ReadByte();//读温度低字节TPH=DS18B20_ReadByte();//读温度高字节while(1); } /************************************** 延时X 微秒(STC12C5A60S2@12M) 不同的工作环境,需要调整此函数此延时函数是使用1T 的指令周期进行计算,与传统的12T 的MCU 不同**************************************/ voidDelayXus(BYTEn) { while(n--){ _nop_(); _nop_(); } } /************************************** 复位DS18B20,并检测设备是否存在**************************************/voidDS18B20_Reset() { CY=1; while(CY) { DQ=0;//送出低电平复位信号DelayXus(240);//延时至少480us DelayXus(240); DQ=1;//释放数据线DelayXus(60);//等待60us CY=DQ;//检测存在脉冲DelayXus(240);//等待设备释放数据线DelayXus(180); } } /************************************** 从DS18B20 读1 字节数据**************************************/。
stc12c5a60s2 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的LCD1602显示屏程序
#include"STC12C5A60S2.h"
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
P0=dictate; //将数据送人p0口,写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //当E由高电平变成低电平时,液晶模块开始
}
/********
函数功能:指定字符显示的地址
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //写指令时E为高脉冲,让E从0到1发生正跳变,所以应先置零
_nop_();
_nop_();
完整word版,STC12C5A60S2程序实现0-256分之一晶振任意频率PWM输出
//头文件STC12C5A.h可在网上下载#include "STC12C5A.H"#define uint unsigned int#define uchar unsigned charuchar t=0;sbit sign=CCON^2;//此位为预留位置,开发用作表示振动片工作模式,0为一//般模式,1为ADC模式void init_T0(void);//初始化T0void init_T1(void);//初始化[T1void init_INT0(void);//初始化外部中断0void init_INT1(void);//初始化外部中断1void init_PCA(void);//初始化PCA模块void init_ADC(void);//初始化A/D转化模块void main(void){sign=0;//默认工作在固定模式P17=1;//开始时P3^0输出为高电平EA=1;//开总中断init_T0();//初始化T0init_T1();//初始化T1init_INT0();//初始化外部中断0init_INT1();//初始化外部中断1init_PCA();//初始化PCA模块CR=1; //开启PCA计数器init_ADC(); //初始化A/D转化模块while(1){if(sign==1)//工作在ADC模式{if(ADC_CONTR&ADC_FLAG!=0)//转换结束{TH0=ADC_RES; //溢出率与初值成正比TL0=ADC_RES;ADC_CONTR=ADC_CONTR & 0xE7;//将ADC_FLAG(转换结//束标志位)与ADC_START清零,其余位不变ADC_CONTR=ADC_CONTR | 0x08;//将ADC_START置1 }}else //工作在固定模式{TH0=0x30; //输出一固定频率的PWM波TL0=0x30;}}}void init_T0(void)//T0做PCA的时钟源输入{//通过改变定时器0溢出率实现可调频率的PWM输出TMOD=0x02;//定时器0工作在方式2,8位定时计数器自动重装载TH0=0x80;//设置T0定时所对应的初值TL0=0x80;//设置T0每次定时结束后重装载的值ET0=1;//允许定时器0中断TR0=1;//定时器0开始计数}void init_T1(void)//T1定时100ms,用于产生呼气吸气脉冲{TMOD=TMOD|0x10;//设置定时器1的工作方式为方式2且不改变定时器0的工作方式TH1=0x3c; //设置定时100ms的处初值TL1=0xb0;ET1=1;//允许定时器1中断TR1=1; //定时器1开始计数}void init_INT0(void){IT0=1;//由下降沿触发,输入引脚P3^2EX0=1;//开外部中断0}void init_INT1(void){IT1=1; //由下降沿触发,输入引脚P3^3EX1=1; //开外部中断1}void init_PCA(void){CMOD=0x04; //CIDL=0(D7):空闲模式下继续计数,D4~D6不用//CPS2/CPS1/CPS0(D3~D1)=010,选择T0做PCA时钟源输入//ECF(D0)=0,关PCA计数器溢出中断CCF1=0; //清零PCA模块1中断标志位CCF0=0; //清零PCA模块0中断标志位CR=0; //关闭PCA计数器CH=0;//PCA计数器高8位置零CL=0; //PCA计数器低8位置零CCAPM0=0X42;//PCA模块0的工作模式寄存器设置为0X42表示8位PWM无中断CCAP0H=0x80; //设置PWM波的占空比为0.5CCAP0L=0x80; //溢出后会将CCAP0H中值赋给CCAP0LCCAPM1=0x31; //PCA模块1扩展为上升沿下降沿均可触发的外部中断}void init_ADC(void){uint i;for(i=10000;i!=0;i--)//若晶振为6MHZ,是延时20ms等待ADC模块内部模拟电源稳定{;}ADC_CONTR=0x80;//开ADC模块电源并选择P1^0作为模拟量输入引脚P1ASF=0x01; //P1口模拟量功能设置寄存器:使用P1^0的模拟量功能AUXR1=AUXR1 & 0xfb;//ADRJ=0,ADC_RES存放A/D转换结果高8位//ADC_RESL存放A/D转换结果低8位ADC_RES=0; //检测前将其清零ADC_RESL=0;//检测前将其清零EADC=1; //开A/D转换中断}void INT0_ISR(void) interrupt 0 //外部中断0服务程序{sign=0;//工作在固定模式ADC_CONTR=ADC_CONTR&0xF7;//关闭ADC电源}void INT1_ISR(void) interrupt 2 //外部中断1服务程序{sign=1;//工作在ADC模式ADC_CONTR|=0x08; //打开ADC电源,由用户决定PWM频率}void T1_ISR(void) interrupt 3 //定时器1中断服务程序{TH1=0x3C; //工作在方式1溢出后不能自动重装载TL1=0xB0;t++;if(t==20)//2s后输出低电平P17=!P17;if(t==50){t=0;//5s为一个周期P17=!P17;}}void PCA_ISR(void) interrupt 7{if(CCF1==1)//PCA模块1中断响应{if(P14==0)//判断是上升沿触发还是下降沿触发,等于0为下降沿触发{while(t!=25); //延时0.5sCCAP0H=0x80; //设置PWM波的占空比为0.5CCAP0L=0x80;}else//上升沿触发{CCAP0H=0xFF; //PWM输出低电平CCAP0L=0xFF;}CCF1=0;elseCCF0=0;//防止干扰信号误动作}}。
STC12C5A60S2控制的花样流水灯
1010 1010,0101 0101,0001 1000,1111 1111,1111 0000,0000 1111,0000 0000,1111 1111,
{
uint x,y;
for(x=z;x>0;x--)
for(y=470;y>0;y--);
}
uchar code Pattern_P1_1[]=
{
0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, //两个0从右往左移
DelayMs(delay_num);
}
for(i=0;i<136;i++)
{
P1=Pattern_P1_2[i];//第二组花样
DelayMs(delay_num);
}
}
}
0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f,
0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,
0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
STC12C5A60S2-PWM调节
#include<STC12C5A60S2.H> //头文件/******************************************************************************************** 函数名:PWM初始化函数调用:PWM_init();参数:无返回值:无结果:将PCA初始化为PWM模式,初始占空比为0备注:需要更多路PWM输出直接插入CCAPnH和CCAPnL即可/*******************************************************************************************/ void PWM_init (void){CMOD=0x02; //设置PCA定时器CL=0x00;CH=0x00;CCAPM0=0x42; //PWM0设置PCA工作方式为PWM方式(0100 0010)CCAP0L=0x00; //设置PWM0初始值与CCAP0H相同CCAP0H=0x00; // PWM0初始时为0//CCAPM1=0x42; //PWM1设置PCA工作方式为PWM方式(使用时删除//)//CCA P1L=0x00; //设置PWM1初始值与CCAP0H相同//CCAP1H=0x00; // PWM1初始时为0//CCAPM2=0x42; //PWM2设置PCA工作方式为PWM方式//CCAP2L=0x00; //设置PWM2初始值与CCAP0H相同//CCAP2H=0x00; // PWM2初始时为0//CCAPM3=0x42; //PWM3设置PCA工作方式为PWM方式//CCAP3L=0x00; //设置PWM3初始值与CCAP0H相同//CCAP3H=0x00; // PWM3初始时为0CR=1; //启动PCA定时器}/*******************************************************************************************/ /********************************************************************************************函数名:PWM0占空比设置函数调用:PWM0_set();参数:0x00~0xFF(亦可用0~255)返回值:无结果:设置PWM模式占空比,为0时全部高电平,为1时全部低电平备注:如果需要PWM1的设置函数,只要把CCAP0L和CCAP0H中的0改为1即可/*******************************************************************************************/ void PWM0_set (unsigned char a){CCAP0L= a; //设置值直接写入CCAP0LCCAP0H= a; //设置值直接写入CCAP0H}/*******************************************************************************************/ /******************************************************************************************* 函数名:主函数调用:无参数:无返回值:无结果:程序开始处,无限循环备注:******************************************************************************************/ void main (void){while(1){PWM_init(); //PWM初始化PWM0_set(0x7F); //设置PWM占空比,总共255,除以2,转换成十六进制得7F}}/******************************************************************************************** **/。
STC12C5A60S2双串口通信例程
#include <STC12C5A60S2.h>#include <Uart.h>#define uchar unsigned char#define uint unsigned int//=====================void delay(void){uint j,g;for(j=0;j<500;j++)for(g=0;g<500;g++);}//============================void main(){Uart_Two_Init();Uart_One_Init();while(1){Uart_One_Send('z');delay();Uart_Two_Send('z');UART_One_Printf("sb123456789\n");delay();UART_Two_Printf("sb123456789\n");delay();}}//======================================#ifndef __UART_H__#define __UART_H__#define uchar unsigned char#define uint unsigned int//=====================================//#define RELOAD 0xFA//#define RELOAD_TWO 0xfa//#define BRTx12_enable() AUXR |= 0x04 //BRT 独立波特率发生器的溢出率快12 倍//#define BRT_start() AUXR |= 0x10 //启动独立波特率发生器BRT 计数。
//=========================================uchar c = 0 ;uint d = 0 ;//=========================================//=======baud 9600=======================void Uart_One_Init() //串口1初始化函数,波特率9600TMOD=0x20;//设置定时器1为工作方式2TH1=0xfd; //设置波特率为9600TL1=0xfd;TR1=1;REN=1;SM0=0;SM1=1;EA=1;ES=1;// AUXR|=0X40; //T1*12;}//========================================void Uart_One_Send(char k) //串口1发送一个字符{ES = 0 ;SBUF=k;while(TI!=1);TI = 0 ;ES = 1 ;}//=========baud 9600=======================void Uart_Two_Init() //串口2初始化函数,波特率9600{S2CON= 0x50 ; //方式2,允许接收// BRT = RELOAD_TWO ;BRT = 0xfd; //设置波特率9600 AUXR = AUXR |0X10 ; //允许独立波特率发生器运行// BRTx12_enable();AUXR1 = AUXR1&0xef ; //S2_P4=0,将uart2切换到P1口IE2 = IE2|0X01; //允许串口2中断}//=========================================void Uart_Two_Send(uchar k) //串口2发送一个字符{ES = 0 ;S2BUF = k ;while((S2CON&0x02)!=0x02);S2CON &= ~0x02;ES = 1 ;}//=============================================void UART_One_Printf(uchar *p)while(* p!='\0') Uart_One_Send(*p++);}//============================================ void UART_Two_Printf(uchar *p){while(* p!='\0') Uart_Two_Send(*p++);}//=========================================== void Uart_One_Receive() interrupt 4{uint k = 0 ;if(RI==1){RI = 0 ;k = SBUF;}}//========================================void Uart_Two_Receive() interrupt 8{uchar a ;uint k = 0 ;// a = S2CON ;a = S2CON & 0x01;if(a==1){k = S2BUF ;S2CON = S2CON & 0xfe; //清0 S2RI }}//=====================================#endifLTC1605 - 16-Bit, 100ksps, Sampling ADC特点•Sample Rate: 100ksps 采样100K次/S•Single 5V Supply 单5V供电•Bipolar Input Range: ±10V 双极输入-10V----+10V•Power Dissipation: 55mW Typ 电源55MW•Integral Nonlinearity: ±2.0LSB Max •Guaranteed No Missing Codes•Signal-to-Noise Ratio: 86dB Typ •Operates with Internal or External Reference •Internal Synchronized Clock•Improved 2nd Source to ADS7805 and AD976 •28-Pin 0.3” PDIP, SSOP and SW Packages。
STC12C5A60S2头文件函数程序
//--------------------------------------------------------------------------------//新一代1T 8051系列单片机内核特殊功能寄存器C51 Core SFRs// 7 6 5 4 3 2 1 0 Reset Valuesfr ACC = 0xE0; //Accumulator 0000,0000sfr B = 0xF0; //B Register 0000,0000sfr PSW = 0xD0; //Program Status Word CY AC F0 RS1 RS0 OV F1 P 0000,0000//-----------------------------------sbit CY = PSW^7;sbit AC = PSW^6;sbit F0 = PSW^5;sbit RS1 = PSW^4;sbit RS0 = PSW^3;sbit OV = PSW^2;sbit P = PSW^0;//-----------------------------------sfr SP = 0x81; //Stack Pointer 0000,0111sfr DPL = 0x82; //Data Pointer Low Byte 0000,0000sfr DPH = 0x83; //Data Pointer High Byte 0000,0000//--------------------------------------------------------------------------------//新一代1T 8051系列单片机系统管理特殊功能寄存器// 7 6 5 4 3 2 1 0 Reset Valuesfr PCON = 0x87; //Power Control SMOD SMOD0 LVDF POF GF1 GF0 PD IDL 0001,0000// 辅助寄存器7 6 5 4 3 2 1 0 Reset Valuesfr AUXR = 0x8E; //Auxiliary Register T0x12 T1x12 UART_M0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS 0000,0000//-----------------------------------sfr AUXR1 = 0xA2; //Auxiliary Register 1 - PCA_P4 SPI_P4 S2_P4 GF2 ADRJ - DPS 0000,0000/*PCA_P4:0, 缺省PCA 在P1 口1,PCA/PWM 从P1 口切换到P4 口: ECI 从P1.2 切换到P4.1 口,PCA0/PWM0 从P1.3 切换到P4.2 口PCA1/PWM1 从P1.4 切换到P4.3 口SPI_P4:0, 缺省SPI 在P1 口1,SPI 从P1 口切换到P4 口: SPICLK 从P1.7 切换到P4.3 口MISO 从P1.6 切换到P4.2 口MOSI 从P1.5 切换到P4.1 口SS 从P1.4 切换到P4.0 口S2_P4:0, 缺省UART2 在P1 口1,UART2 从P1 口切换到P4 口: TxD2 从P1.3 切换到P4.3 口RxD2 从P1.2 切换到P4.2 口GF2: 通用标志位ADRJ:0, 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器1,10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器DPS: 0, 使用缺省数据指针DPTR01,使用另一个数据指针DPTR1*///-----------------------------------sfr WAKE_CLKO = 0x8F; //附加的SFR WAK1_CLKO/*7 6 5 4 3 2 1 0 Reset ValuePCAWAKEUP RXD_PIN_IE T1_PIN_IE T0_PIN_IE LVD_WAKE _ T1CLKO T0CLKO 0000,0000Bb7 - PCAWAKEUP : PCA 中断可唤醒powerdown。
STC12C5A60S2-AD转换12864显示示例程序
#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结果函数发送到串口,方便调试{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=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);}}参考链接:。
增强型51单片机STC12C5A60S2的内部AD和PWM波以及时钟输出程序
增强型51单片机STC12C5A60S2的内部AD和PWM波以及时钟输出程序#ifndef __ad_h__#define __ad_h__uint adzhi[8]; //AD值存放数组void AD_Init(){AUXR1|=0X04; //设置AD的ADRJ位为1,使AD取十位结果RES寄存器存高两位,RESL存低七位ADC_CONTR=0X80; //开AD转换电源,第一次使用时要打开内部模拟电源delayms(1);P1ASF=0xff; //P1口7路ADC}void Get_AD(){uchar i;uint res,resl; //AD结果暂存变量uchar status=0; //AD转换状态ADC_CONTR=0X80; //再次打开电源delayms(1);for(i=0;i<8;i++){ADC_CONTR=(0X80|i); //设定转换的通道ADC_CONTR|=0x08; //开始AD转换status=0;while(!(ADC_CONTR&0x10));//等待转换完成ADC_CONTR&=0xE7; //清零即D3位start清零,D4位转换结束标志位ADC——flag清零res=ADC_RES; //存储高两位resl=ADC_RESL; //存储低八位adzhi[i]=res*256+resl;}}void PWM_Init(){CMOD=0X84; //初始化工作模式寄存器CCON=0X00; //所有标志位清零CL=0;CH=0; //给PCA的16位计数器赋初值CCAP0H=CCAP0L=0x80; //给占空比100%CCAPM0=0X42; //工作在PWM波模式,且无PCA中断PCA_PWM0=0X00; //最高位给00CCAP1H=CCAP1L=0x80; //给PWM1占空比50%CCAPM1=0X42; //工作模式设定PCA_PWM1=0x00;CR=1; //启动}void CLK(){TMOD=0X22; //T0、T1工作在方式2,8位自动重装AUXR|=0X80; //T0工作在1T模式AUXR|=0X40; //T1工作在1TAUXR|=0X04; //独立波特率发生器工作在1TBRT=106;TH0=106;TH1=106;WAKE_CLKO|=0X07; //允许T0、T1,独立波特率发生器输出时钟TR0=1; //启动计数TR1=1;AUXR|=0X10; //启动BRT工作,对系统时钟进行分频输出while(1);}#endif。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//12T指的是每12个时钟加1与普通C51一样
//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只
能工作在定时器模式2下
//T1工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2
//T1工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2
//工作模式为1T
BRT = 0xff;
#if( Bus_clk == 12 )
CLK_DIV = 0x00;
#elif( Bus_clk == 6 )
CLK_DIV = 0x01;
#elif( Bus_clk == 3 )
CLK_DIV = 0x02;
#elif( Bus_clk == 1500 )
void Delay_ms( uint time )
{
uint t; //延时时间 = (time*1003+16)us while(time--)
{
for( t = 0; t < 82; t++ );
}
}
//***********************************//
//1T指的是每1个时钟加1,是普通C51的12倍
//12T指的是每12个时钟加1与普通C51一样
AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下
//T1定时器速度是普通8051的12倍,即工作在1T模式下
TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数
#define uchar unsigned char
#define uint unsigned int
uchar Power_Down_Flag = 0; //进入掉电状态标志
sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯
sbit Power_Down_LED_INT0 = P0^1; //INT0口掉电唤醒指示灯
钟
// P1.0输出CLKOUT2时钟
//
////****************************************************************************/
/
#include <STC12C5A60S2.H>
#include <intrins.h>
//BRT工作在12T模式下时输出频率 = Sysclk/12/(256-BRT)/2
AUXR = 0x14; //Bit4-BRTR 允许独立波特率发生器运行
//Bit2-BRTx12 BRT工作在1T模式下
BRT = 0xff; //更改该寄存器的值可实现对输出的时钟式2,自动装载时间常数
TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频
TL0 = 0xff;
TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频
TL1 = 0xff;
TR1 = 1;
TR0 = 1;
}
#else /*条件编译CLKOUT0时钟输出*/
//*********************************//
// CLKOUT0时钟和CLKOUT1初始化 //
//*********************************//
void CLKOUT_init(void)
//****************************************************************************//
// STC12C5A60S2可编程时钟模块
//
//
// 说明:STC12C5A60S2单片机有三路可编程时钟输出CLKOUT0/T0/P3.4
{
WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0
//T0工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2
//T0工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2
//1T指的是每1个时钟加1,是普通C51的12倍
//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句
//若想测试CLKOUT1和CLKOUT0请注释此句
#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*/
//*********************************//
CLK_DIV = 0x03;
#elif( Bus_clk == 750 )
CLK_DIV = 0x04;
#elif( Bus_clk == 375 )
CLK_DIV = 0x05;
#elif( Bus_clk == 187500 )
CLK_DIV = 0x06;
#elif( Bus_clk == 93750 )
// 中断初始化 //
//***********************************//
void Intp_init(void)
{
IT0 = 0; //外部中断源0为低电平触发
EX0 = 1; //允许外部中断
}
#endif
//**********************************//
// 主程序 //
//**********************************//
void main()
{
CLKOUT_init();
while(1);
}
//****************************************************************************//
// 系统时钟初始化 //
//*********************************************//
void Sysclk_init(void)
{
WAKE_CLKO = 0x04; //配置P1.0口为频率输出
AUXR = 0x14; //允许波特率时钟工作
// 唤醒后单片机将通过P0^0-3口的灯闪烁显示开始工作
////****************************************************************************/
/
#include <STC12C5A60S2.h>
#include <intrins.h>
#include <STC12C5A60S2.h>
#include <intrins.h>
#define Bus_clk 12 //若要修改系统时钟直接在此处修改
//12 为 12M 的sysclk
//6 为 6M 的sysclk
//3 为 3M 的sysclk
//1500 为 1.5M 的sysclk
{
Sysclk_init();
while(1);
}
//****************************************************************************//
// STC12C5A60S2系统省电模块 //
//
// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式
sbit N_Power_Down_LED_INT0 = P0^2; //INT0口没有唤醒指示灯
sbit Normal_Work_LED = P0^3; //正常工作指示灯
sbit Power_Down_Wakeup_INT0= P3^2; //外中断唤醒输入口
void Delay_ms( uint time );
// 掉电模式
//
//
// 涉及寄存器:PCON(电源控制寄存器)
// Bit0 - IDL 控制单片机进入IDLE空闲模式
// Bit1 - PD 控制单片机进入掉电模式
// //
// 程序说明: 程序实现让单片机先工作一阵子(通过P0^3指示灯显示)
// 然后进入掉电状态,利用外部中断0口来唤醒单片机工作
// STC12C5A60S2系统时钟模块
//
//
// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时
钟
// 出厂标准配置是使用外部晶体或时钟
//
//
// 涉及寄存器:CLK_DIV(时钟分频寄存器)
// 由该寄存器的Bit0-2组合可实现对时钟源进行0、2、4、8、16
CLK_DIV = 0x07;
#endif
}
//**********************************************//
// 主程序 //
//**********************************************//
void main()
// CLKOUT2时钟初始化 //
//*********************************//
void CLKOUT_init(void)