STC单片机串口1、2代码

合集下载

STC串口通信编程

STC串口通信编程

//注意,如您使用的MCU没有那个功能,就不要操作相应的寄存器//注意,如您使用的MCU没有那那么大的扩展SRAM,就不要操作超过范围的SRAM#include<reg51.h>#include<intrins.h>sfr S2CON = 0x9A;//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,SRB8,S2TI,S2RIsfr IE2 = 0xAF;//X,X,X,X,X,X,ESPI,ES2sfr S2BUF = 0x9B;sfr AUXR = 0x8e;sfr BRT = 0x9c;sfr IAP_CONTR = 0xC7;sfr CCON = 0xD8;sfr CMOD = 0xD9;sfr CL = 0xE9;sfr CH = 0xF9;sfr CCAP0L = 0xEA;sfr CCAP0H = 0xFA;sfr CCAPM0 = 0xDA;sfr CCAPM1 = 0xDB;sbit CR = 0xDE;sbit MCU_Start_Led = P1^7;sbit S2_Interrupt_Receive_Led = P1^4;//unsigned char self_command_array[4] = {0x22,0x33,0x44,0x55};#define Self_Define_ISP_Download_Command 0x22#define RELOAD_COUNT 0xfb //18.432MHz,12T,SMOD=0,9600bpsvoid serial_port_one_initial();void send_UART_one(unsigned char);void UART_one_Interrupt_Receive(void);void serial_port_two_initial();void send_UART_two(unsigned char);void UART_two_Interrupt_Receive(void);void soft_reset_to_ISP_Monitor(void);void delay(void);void display_MCU_Start_Led(void);void send_PWM(void);void main(void){unsigned int array_point = 0;unsigned char xdata Test_array_one[512] ={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1,0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,};unsigned char i = 0;serial_port_one_initial(); //串口1初始化// serial_port_two_initial(); //串口2初始化display_MCU_Start_Led(); //点亮发光二极管表示单片机开始工作// send_UART_two(0x55); //串口2发送数据表示单片机串口正常工作// send_UART_two(0xaa); //串口2发送数据表示单片机串口正常工作/*for(array_point=0; array_point<512; array_point++){send_UART_two(Test_array_one[array_point]);}*/send_UART_one(0x34); //串口1发送数据表示单片机串口正常工作send_UART_one(0xa7); //串口1发送数据表示单片机串口正常工作for(array_point=0; array_point<512; array_point++){send_UART_one(Test_array_one[array_point]);}// send_PWM(); //6kHz PWM, 50% dutywhile(1);}void serial_port_one_initial(){SCON = 0x50; //0101,0000 8位可变波特率,无奇偶校验位// TMOD = 0x21; //0011,0001 设置顶时器1为8位自动重装计数器// TH1 = RELOAD_COUNT; //设置定时器1自动重装数// TL1 = RELOAD_COUNT;// TR1 = 1; //开定时器1BRT = RELOAD_COUNT;// BRTR = 1, S1BRS = 1, EXTRAM = 1 ENABLE EXTRAMAUXR = 0x11; // T0x12,T1x12,UART_M0x6,BRTR,S2SMOD,BRTx12,EXTRAM,S1BRS ES = 1; //允许串口中断EA = 1; //开总中断}void serial_port_two_initial(){//sfr SCON = 0x98;//SM0,SM1,SM2,REN,TB8,RB8,TI,RI//sfr S2CON = 0x9A;//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI//sfr S2BUF = 0x9B;//sfr IE2 = 0xAF;//X,X,X,X,X,X,ESPI,ES2S2CON = 0x50; //0101,0000 8位可变波特率,无奇偶校验位,允许接收BRT = RELOAD_COUNT;// BRTR = 1, S1BRS = 1, EXTRAM = 0 ENABLE EXTRAMAUXR = 0x11; // T0x12,T1x12,UART_M0x6,BRTR,S2SMOD,BRTx12,EXTRAM,S1BRS // ES = 1; //允许串口1中断// ES2 = 1IE2 = 0x01; //允许串口2中断,ES2=1EA = 1; //开总中断}void send_UART_one(unsigned char i){ES = 0; //关串口中断TI = 0; //清零串口发送完成中断请求标志SBUF = i;while(TI ==0); //等待发送完成TI = 0; //清零串口发送完成中断请求标志ES = 1; //允许串口中断}void send_UART_two(unsigned char i){//sfr SCON = 0x98;//SM0,SM1,SM2,REN,TB8,RB8,TI,RI//sfr S2CON = 0x9A;//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI//sfr S2BUF = 0x9B;//sfr IE2 = 0xAF;//X,X,X,X,X,X,ESPI,ES2unsigned char temp = 0;// ES = 0; //关串口1中断IE2 = 0x00; //关串口2中断,es2=0// TI = 0; //清零串口1发送完成中断请求标志S2CON = S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志// SBUF = i;S2BUF = i;// while(TI ==0); //等待发送完成do{temp = S2CON;temp = temp & 0x02;}while(temp==0);// TI = 0; //清零串口发送完成中断请求标志S2CON = S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志// ES = 1; //允许串口1中断// ES2 = 1IE2 = 0x01; //允许串口2中断,ES2=1}void UART_one_Interrupt_Receive(void) interrupt 4{unsigned char k = 0;if(RI==1){RI = 0;k = SBUF;if(k==Self_Define_ISP_Download_Command) //是自定义下载命令{delay(); //延时1秒就足够了delay(); //延时1秒就足够了soft_reset_to_ISP_Monitor(); //软复位到系统ISP监控区}send_UART_one(k+1);}else{TI = 0;}}void UART_two_Interrupt_Receive(void) interrupt 8{//sfr SCON = 0x98;//SM0,SM1,SM2,REN,TB8,RB8,TI,RI//sfr S2CON = 0x9A;//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI//sfr S2BUF = 0x9B;//sfr IE2 = 0xAF;//X,X,X,X,X,X,ESPI,ES2unsigned char k = 0;k = S2CON ;k = k & 0x01;//if(S2RI==1)if(k==1){//RI = 0;S2CON = S2CON & 0xFE; //1111,1110S2_Interrupt_Receive_Led = 0;k = S2BUF;if(k==Self_Define_ISP_Download_Command) //是自定义下载命令 {delay(); //延时1秒就足够了delay(); //延时1秒就足够了soft_reset_to_ISP_Monitor(); //软复位到系统ISP监控区 }send_UART_two(k+1);}else{//TI = 0;S2CON = S2CON & 0xFD; //1111,1101}}void soft_reset_to_ISP_Monitor(void){IAP_CONTR = 0x60; //0110,0000 软复位到系统ISP监控区}void delay(void){unsigned int j = 0;unsigned int g = 0;for(j=0;j<5;j++){for(g=0;g<60000;g++){_nop_();_nop_();_nop_();_nop_();_nop_();}}}void display_MCU_Start_Led(void){//sbit MCU_Start_Led = P1^7;unsigned char i = 0;for(i=0;i<1;i++){MCU_Start_Led = 0; //顶亮MCU开始工作指示灯delay();MCU_Start_Led = 1; //熄灭MCU开始工作指示灯delay();MCU_Start_Led = 0; //顶亮MCU开始工作指示灯}}void send_PWM(void){CMOD = 0x00; // CIDL - - - - CPS1 CPS0 ECF Setup PCA Timer // CPS1 CPS0 = 00, Fosc/12 is PCA/PWM clock// 18432000/12/256 = 6000CL = 0x00;CH = 0x00;CCAP0L = 0x80; //Set the initial value same as CCAP0HCCAP0H = 0x80; //50% Duty CycleCCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in 8BIT PWM, P3.7 CR = 1; //启动 PCA/PWM 定时器}。

STC15F204EA单片机旋转编码器版白光T12控制器代码

STC15F204EA单片机旋转编码器版白光T12控制器代码

/*************STC15F204EA单片机旋转编码器版白光T12控制器代码(开发固件)(by金向维)******************* /#include <> //单片机头文件,24MHz时钟频率#include "" //头文件unsigned char code duanma[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x73}; //共阴数码管段码数据(0,1,2,3,4,5,6, 7,8,9),倒数第二个是显示负号-的数据,倒数第一个是显示字母P的数据unsigned int code wendubiao[62]={924,959,996,1033,1071,1110,1150,1190,1232,1273,1315,1358,1401,1443 ,1487,1501,1574,1619,1663,1706,1751,1756,1776,1810,1853,1903,1958,2017,2078,2 141,2204,2266,2327,2387,2444,2500,2554,2607,2657,2706,2738,2800,2844,2889,2 931,2974,3016,3056,3098,3139,3179,3218,3257,3296,3333,3372,3408,3446,3484,3 519, 3554,3590}; //根据NTC电阻随温度变化进而引起电压变化得出的数据,用来查表计算室温(进而对热电偶冷端补偿)sbit t12=P2^0; //T12通过控制sbit bw=P3^4; //数码管百位位选为sbit sw=P3^5; //数码管十位位选为sbit gw=P3^6; //数码管个位位选为sbit tihuan=P3^7; //数码管的a段本应该用控制,由于被用来控制T12,所以要用替代sbit encoderb=P1^4; //编码器的b脚接sbit encodera=P3^2; //编码器的a脚接sbit zhendongkaiguan=P0^1; //震动开关接sbit bianmaanniu=P3^3; //编码器的按键接sbit a7=P2^7; //数码管小数点sbit a6=P2^6; //数码管g段sbit a5=P2^5; //数码管f段sbit a4=P2^4; //数码管e段sbit a3=P2^3; //数码管d段sbit a2=P2^2; //数码管c段sbit a1=P2^1; //数码管d段bit e=1, f=1; //e f 用来保存编码器上一次的状态bit huancunkaiguan=0; //用于改变设定温度后延时显示设定温度(而不是立刻显示t12温度)signed int huancun; //显示函数直接显示huancun,要显示一个数据将必须这个数据赋值给缓存(由于数码管只有三位,为了在显示三位数同时保持四位数的精度,所以实际显示的是数据除以10,并支持显示负数)signed int shiwen; //10倍实际室温,即实际室温乘以10(为了精确)(允许的室温范围为-11度至50度)signed int t12wendu; //T12烙铁头的实际温度(非热电偶的温差)(同样为10倍温度)signed int shedingwendu; //设定温度(范围200~450度)signed int wencha; //T12两个周期间的温差signed int jiareshu; //每200ms加热周期内需要加热的次数(一次等于1ms,相当于加热占空比)unsigned char zhouqijishu; //加热周期200ms计数unsigned int huancunjishu; //用于改变设定温度后延时显示设定温度(而不是立刻显示t12温度)unsigned long cankaodianya0, t12dianya, ntcdianya, dianyuandianya;/********************************1ms延时函数*************************************************/void delay_ms (unsigned int a) //24MHz时钟时的1毫秒延时函数{unsigned int b;while(a--){for(b=0;b<1200;b++);}}/********************************10us延时函数************************************************/void delay_10us (unsigned int a) //24MHz时钟时的10微秒延时函数{unsigned int b;while(a--){for(b=0;b<12;b++);}}/********************************数码管延时关断函数******************************************/ void guanduan (void) //用于关断数码管的位选{delay_ms(1); //延时bw=1; //关断百位sw=1; //关断十位gw=1; //关断个位}/********************************公共函数10(显示)********************************************/ void gonggonghanshu10(unsigned char a){a7=a&0x80; //小数点a6=a&0x40; //ga5=a&0x20; //fa4=a&0x10; //ea3=a&0x08; //da2=a&0x04; //ca1=a&0x02; //btihuan=a&0x01; //a}/********************************显示函数****************************************************/ void display(signed int a) //显示函数(显示实际数据除以10,支持显示负数){unsigned char baiwei, shiwei, gewei, d; //定义百位,十位,个位,每次显示帧数signed int c; //用于处理数字aif(a<0) //如果a是负数c=-a; //取a的相反数else //否则c=a; //就直接取ac=c/10;baiwei=c/100; //计算百位c=c%100;shiwei=c/10; //计算十位c=c%10;gewei=c; //计算个位for(d=0;d<20;d++) //显示部分,每次显示20个循环(20帧){if(a<0) //如果a是负数,则百位显示负号gonggonghanshu10(duanma[10]);else //否则直接显示百位gonggonghanshu10(duanma[baiwei]); //显示百位bw=0; //打开百位guanduan(); //延时关断百位gonggonghanshu10(duanma[shiwei]); //显示十位sw=0; //打开十位guanduan(); //延时关断十位gonggonghanshu10(duanma[gewei]); //显示个位gw=0; //打开个位guanduan(); //延时关断个位}}/********************************ADC公共函数**************************************************/ void gonggonghanshu2(void) //此函数测量单片机电源电压{ADC_CONTR=0x88; //ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0 delay_10us(2); //延时等待转换结束ADC_RESL=ADC_RESL&0x03; //取转换结果低八位中的低二位cankaodianya0=(ADC_RES*4+ADC_RESL); //把结果转换成十进制数据(10位ADC,最大值1024)dianyuandianya=2549760/cankaodianya0; //计算电源电压,单位mV}/********************************ADC测电压函数************************************************/void adc (void) //ADC函数,用于测量和计算各种电压{signed char a; //查NTC表用gonggonghanshu2(); //公共函数2(此函数功能是测量电源电压,单位mV)ADC_CONTR=0x89; //ADC控制寄存器设置,转换采用最低速度速,低速更精确(测量t12电压务必使用最低速度AD转换,实测高速误差大) delay_10us(2);ADC_RESL=ADC_RESL&0x03;t12dianya=(ADC_RES*4+ADC_RESL);t12dianya=2490*t12dianya/cankaodianya0; //计算t12电压,单位mVADC_CONTR=0x8a; //ADC控制寄存器设置delay_10us(2);ADC_RESL=ADC_RESL&0x03;ntcdianya=(ADC_RES*4+ADC_RESL);ntcdianya=2490*ntcdianya/cankaodianya0; //计算ntc电压,单位mVfor(a=0;wendubiao[a]<ntcdianya;a++) //查表计算室温{if(a>=61) //如果超出表的范围就取允许的最高温度(50度) break; //并且退出查表}shiwen=(a-11)*10; //得出室温(实际室温乘以10)t12wendu=(t12dianya-100)*43*10/260+shiwen; //计算t12的实际温度,其中260为运放增益if(t12wendu<shiwen) //如果t12温度小于室温t12wendu=shiwen; //就取室温if(t12wendu>5000) //如果得出的温度超过500度,说明没有插入烙铁头或参数错误(因为烙铁头的温度不可能超过500度)t12wendu=5000; //显示500作为错误指示(注意显示函数显示的是1/10,所以要显示500,需要赋值5000)if(huancunkaiguan==1) //如果缓存开关开,说明刚刚改变了设定温度huancun=shedingwendu; //于是显示设定温度(而不是t12温度) elsehuancun=t12wendu; //否则直接显示t12温度}/********************************定时器0初始化函数*******************************************/ void timer0init (void) //定时器0初始化程序,24MHz频率下,每1ms中断一次{TMOD=0x00; //定时模式,16位自动重装TH0=0xf8; //计时1msTL0=0x2f;ET0=1; //开启定时器0中断TR0=1; //启动定时器0}/********************************公共函数6(记录编码器状态)**********************************/ void gonggonghanshu6(void){e=encodera; //记录编码器a脚此次状态f=encoderb; //记录编码器b脚此次状态}/********************************编码器函数(正常加热模式调用)********************************/ void bianmaqi(void){if(e==1&&f==1&&encodera==1&&encoderb==0) //和前一次状态比较确定为右旋{shedingwendu=shedingwendu+100; //步进if(shedingwendu>4500) //最高允许450度shedingwendu=4500;huancun=shedingwendu; //显示改变后的设定温度huancunkaiguan=1; //打开缓存开关(用于延时显示设定温度秒)huancunjishu=0; //重新开始缓存计数}if(e==1&&f==1&&encodera==0&&encoderb==1) //和前一次状态比较确定为左旋{shedingwendu=shedingwendu-100; //步进if(shedingwendu<2000) //最低允许200度shedingwendu=2000;huancun=shedingwendu; //显示改变后的设定温度huancunkaiguan=1; //打开缓存开关(用于延时显示设定温度秒)huancunjishu=0; //重新开始缓存计数}gonggonghanshu6(); //记录编码器状态}/********************************定时器0中断函数********************************************/void timer0(void) interrupt 1 //定时器0中断函数,检测编码器,掉电存储等操作(仅用于正常工作模式){unsigned char buchang;bianmaqi(); //调用编码器函数if(huancunkaiguan==1) //延时显示计数huancunjishu++;zhouqijishu++; //加热周期计数if(jiareshu>190) //最多加热190msjiareshu=190;if(zhouqijishu<=jiareshu) //如果当前计数小于等于加热数t12=1; //就加热else //否则t12=0; //不加热if(t12wendu==5000) //如果t12温度为500,说明没有插入烙铁头或参数严重错误t12=0; //停止加热if(huancunjishu==1500) //如果达到了设定温度延时显示的秒{huancunkaiguan=0; //关闭缓存开关huancunjishu=0; //停止缓存计数huancun=t12wendu; //由显示设定温度改为显示t12温度}if(zhouqijishu==200) //t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高){adc(); //检测电压,计算温度zhouqijishu=0; //重新开始加热周期计数////////////////////以下为加热算法(请自行理解,不作注释)//// /////////////if(t12wendu>shedingwendu){if(t12wendu-shedingwendu<=20)jiareshu=(shedingwendu-1500)/160;elsejiareshu=0;}if(t12wendu<=shedingwendu){wencha=shedingwendu-t12wendu;if(wencha>20){buchang++;if(buchang>150)buchang=150;}elsebuchang=0;if(shedingwendu-t12wendu>=300)jiareshu=198;else if(shedingwendu-t12wendu>=200)jiareshu=160;else if(shedingwendu-t12wendu>=150)jiareshu=130;else if(shedingwendu-t12wendu>=100)jiareshu=90+wencha/2+buchang;else if(shedingwendu-t12wendu>=50)jiareshu=50+buchang*2;elsejiareshu=(shedingwendu-1000)/80+wencha*2/3+buchang;}}}/********************************主函数*****************************************************/ void main (void) //主函数{P1M0=0x00; //P1除,,为输入模式外均为正常模式P1M1=0x07;P1ASF=0x07; //设置P1相应ADC转换的I/O口为ADC输入模式P2M0=0xff; //P2都是推挽模式P2M1=0x00;P3M0=0xf0; //,,,为推挽模式,,为输入模式,P3M1=0x06; //其余正常模式ADC_CONTR=0xe0; //打开ADC电源shedingwendu=3000; //设为300度IE=0x88; //打开定时器0中断,关闭定时器1中断timer0init(); //初始化定时器0while(1){display(huancun); //数码管显示数据}}。

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

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

//**************************************************************************** //// STC12C5A60S2可编程时钟模块////// 说明:STC12C5A60S2单片机有三路可编程时钟输出CLKOUT0/T0/P3.4// CLKOUT1/T1/P3.5、CLKOUT2/P1.0//// 涉及寄存器:AUXR(辅助寄存器)、WAKE_CLKO(时钟与系统掉电唤醒控制寄存器) // BRT(独立波特率发生器定时器寄存器)//// 程序说明:// 本程序可选实现P3.4输出CLKOUT0时钟、P3.5输出CLKOUT1时钟// P1.0输出CLKOUT2时钟//////************************************************************************** **//#include <STC12C5A60S2.H>#include <intrins.h>//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句//若想测试CLKOUT1和CLKOUT0请注释此句#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*///*********************************//// CLKOUT2时钟初始化 ////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x04; //Bit2-BRTCLKO 允许P1.0配置为独立波特率发生器的时钟输出//BRT工作在1T模式下时的输出频率 = Sysclk/(256-BRT)/2 //BRT工作在12T模式下时输出频率 = Sysclk/12/(256-BRT)/2 AUXR = 0x14; //Bit4-BRTR 允许独立波特率发生器运行//Bit2-BRTx12 BRT工作在1T模式下BRT = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频}#else /*条件编译CLKOUT0时钟输出*///*********************************//// CLKOUT0时钟和CLKOUT1初始化 ////*********************************//void CLKOUT_init(void){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倍//12T指的是每12个时钟加1与普通C51一样//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只能工作在定时器模式2下//T1工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2//T1工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2 //1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下//T1定时器速度是普通8051的12倍,即工作在1T模式下TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数//定时器1工作模式为方式2,自动装载时间常数TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL0 = 0xff;TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL1 = 0xff;TR1 = 1;TR0 = 1;}#endif//**********************************//// 主程序////**********************************//void main(){CLKOUT_init();while(1);}//**************************************************************************** //// STC12C5A60S2系统时钟模块////// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时钟// 出厂标准配置是使用外部晶体或时钟////// 涉及寄存器:CLK_DIV(时钟分频寄存器)// 由该寄存器的Bit0-2组合可实现对时钟源进行0、2、4、8、16 // 32、64、128分频// //// 程序说明:// 对外部时钟进行分频得到Sysclk,然后经过P1.0的独立波特率// 时钟输出功能Sysclk/2输出时钟频率//**************************************************************************** //#include <STC12C5A60S2.h>#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 的sysclk//93750 为 93.75kHz 的sysclk//*********************************************//// 系统时钟初始化 ////*********************************************//void Sysclk_init(void){WAKE_CLKO = 0x04; //配置P1.0口为频率输出AUXR = 0x14; //允许波特率时钟工作//工作模式为1TBRT = 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 )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 )CLK_DIV = 0x07;#endif}//**********************************************//// 主程序////**********************************************//void main(){Sysclk_init();while(1);}//**************************************************************************** //// STC12C5A60S2系统省电模块////// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式// 掉电模式////// 涉及寄存器:PCON(电源控制寄存器)// Bit0 - IDL 控制单片机进入IDLE空闲模式// Bit1 - PD 控制单片机进入掉电模式// //// 程序说明:程序实现让单片机先工作一阵子(通过P0^3指示灯显示)// 然后进入掉电状态,利用外部中断0口来唤醒单片机工作// 唤醒后单片机将通过P0^0-3口的灯闪烁显示开始工作////************************************************************************** **//#include <STC12C5A60S2.h>#include <intrins.h>#define uchar unsigned char#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; //外中断唤醒输入口void Delay_ms( uint time );void Normal_work(void);void Intp_init(void);void After_Powr_Down(void);//***********************************//// 软件延时 ////***********************************//void Delay_ms( uint time ){uint t; //延时时间 = (time*1003+16)us while(time--){for( t = 0; t < 82; t++ );}}//***********************************//// 正常工作指示//***********************************//void Normal_work(void){Normal_Work_LED = 1;Delay_ms(500);Normal_Work_LED = 0;Delay_ms(500);}void After_Power_Down(void){uchar i ;for( i = 0; i < 100; i++ ){P0 = 0x0f;Delay_ms(500);P0 = 0x00;Delay_ms(500);}}//***********************************//// 中断初始化 ////***********************************//void Intp_init(void){IT0 = 0; //外部中断源0为低电平触发EX0 = 1; //允许外部中断EA = 1; //开总中断}//***********************************//// 主程序 ////***********************************//void main(){uchar j = 0;uchar wakeup_counter = 0; //记录掉电次数P0 = 0x00;Chip_Start_LED = 1; //单片机开始工作Intp_init(); //外中断0初始化while(1){P2 = wakeup_counter;wakeup_counter++;for( j = 0; j < 250; j++ ){Normal_work(); //系统正常工作指示}Power_Down_Flag = 1; //系统开始进入掉电状态PCON = 0x02;_nop_();_nop_();_nop_();_nop_();After_Power_Down(); //掉电唤醒后}}//**********************************//// 中断服务//**********************************//void INT0_Service(void) interrupt 0{if( Power_Down_Flag ) //掉电唤醒状态指示 {Power_Down_Flag = 0;Power_Down_LED_INT0 = 1;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 ){_nop_();}N_Power_Down_LED_INT0 = 0;}}//**************************************************************************** //// STC12C5A60S2 A/D转换模块////// 说明: 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口的状态,有利于高精度A/D 转换// 若能将定时器/串行/中断系统关闭更好。

STC单片机模拟串口程序

STC单片机模拟串口程序

STC单片机模拟串口程序/*************stc12模拟串口程序*************//*功能:用单片机的任意I/O引脚模拟串口的TXB/RXB*//*适于STC1T系列单片机,波特率默认为9600晶振11.0592工作于1T模式,请根据实际需要直接使用或修改*//*未使用任何软件延时,仅占用了T0及其中断,和纯硬件串口效果完全相同,对其他程序执行无影响*//*示例功能为根据变量nSel的值选择1个字符串数组,并在条件满足时逐字节逐位由模拟串口引脚TXB发送,全部字符发完后置位TSEND 标志*//*发送同时以全双工方式接收数据,收到的字节按顺序循环存入Rbuf[16]中*//*以语音合成芯片SYN6658的命令格式为例,从3段合成文本中任选1段播放*//*数组选择变量nSel的值为1播放第1段,2播放第2段...,0不播放(nSel值的获取方法请根据具体需要添加相应程序段)*/ /*该程序已通过实际调试,误码率为0*//*该程序参考了STC单片机用户手册中的模拟串口程序*//***********作者:ltiaobao,2013.08***********/#include "reg51.h"#include/*define baudrate const*//*BAUD=65536-SYSclk/3/baudrate/M(1T:M=1,12T:M=12)*/ //#defineBAUDOxF400//******************(1T)#defineBAUD0xFE90//******************(1T)//#defineBAUDOxFF00//******************(12T)//#defineBAUDOxFFC0//******************(12T)//#defineBAUDOxFFE0//******************(12T)sfr AUXR=0x8E;sbit RXB=P3^0; //define UART TXD/RXD pinsbit TXB=P3^1;typedef bit BOOL;typedef unsigned char BYTE;typedef unsigned int WORD;BOOL TING,RING;BOOL TBEND,RBEND;BOOL TSEND;BYTE TDAT,RDAT;BYTE TCNT,RCNT; //baudrate counterBYTE nTBIT,nRBIT;BYTE nTbyte,nRbyte;BYTE nSel=1; //number to select string(0-don't send)BYTE Slength; //length of sending stringBYTE xdata *PTS; //pointer of string to sendBYTE xdata Rbuf[16];BYTE xdata headOfFrame[5]={0xFD,0x00,0x00,0x01,0x01};//command head of syn6658BYTE xdata string1[24]={"head,语音合成文本第一段"};BYTE xdata string2[24]={"head,语音合成文本第二段"};BYTE xdata stringn[26]={"head,选择溢出,请重新选择!"};void UART_INIT();void main(){BYTE i;TMOD=0x01; //set T0 to timer working at 16bit(mode1)AUXR=0x80; //T0x12=1,working at 1T modeTL0=BAUD;TH0=BAUD>>8;TR0=1;ET0=1;PT0=1;EA=1;UART_INIT();while(nSel){if(TSEND){if(Rbuf[(nRbyte-1)&0x0f]==0x4A||Rbuf[(nRbyte-1)&0x0f]==0x4F) //JUDGE SYN6658 READY OR NOT{Rbuf[(nRbyte-1)&0x0f]=0x55; //clear 0x4A 0r 0x4F inorder not to play many timesif(nSel==1){PTS=string1;Slength=strlen(string1+5)+5;}else if(nSel==2){PTS=string2;Slength=strlen(string2+5)+5;}else{PTS=stringn;Slength=strlen(stringn+5)+5;}headOfFrame[2]=Slength-3;for(i = 0; i<5; i++){PTS[i]=headOfFrame[i];}TING=1;TSEND=0;nTbyte=0;TCNT=0;nTBIT=0;}}}}/******Timer interrupt routline for UART******/ void tm0() interrupt 1 using 1{TL0=BAUD;TH0=BAUD>>8;if(RING){if(--RCNT==0){RCNT=3; //reset send baudrate counterif(--nRBIT==0) //received 9 bit{nRbyte &=0x0f;Rbuf[nRbyte++]=RDAT; //save the received byte to RBUF RING=0; //stop receiveRBEND=1; //set receive completed flag}else{RDAT>>=1; //receive 1 bitif(RXB) RDAT|=0x80;}}}else if(!RXB) //differentiate staring bit{RING=1;RCNT=4;nRBIT=9;}/*L_RBEND and L_TING*/if(--TCNT==0){TCNT=3; //reset send baudrate counterif(TING) //judge whether sending{if(nTBIT==0){TXB=0; //send start bitTDAT=PTS[nTbyte++]; //load data from string[] to TDAT nTBIT=9; //initial send bit number}else{TDAT>>=1; //shift data to CYif(--nTBIT==0){TXB=1;//TING=0; //stop sendTBEND=1; //set send completed flagif(nTbyte>=Slength){TING=0;TSEND=1;}}else{TXB=CY; //write CY to TXD pin}}}}}/******initial UART module variable******/void UART_INIT(){TING=0;RING=0; TSEND=1; RBEND=0; TCNT=0; RCNT=0; nTbyte=0; }。

STC的双串口程序

STC的双串口程序
EA=1; // 开总中断
}
void UartSendByte(unsigned char i)//单片机向主机发送数据
{
ES=0;
TI=0;
SBUF=i;
while(TI==0);
TI=0;
ES=1;
}
/********************************************************************
{
S2CON=S2CON&0XFE;
if(Num>0)
{
DATA2[20-Num]=S2BUF;//传送字节数
Num--;
}
}
else
{
S2CON=S2CON&0XFD; //S2TI=0
函数功能:串口中断处理。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UartISR(void) interrupt 4 //主机接收单片机数据
}
}
void main()
{
UartInit();
UartInit2();
//接收电脑发来的数组
while(Num>0);
//把接收到的数组发给从机
for(Num=20;Num>0;Num--)
{
UartSendByte2(DATA1[20-Num]);
TH1=256-Fclk/(BitRate*12*Байду номын сангаас6); //计算定时器重装值

stc12双串口

stc12双串口
增强型8051芯片,具有双串口。我以前通常采用软件模拟一个串口来实现,要占用太多的系统资源。该芯片可以通过一个内置的波特率发生器,实现两个串口同时工作在一个波特率下,或一个通过内置,一个通过TH1实现不同波特率的通讯。通过配置AUXR来配置波特率发生器 BRT设置波特率重入装载数,S2CON 配置通讯模式。
{
unsigned char in_data;
if(RI)
{
in_data=SBUF;
RI=0;
}
பைடு நூலகம்
if(TI)
{
TI=0;
}
}
//串口2中断
void serial_2() interrupt 8 using 2
{
unsigned char rti;
unsigned char in_data;
rti=S2CON;
rti=rti & 0x01;
if (rti==1) // 接收
例如: 在12MHz 频率下 两串口工作在 9600,8,1 配置如下
//配置串口1
SCON=0x40; /* n,8,1 */
PCON=0x80; //Bps加倍
TCON=0;
ES=1;
REN=1;
//STC 串口2定义
AUXR=0x1d; //配置两个串口波特率发生器采用内置,1个时钟/机器周期
BRT=0xb2; //重装载数
S2CON=0x50;
IE2=0x01; //ES2=1 //开中端
//串口1中断
void serial_1() interrupt 4 using 2
{

STC系列单片机串口通信的总结

STC系列单片机串口通信的总结
串口通信:
软件调试,在调试过程中需要使用虚拟串口助手。在编程中注意设计时钟和波特率。注意程序的串口设置和串口调试助手中串口设置相同。
单串口:
mode com2 9600,0,8,1
assign com2 <sin> sout
stime = 0
多串口:
mode com2 9600,0,8,1
assign com2 <s0in> s0out
{
uchar Data;
Data = ucRecData;
ucRecData = 0;
return Data;
}
Unsigned char RString(unsigned char *s, unsigned int len)
{
Unsigned int i;
For(i =0;i<len ;i++)
{
{
Unsigned int i;
For(i =0;i<len ;i++)
{
SendData(*s++);
}
}
一个比较好的接收处理框架(利用通信协议):
void UART1_ISR(void) interrupt 4 using 1
{
unsigned char sbuffer;
if(RI)
{
RI = 0;
Rec_Len = 0;
uarttext[0] = sbuffer; //这里保留了包头
}
else if(Rec_Flag) //开始接收
{
if(Rec_Len < (REC_MAX - 1))
{
Rec_Len++;

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码STC 51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码原文:(改自周立功软件包)#include <reg51.h>#include <intrins.h>#define uchar unsigned char /*宏定义*/#define uint unsigned intextern void Delay1us(unsigned char );sbit SDA=P1^6; /*模拟I2C数据传送位*/sbit SCL=P1^7; /*模拟I2C时钟控制位*/bit ack; /*应答标志位*//************************************************************** *****起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.*************************************************************** *****/void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/Delay1us(1);SCL=1;Delay1us(5); /*起始条件建立时间大于4.7us,延时*/SDA=0; /*发送起始信号*/Delay1us(5); /* 起始条件锁定时间大于4μs*/SCL=0; /*钳住I2C总线,准备发送或接收数据 */Delay1us(2);}/************************************************************** *****结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.*************************************************************** *****/void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/Delay1us(1); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4us*/Delay1us(5);SDA=1; /*发送I2C总线结束信号*/Delay1us(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(uchar c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

STC15F2K60S2串口1程序

STC15F2K60S2串口1程序

STC15F2K60S2串口1程序
此程序为才写的串口1,工作模式1 程序,自己测试没问题//本示例在Keil
开发环境下请选择Intel 的8058 芯片型号进行编译//假定测试芯片的工作频率为18.432MHz#include “reg51.h”sfr P4 = 0xc0;sfr P5 = 0xc8;sfr AUXR = 0x8e ;unsigned char temp ;bit flag = 0 ;void UartInit(void) //9600bps@11.0592MHz{SCON = 0x50; //8 位数据,可变波特率AUXR |= 0x40; // 定时器1 时钟为Fosc,即1TAUXR &= 0xFE; //串口1 选择定时器1 为波特率发
生器TMOD &= 0x0F; //设定定时器1 为16 位自动重装方式TL1 = 0xE0; //设定
定时初值TH1 = 0xFE; //设定定时初值ET1 = 0; //禁止定时器1 中断TR1 = 1; // 启动定时器1EA = 1 ; //开启总中断ES = 1 ; //开串口中断}void main( void ) {UartInit() ;SBUF = A ;while(1){if( flag == 1 ){SBUF = temp ;flag = 0 ;}}}void Uart( void ) interrupt 4 using 1{if( RI ){RI = 0 ; temp = SBUF ;flag = 1 ;}if( TI ){TI = 0 ;}}tips:感谢大家的阅读,本文由我司收集整编。

仅供参阅!。

STC单片机双串口使用设置与例程

STC单片机双串口使用设置与例程

STC单片机双串口使用设置与例程在用STC_60s2单片机进行双串口同时收发时,要注意一些容易配置错误的地方。

AUXR寄存器有很多功能。

在对其中的位置位和复位时,很可能在不同的地方多次进行,应该使用AUXR |= bitx 和AUXR &=~bitx 语句进行对某一位的置位和复位。

这样就不会影响其他功能位了。

附上程序:#include ;//sfr AUXR = 0x8E;#define uchar unsigned char//#define uint unsigned int //#define BUADRATE 38400#define FOSC 24000000#define S2RI 0x01#define S2TI 0x02sbit LED1 = P2^7;uchar ReceBuf[200]={0};bit finishflag = 0;uchar revcnt = 0;uchar startflag = 0;void InitUART1(void) //baudrate 115200{TMOD = 0x20;SCON = 0x50;TH1 = 0xf3; //115384TL1 = TH1;PCON = 0x80; //SMOD = 1;ES = 1;TR1 = 1;}void InitUART2() //baudrate 38400{S2CON = 0x50; //8-Bit 串口模式允许接收BRT = 236; //[24000000/(256-236)]/32 = 37500 error2.34%AUXR |= 0x14; //BRTR=1使能BRT BRTx12=1 不分频(AUXR 第二次出现,不能用&lsquo;=&rsquo;应该用&ldquo;|=&rdquo;)IE2 = 0x01; //enable UART2 interruptAUXR1 = 0; //UART2 TXD->;P1.3 RXD->;P1.2}void SendOneByte(unsigned char c){SBUF = c;while(!TI);TI = 0;}void U1SendString(uchar *dat){while(*(dat)!='\0'){SendOneByte(*dat);dat ;}}void U2SendOneByte(unsigned char c) {S2BUF = c;while(!(S2CON & S2TI));S2CON &= ~S2TI;}void U2SendString(uchar *dat){while(*(dat)!='\0'){U2SendOneByte(*dat);dat ;}}void main(){ uchar temp = 0x01;AUXR = AUXR|0x40; // T1, 1T Mode AUXR 第一次出现InitUART1();EA = 1;SendOneByte(0xaa);SendOneByte(0xbb);SendOneByte(0xcc);InitUART2();SendOneByte(0xdd);while(1){// temp = ~temp;// U2SendOneByte(temp);if(finishflag){ LED1 = 1;finishflag = 0;U1SendString(ReceBuf);LED1 = 0;}}void UART1ISR(void) interrupt 4 {if(RI){RI = 0;//add your code here!}elseTI = 0;}void UART2ISR(void) interrupt 8 { static bit flash=0;static uchar i=0;static uchar endcnt = 0;uchar tempdat = 0;if(S2CON & S2RI){S2CON &= ~S2RI;if(~finishflag)flash=~flash;// LED1 = flash;tempdat = S2BUF;if(tempdat=='$'){startflag = 1;}///////////////////////////////////////////////// ///////////if(startflag){ReceBuf[i] = tempdat;i ;///////////////////////////////////////////////// ///////////if(i==6&&ReceBuf[3]!='R'&&ReceBuf[5]!='C') //判断是不是$GPRMC帧{startflag = 0;i = 0;}else if(ReceBuf[i-1]=='*') {endcnt ;if(endcnt==2){revcnt = i;endcnt = 0;i = 0;finishflag = 1;startflag = 0;}}else ;}}else ;}elseS2CON &= ~S2TI;}。

STC15F2K60S2系列串口1通信程序

STC15F2K60S2系列串口1通信程序

STC15F2K60S2系列串口1通信程序#include#include "intrins.h"#include#define FOSC 12000000L //系统频率#define BAUD 9600 //串口波特率#define S1_S0 0x40 //P_SW1.6#define S1_S1 0x80 //P_SW1.7unsigned char a,i=0;unsigned char String[32];bit busy;/*************系统初始化****************/void sys_init(void){P20=1;P32=1;P33=1;//P_SW1=0x40; //P3.6/P3.7串口1 RXD/TXD//P_SW1=0x80; //P1.6/P1.7串口1 RXD/TXD}/*************UART_1 初始化****************/void UartInit(void){SCON = 0x50; //8位数据,可变波特率T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值T2H = (65536 - (FOSC/4/BAUD))>>8;AUXR = 0x14; //T2为1T模式, 并启动定时器2 AUXR |= 0x01; //选择定时器2为串口1的波特率发生器ES = 1; //使能串口1中断}/*************发送字符****************/void SendData(unsigned char dat){while (busy); //等待前面的数据发送完成busy = 1;SBUF = dat; //写数据到UART数据寄存器}/*************发送字符串****************/void SendString(char *s){while (*s) //检测字符串结束标志{SendData(*s++); //发送当前字符}}/*************主函数****************/void main(){sys_init();UartInit();while(1){if(P33==0){// P20=0;SendString("STC15F2K60S2\r\nUart T est !\r\n"); }if(P32==0){//SendData(a);SendString(String);}}}/*************UART_1 中断服务程序****************/ void Uart1() interrupt 4 using 1{if (RI){RI = 0; //清除RI位String[i++]= SBUF; //P0显示串口数据if(i>8)i=0;}if (TI){TI = 0; //清除TI位busy = 0; //清忙标志}}。

STC双串口通信

STC双串口通信
void UART_2Interrupt(void) interrupt 8
{
if(S2CON&S2RI)
{S2CONBiblioteka =~S2RI;flag2=1;
temp2=S2BUF;
}
}
flag2=0;
UART_1SendOneByte(temp2);
}
}
}
/************串行口1中断处理函数*************/
void UART_1Interrupt(void) interrupt 4
{
if(RI==1)
{
RI=0;
flag1=1;
temp1=SBUF;
}
}
/************串行口2中断处理函数*************/
void UART_1SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI);//若TI=0,在此等待
TI = 0;
}
/*void UART_1sendstr(unsigned char *s)
{
while(*s!='\o') // \0表示字符串结束标志,通过检测字符串末尾
void main(void)
{
InitUART();//串行口初始化
while(1)
{
//如果串口1接收到数据,将此数据由串口2发送
if(flag1==1)
{
flag1=0;
UART_2SendOneByte(temp1);
}
//如果串口2接收到数据,将此数据由串口1发送
if(flag2==1)

STC12C5A60S2双串口通信例程

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。

STC12C5A系列单片机串口编程

STC12C5A系列单片机串口编程

STC12C5A系列单片机串口编程串口头文件uart.h如下:=================================================================== /** File : uart.h* Description : This file is UART driver header of STC12C5A serial signal chip.* Author : Chao* Copyright : Chao** History* ----------------------* Rev : 0.0* Date : 20/08/2011** create.* ----------------------*/#ifndef UART_H_#define UART_H_//---------------Config-------------------------//#define UART1_EN //使能串口1#define UART1_RECEIVE_EN //允许串口1中断接收函数#define UART2_EN //使能串口2#define UART2_RECEIVE_EN //允许串口2中断接收函数//#define ECHO //使能回显//---------------Defines-------------------------//#define SystemFosc 22118400 //系统时钟:22.1184MHz#define UartBaud 9600 //串口波特率#define UART_BUFFER_SIZE 16 //串口数据缓冲区大小#define UartEndChar '>' //串口数据结束字符//---------------Type define-------------------------//typedef struct {unsigned int receive_flag; //数据接收标志unsigned char data_length; //数据缓冲区中有效数据个数unsigned char receive_buffer[UART_BUFFER_SIZE]; //数据接收缓冲区void (* init)(void); //串口初始化函数void (* send_byte)(unsigned char ddata); //发送单个字符void (* send_string)(unsigned char *ddata, unsigned char length); //发送字符串}UART_T;//---------------Extern-------------------------//#ifdef UART1_ENextern UART_T uart1;#endif#ifdef UART2_ENextern UART_T uart2;#endif#endif /*UART_H_*/======================================================================== 串口编程C程序文件uart.c如下:======================================================================== /** File : uart.c* Description : This file is UART driver of STC12C5A serial signal chip.* Author : Chao* Copyright : Chao** History* ----------------------* Rev : 0.0* Date : 20/08/2011** create.* ----------------------*///---------------Include files-------------------------//#include<stc12c5a.h>#include"uart.h"//---------------Function Prototype-------------------------//#ifdef UART1_ENstatic void uart1_init(void); //串口1初始化函数static void uart1_send_byte(unsigned char ddata); //串口1发送单个字符static void uart1_send_string(unsigned char *ddata, unsigned char length); //串口1发送字符串#endif#ifdef UART2_ENstatic void uart2_init(void); //串口2初始化函数static void uart2_send_byte(unsigned char ddata); //串口2发送单个字符static void uart2_send_string(unsigned char *ddata, unsigned char length); //串口2发送字符串#endif//---------------Variable-------------------------//unsigned long Fosc; //波特率设定时中间变量#ifdef UART1_ENUART_T uart1 = {0, // receive_flag0, // data_length"Hello\n", // receive_bufferuart1_init, // inituart1_send_byte, // send_byteuart1_send_string // send_string};unsigned char uart1_receive_temp;unsigned char *uart1_receive_point=uart1.receive_buffer;#endif#ifdef UART2_ENunsigned char uart1_receive_temp;UART_T uart2 = {0, // receive_flag0, // data_length"Hello\n", // receive_bufferuart2_init, // inituart2_send_byte, // send_byteuart2_send_string, // send_string};unsigned char uart2_receive_temp;unsigned char *uart2_receive_point=uart2.receive_buffer;#endif#ifdef UART1_EN/** ---- FUNCTION ----------------------------------------------------------------------- * Name : uart1_init* Description : 串口1初始化程序* -------------------------------------------------------------------------------------------- */static void uart1_init(void){unsigned long baud;//选择波特率产生方式:采用独立波特率发生器AUXR |= S1BRS;//设定波特率发生器重新计数初值Fosc = SystemFosc/32;baud = UartBaud;if(baud > 9600)AUXR |= BRTx12; //时钟频率不分频elseFosc /= 12;BRT = 256-Fosc/baud;//启动波特率发生器AUXR |= BRTR;SCON = 0x50; //设定串口1工作方式:方式1(8n1),允许接收ES = 1; //开串口1中断}/** === FUNCTION ---------------------------------------------------------------------* Name : uart1_send_byte* Description : 串口1发送单个字节数据* --------------------------------------------------------------------------------------------*/static void uart1_send_byte(unsigned char ddata){SBUF = ddata; //写入要发送的字符while(!TI); //等待发送完毕TI = 0; //清发送标志}/** === FUNCTION ---------------------------------------------------------------------* Name : uart1_send_string* Description : 串口1发送以'\0'结尾的字符串* --------------------------------------------------------------------------------------------*/static void uart1_send_string(unsigned char *ddata, unsigned char length){while(length--)uart1_send_byte(*ddata++);}#ifdef UART1_RECEIVE_EN/** === FUNCTION ---------------------------------------------------------------------* Name : ISR_uart1* Description : 串口1中断数据接收程序* --------------------------------------------------------------------------------------------*/void ISR_uart1(void) interrupt 4{if(RI) //确认接收到字符{uart1_receive_temp = SBUF;#ifdef ECHOuart1.send_byte(uart1_receive_temp);#endifif(uart1_receive_temp != UartEndChar) //如果没有接收到(假设接收缓冲区足够大){*uart1_receive_point++ = uart1_receive_temp;uart1.data_length++;}else{uart1_receive_point = uart1.receive_buffer; //重新将接收字符指针指向接收缓冲区头uart1.receive_flag = 1; //置位接收命令完成标志}RI = 0; //清接收标志}}#endif#endif#ifdef UART2_EN/** === FUNCTION ---------------------------------------------------------------------* Name : uart2_init* Description : 串口1初始化程序* --------------------------------------------------------------------------------------------*/static void uart2_init(void){#ifndef UART1_ENunsigned long baud;//选择波特率产生方式:采用独立波特率发生器AUXR |= S1BRS;//设定波特率发生器重新计数初值Fosc = SystemFosc/32;baud = UartBaud;if(baud > 9600)AUXR |= BRTx12; //时钟频率不分频elseFosc /= 12;BRT = 256-Fosc/UartBaud;//启动波特率发生器AUXR |= BRTR;#endifS2CON=0x50; //设定串口工作方式:方式1(8n1),允许接收IE2=0x01; //允许串口2中断}/** --- FUNCTION ---------------------------------------------------------------------* Name : uart2_send_byte* Description : 串口2发送单个字节数据* --------------------------------------------------------------------------------------------*/static void uart2_send_byte(unsigned char ddata){S2CON &= 0xFD; //清发送标志S2BUF = ddata; //发送数据while(!(S2CON&0x02)); //等待发送完成}/** === FUNCTION ---------------------------------------------------------------------* Name : uart2_send_string* Description : 串口2发送以'\0'结尾的字符串* --------------------------------------------------------------------------------------------*/static void uart2_send_string(unsigned char *ddata, unsigned char length){while(length--)uart2_send_byte(*ddata++);}#ifdef UART2_RECEIVE_EN/** ----- FUNCTION ---------------------------------------------------------------------* Name : ISR_uart2* Description : 串口2中断数据接收程序* --------------------------------------------------------------------------------------------*/void ISR_uart2(void) interrupt 8 //单片机接收从机发来的数据{if(S2CON&0x01) //如果接收到数据{uart2_receive_temp = S2BUF; //读取数据#ifdef ECHOuart2.send_byte(uart2_receive_temp);#endifif(uart2_receive_temp != UartEndChar) //如果没有接收到(假设接收缓冲区足够大){*uart2_receive_point++ = uart2_receive_temp;uart2.data_length++;}else{uart2_receive_point = uart2.receive_buffer; //重新将接收字符指针指向接收缓冲区头uart2.receive_flag = 1; //置位接收命令完成标志}S2CON &= 0xFE; //清接收标志}}#endif#endif======================================================================= 通过上面两个文件,就能很方便的实现STC12C5A系列单片机中串口操作,并且能够通过配置uart.h文件来实现串口1、串口2的条件编译,测试主函数main.c如下:======================================================================= #include<stc12c5a.h>#include"uart.h"void Sys_init(void); //系统初始化void main(){Sys_init();while(1){if(uart1.receive_flag){uart1.send_string(uart1.receive_buffer, uart1.data_length);uart1.receive_flag = 0;uart1.data_length = 0;}if(uart2.receive_flag){uart2.send_string(uart2.receive_buffer, uart2.data_length);uart2.receive_flag = 0;uart2.data_length = 0;}}}void Sys_init(void) //系统初始化{uart1.init();uart1.send_string("uart1\r\n",7);uart2.init();uart2.send_string("uart2\r\n",7);EA = 1;}该测试主函数实现的功能是:上电后,从串口1、串口2分别输出字符串"uart1\r\n"、“uart2\r\n”,然后两路串口分别等待接收数据,接收的字符串以字符“>”作为结束标志(可以在uart.h文件中进行修改),串口每接收完一个以“>”作为结尾的字符串,会通过相应串口将接收的字符串发送出去。

STC15系列51增强版单片机串行通信实现方法串行口1模式1,T2定时器

STC15系列51增强版单片机串行通信实现方法串行口1模式1,T2定时器

IAP15W4K58S4单片机串行通信实现方法串行口1模式1,T2定时器01基础知识当软件设置SCON的SM0和SM1为“01”时,串行口1则以模式1工作。

此模式为8为UART格式,一帧信息为10位;1位起始位,8位数据位(低位在先)和1位停止位。

TxD/P3.1位发送信息,RxD/P3.0位接收信息,串口全双工。

串行口涉及的相关寄存器如下表,串行通信模式1,其波特率可变,当串行口1用定时器T2作为波特率发生器时,串行口1的波特率=(定时器T2的溢出率)/4。

(此时波特率与SMOD无关)当T2工作在1T模式(AUXR.2/T2x12=1)时,定时器T2的溢出率=SYSclk/(65536-[RL_TH2,RL_TL2])。

02设置步骤(1)设置串口1的工作模式,SCON寄存器的SM0和SM1两位决定了串口1的4中工作方式,本文选用方式1,故SMON=0x50。

(2)设置串口1的波特率,使用定时器2寄存器T2H及T2L。

(3)设置寄存器AUXR中的T2x12/AUXR.2,确定定时器2速度是1T还是2T(4)启动定时器2,让T2R位为1,T2H/T2L定时器2寄存器立即开始计数。

(5)设置串口1的中断优先级,及打开中断相应的控制位是PS、ES、EA(6)如要串口1接收,先将SCON寄存器的REN位置1,若串口1发送,将数据送入SBUF即可,接收完的标志位RI,发送完成标志位TI,都要软件清0。

当串口1工作在模式1时,需要计算相应波特率设置的T2重装的初值(用Reload表示),送入T2H/T2L。

计算公式如下:Reload=65536-INT(SYSclk/Baud0/4+0.5)SYSclk=晶振频率,Baud0=标准波特率,INT()表示取整和运算,+0.5四舍五入。

设置时,T2x12/AUXR.2=1,1T工作模式,重新核算用Reload产生的波特率,Baud= SYSclk/(65536-Reload)/4。

stc 单片机编程指南

stc 单片机编程指南

}
else
{
TI=0;
}
}
2.各串口接收标志位
a.串口 2:if(S2CON&0x01)置零:S2CON&=0xfe;
b.串口 3:if(S3CON&0x01)置零:S3CON&=0xfe;
c.串口 4:if(S4CON&0x01)置零:S4CON&=0xfe;
3.各串口发送标志位
a.串口 2:if(S2CON&0x02)置零:S2CON&=0xfd;
T4T3M &= 0xDF; //定时器 4 时钟为 Fosc/12,即 12T
T4L = 0xE8; //设定定时初值
T4H = 0xFF; //设定定时初值
T4T3M |= 0x80; //启动定时器 4
}
如果用到不同的定时器,把定时器的那部分改一下就好~
6.RS485 半双工异步通信(收发控制由 P1.0 口控制,其他的和串口通信一样)
{
AUXR &= 0xFB;
//定时器时钟 12T 模式
T2L = 0x00; //设置定时初值
T2H = 0xDC; //设置定时初值
AUXR |= 0x10;
//定时器 2 开始计时
}
C.定时器 3:
void Timer3Init(void) //10 毫秒@11.0592MHz
{
T4T3M &= 0xFD; //定时器时钟 12T 模式
EA=1;//开总中断开关
while(1);
}
void Timer0Init(void) //10 毫秒@11.0592MHz
{
AUXR &= 0x7F;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

功 能:
********************************************************************/
void Timer0_Routine(void) interrupt 1
{
TH0 = 0xdc; //重置计数初值
s1_send_data[2] = adc_data[1] /256;
s1_send_data[3] = adc_data[1] %256;
s1_send_data[4] = adc_data[2] /256;
s1_send_data[5] = adc_data[2] %256;
write_e2_time = 0;
finish_write_e2 = 0;
start_write_e2 = 1;
while(!finish_write_e2);
AT24CXX_Page_Write(0xa0,0x10,Test_Write_Data,16);
write_e2_time = 0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
P2 = 0x00;
STC_ADC_Init();
/*if(AT24CXX_Random_Read(0xa0,0x00) != 0x68)
{
AT24CXX_Byte_Write(0xa0,0x00,0x68);
}
}
/*******************************************************************
定时器0中断子程序
函数原型: void Timer0_Routine(void) interrupt 1;
#include "STC_ADC_MODULE.h"
//#include "CRC16.h"
/*******************************************************************
主函数
{
TI = 0; //清发送标志位
if(s1_current_send_number <s1_send_number) //判断发送数据个数
{
SBUF = s1_send_data[s1_current_send_number]; //发送缓存数据
TL0 = 0x00;
watch_dog_interval++; //喂狗间隔变量加1
if(watch_dog_interval >=WATCH_DOG_INTERVAL) //喂狗间隔变量大于喂狗间隔,则喂狗
{
watch_dog_interval = 0;
finish_write_e2 = 0;
start_write_e2 = 1;
while(!finish_write_e2);
}*/
while(1)
{
if(send_1_byte)
{
send_1_byte = 0;
//s1_send_data[0] = AT24CXX_Random_Read(0xa0,0x00);
adc_data[1] = Get_STC_ADC_Result(5);
adc_data[2] = Get_STC_ADC_Result(6);
s1_send_data[0] = adc_data[0] /256;
s1_send_data[1] = adc_data[0] %256;
SCON = 0x50; //串口1工作方式3(9位UART),允许接收 S2CON 9AH name: SM0/FE SM1 SM2 REN TB8 RB8 TI RI
// 1 1 1 1 0 0 0 0 = 0xf0
ST = ~ST;
}
if(start_write_e2)
{
write_e2_time ++;
if(write_e2_time >=2)
{
write_e2_time = 0;
start_write_e2 = 0;
finish_write_e2 = 1;
if(RI)
{
RI = 0;
switch(s1_receive_number) //判断接收数据个数
{
case 0: {
if(SBUF == 0x01)
{
send_1_byte = 1;
}
P1M1 = 0x70;
P1M0 = 0x00;
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1 TCON 88H name: GATE C/T M1 M0 GATE C/T M1 M0 (高4位定时器1,低4位定时器0)
}
}
}
/*******************************************************************
串口1中断子程序
函数原型: void Uart1_Routine(void) interrupt 4;
s1_send_number = 6;
s1_current_send_number = 0;
TI = 1;
}
else if(s2_send_1_byte)
{
s2_send_1_byte = 0;
ADM2483_RD1 = 1;
s1_send_number = 16;
s1_current_send_number = 0;
TI = 1;
}
else if(send_byte)
{
send_byte = 0;
//s1_send_data[0] = AT24CXX_Current_Address_Read(0xa0);
TH1 = 0xfa; //波特率9600
TL1 = 0xfa;
PCON = 0x80; //SMOD = 1,波特率加倍 PCON 87H name: SMOD SMOD0 LVDF POF GF1 GF0 PD IDL
// 1 0 0 0 0 0 0 0 = 0x80
// 0 0 1 0 0 0 0 1 = 0x21
TH0 = 0xdc; //定时器0产生10ms定时中断
TL0 = 0x00;
ET0 = 1; //允许T0中断
ES = 1; //串口1中断允许
BRT = 0xfa; //独立波特率发生器重装时间常数 波特率9600
S2CON = 0x50; //串口2工作方式1(8位UART),允许接收 S2CON 9AH name: S2SM0 S2SM1 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI
s2_send_data[0] = 1;
s2_send_data[1] = 9;
s2_send_number = 2;
s2_current_send_number = 0;
S2CON = S2CON | 0x02;
}
// 0 1 0 1 0 0 0 0 = 0x50
AUXR = 0x18;
IE2 = 0x01;
TR0 = 1; //启动定时器0
TR1 = 1; //启动定时器1
EA = 1;
ADM2483_RD1 = 0;
ADM2483_RD2 = 0;
//ANGEL_VOLTAGE_1 = 0;
//ANGEL_VOLTAGE_2 = 0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
s1_send_number = 1;
s1_current_send_number = 0;
TI = 1;
}
else if(send_16_byte)
{
send_16_byte = 0;
//AT24CXX_Sequential_Read(0xa0,0x20,s1_send_data,16);
s1_send_number = 1;
s1_current_send_number = 0;
TI = 1;
}
else if(send_adc_data)
{
send_adc_data = 0;
adc_data[0] = Get_STC_ADC_Result(4);
#include "STC12C5A60S2.h"
#include "IO_Configure.h"
#include "intrins.h"
#include "MACRO_DEFINITION.h"
#include "VARIABLE.h"
//#include "AT24CXX.h"
函数原型: void Main(void);
功 能:
********************************************************************/
void main(void)
{
uint adc_data[3];
else if(SBUF == 0x02)
相关文档
最新文档