首页 STC12C5A60S2精简开发板带232及485产品使用手册

STC12C5A60S2精简开发板带232及485产品使用手册

举报
开通vip

STC12C5A60S2精简开发板带232及485产品使用手册STC12C5A60S2精简开发板带232及485产品使用手册 STC12C5A60S2单片机开发学习板带232及485产品使用手册 【简要说明】 一、尺寸:长80mmX宽71mmX高12mm 二、主要芯片:STC12C5A60S2单片机 三、工作电压:直流6~36伏 四、、特点: 1、具有电源指示; 2、所有I/O口已引出; 3、可以实现与电脑串口通信; 4、可以实现RS485通讯; 5、具有上电复位和手动复位; 6、LM2596宽电压稳压芯片; 7、支持STC串口下载以及UART口下...

STC12C5A60S2精简开发板带232及485产品使用手册
STC12C5A60S2精简开发板带232及485产品使用 手册 华为质量管理手册 下载焊接手册下载团建手册下载团建手册下载ld手册下载 STC12C5A60S2单片机开发学习板带232及485产品使用手册 【简要说明】 一、 尺寸 手机海报尺寸公章尺寸朋友圈海报尺寸停车场尺寸印章尺寸 :长80mmX宽71mmX高12mm 二、主要芯片:STC12C5A60S2单片机 三、工作电压:直流6~36伏 四、、特点: 1、具有电源指示; 2、所有I/O口已引出; 3、可以实现与电脑串口通信; 4、可以实现RS485通讯; 5、具有上电复位和手动复位; 6、LM2596宽电压稳压芯片; 7、支持STC串口下载以及UART口下载; 8、串口通讯(注:只能使用下载程序); 9、八路LED灯(注:可拔出短路帽,断开LED灯); 10、可端子接线供电、可排针引电; 11、输入电压范围宽,且确保AD参考电压准确(注:因无外部参考电压点); 1 12、四位按键输入,一位按键复位。 五、提供相关软件、资料、原理图 适用场合:单片机学习、电子竞赛、产品开发、毕业设计。。。 注意啦:本产品提供的所有程序都附带原理图以及说明~ 【图片标注】 【连接图】 2 【原理图】(放大可以看清楚) 【PCB尺寸图】 3 【开发板支持同系列单片机的型号】 4 STC单片机最新型号——STC12C5A60S2 STC12C5A60S2/AD/PWM系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。 1.增强型8051 CPU,1T,单时钟/机器周期,指令代码完全兼容传统8051; 2.工作电压:STC12C5A60S2系列工作电压:5.5V-3.3V(5V单片机)STC12LE5A60S2系列工作电压:3.6V-2.2V(3V单片机); 3.工作频率范围:0 - 35MHz,相当于普通8051的 0,420MHz; 4.用户应用程序空间8K /16K / 20K / 32K / 40K / 48K / 52K / 60K / 62K 字节; 5 5.片上集成128 0字 个人自传范文3000字为中华之崛起而读书的故事100字新时代好少年事迹1500字绑架的故事5000字个人自传范文2000字 节RAM; 6.通用I/O口(36/40/44个),复位后为:准双向口/弱上拉(普通8051传统I/O口),可设置成四种模式:准双向口/弱上拉,推挽/强上拉,仅为输入/高阻,开漏,每个I/O口驱动能力均可达到20mA,但整个芯片最大不要超过55Ma; 7. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器 可通过串口(P3.0/P3.1)直接下载用户程序,数秒即可完成一片; 8.有EEPROM功能(STC12C5A62S2/AD/PWM无内部EEPROM); 9. 看门狗; 10.内部集成MAX810专用复位电路(外部晶体12M以下时,复位脚可直接1K电阻到地); 11.外部掉电检测电路:在P4.6口有一个低压门槛比较器,5V单片机为1.32V,误差为+/-5%,3.3V单片机为1.30V,误差为+/-3%; 12.时钟源:外部高精度晶体/时钟,内部R/C振荡器(温漂为+/-5%到+/-10%以内) 1用户在下载用户程序时,可选择是使用内部R/C振荡器还是外部晶体/时钟,常温下内部R/C振荡器频率为:5.0V单片机为:11MHz,15.5MHz,3.3V单片机为:8MHz,12MHz,精度要求不高时,可选择使用内部时钟,但因为有制造误差和温漂,以实际测试为准; 13.共4个16位定时器 两个与传统8051兼容的定时器/计数器,16位定时器T0和T1,没有定时器2,但有独立波特率发生器 做串行通讯的波特率发生器 再加上2路PCA模块可再实现2个16位定时器; 14. 2个时钟输出口,可由T0的溢出在P3.4/T0输出时钟,可由T1的溢出在P3.5/T1输出时钟; 15.外部中断I/O口7路,传统的下降沿中断或低电平触发中断,并新增支持上升沿中断的PCA模块, Power Down模式可由外部中断唤醒, INT0/P3.2,INT1/P3.3,T0/P3.4, T1/P3.5, RxD/P3.0,CCP0/P1.3(也可通过寄存器设置到P4.2 ), CCP1/P1.4 (也可通过寄存器设置到P4.3); 16. PWM(2路)/PCA(可编程计数器阵列,2路): ——也可用来当2路D/A使用 ——也可用来再实现2个定时器 ——也可用来再实现2个外部中断(上升沿中断/下降沿中断均可分别或同时支持); 17.A/D转换, 10位精度ADC,共8路,转换速度可达250K/S(每秒钟25万次)18.通用全双工异步串行口(UART),由于STC12系列是高速的8051,可再用定时器或PCA软件实现多串口; 19. STC12C5A60S2系列有双串口,后缀有S2标志的才有双串口,RxD2/P1.2(可通过寄存器设置到P4.2),TxD2/P1.3(可通过寄存器设置到P4.3); 6 20.工作温度范围:-40 - +85?(工业级) / 0 - 75?(商业级)21.封装:PDIP-40,LQFP-44,LQFP-48 I/O口不够时,可用2到3根普通I/O口线外接 74HC164/165/595(均可级联)来扩展I/O口, 还可用A/D做按键扫描来节省I/O口,或用双CPU,三线通信,还多了串口。 【产品展示】 7 8 9 10 11 【产品加壳展示】 12 13 14 15 16 【单片机支持的USB转串口线下载】 通过USB转串口线下载,需要断开再启动一下电源开关~ STC12C5A60S2单片机USB转串口线下载说明: 1、连接串口线:USB头连接电脑,并安装驱 动。 2、9针串口头连接开发板串口1。 3、开发板接电源,VCC接正极,GND接负极,并断开电源开关。 4、打开下载软件,选择USB转串口线的串口号,并打开要下载的文件。 5、点击下载,等待软件提示给开发板供电。 6、软件提示供电后,按下电源开关,等待程序下载完成。 【单片机编程软件KEIL】 【单片机编程软件界面如下】 17 【单片机下载软件】 【单片机下载软件界面】 18 【STC12C5A60S2系列单片机单片机开发应用参考程序】 001、STC12C5A60S2单片机之闪烁灯 002、STC12C5A60S2单片机之流水灯 003、STC12C5A60S2单片机之跑马灯 004、STC12C5A60S2单片机之简单的按键识别 005、STC12C5A60S2单片机之按键识别的应用 006、STC12C5A60S2单片机之数码管动态显示 007、STC12C5A60S2单片机之SD卡读写 008、STC12C5A60S2单片机之串口一应用 009、STC12C5A60S2单片机之串口二应用 010、STC12C5A60S2单片机之串口简单收发 011、STC12C5A60S2单片机之双串口通信 012、STC12C5A60S2单片机之不同波特率串口12通讯演示 013、STC12C5A60S2单片机之串口2演示程序9位数据 014、STC12C5A60S2单片机之演示(ADC查询方式) 015、STC12C5A60S2单片机之演示(ADC中断方式) 016、STC12C5A60S2单片机之AT24C04测试程序1T 19 017、STC12C5A60S2单片机之AT24C04测试程序12T 018、STC12C5A60S2单片机之DS18B20温度传感器1T 019、STC12C5A60S2单片机之DS18B20温度传感器12T 020、STC12C5A60S2单片机之DS1302应用1T 021、STC12C5A60S2单片机之DS1302应用12T 022、STC12C5A60S2单片机之串口通信单主单从 023、STC12C5A60S2单片机之串口通信互为主从 024、STC12C5A60S2单片机之EEPROM 025、STC12C5A60S2单片机之PWM 001、STC12C5A60S2单片机之闪烁灯: /******************************************************************** 实现功能:闪烁灯 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:9600 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ /********************************************************************/ #include //库文件 #include #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** I/O定义 *********************************************************************/ sbit LED=P0^0; //定义单片机P0口的第0位 (即P0.0) /******************************************************************** 延时100MS函数 *********************************************************************/ void Delay100ms() { uchar i, j, k; _nop_(); i = 5; 20 j = 144; k = 71; do { do { while (--k); } while (--j); } while (--i); } /******************************************************************** 延时1S函数 *********************************************************************/ void Delay1s(uint s) { uchar m,n; for(m=s;m>0;m--) for(n=10;n>0;n--) Delay100ms(); } /******************************************************************** 主函数 *********************************************************************/ void main() { while(1) //无限循环 { LED=0; //点亮P1.0口灯 Delay1s(1); //延时 LED=1; //熄灭P1.0口灯 Delay1s(1); //延时 } } /******************************************************************** 结束 *********************************************************************/ 002、STC12C5A60S2单片机之流水灯: /******************************************************************** 实现功能:流水灯 21 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:9600 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include //库文件 #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ uchar temp; //定义字符型变量 uchar a,b,i; /******************************************************************** 延时函数 *********************************************************************/ void delay()//延时程序 { uchar m,n,s; for(m=10;m>0;m--) for(n=200;n>0;n--) for(s=248;s>0;s--); } /******************************************************************** 主函数 *********************************************************************/ void main() { temp=0xfe; //11111110定义每次一个灯亮 while(1) { P3=P2=P0=P1=temp;//直接对1/0口赋值,使批输出低电平。 delay();//延时 for(i=1;i<8;i++)//实现广告灯的从右到左移动 { a=temp< //库文件 #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ 定义字符型变量 uchar temp; // uchar a,b,i; /******************************************************************** 延时函数 *********************************************************************/ void delay()//延时程序 { uchar m,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--); } /******************************************************************** 主函数 *********************************************************************/ void main() { while(1) { temp=0xfe; //11111110定义每次一个灯亮 P3=P2=P0=P1=temp;//直接对1/0口赋值,使批输出低电平。 23 delay();//延时 for(i=1;i<8;i++)//实现广告灯的从右到左移动 { a=temp<>(8-i); //右移8-i位 P3=P2=P0=P1=a|b;//相与求值 delay(); } for(i=1;i<8;i++)//实现广告灯的从左到右移动 { a=temp>>i; //右移i位 b=temp<<(8-i); //左移8-i位 P3=P2=P0=P1=a|b;//相与求值 delay(); } } } /******************************************************************** 结束 *********************************************************************/ 004、STC12C5A60S2单片机之简单的按键识别: /******************************************************************** 实现功能:简单的按键识别 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:9600 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include //库文件 #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** I/O定义 *********************************************************************/ sbit LED1=P0^0; //定义单片机P0口的第0位 (即P0.0)//为输出 sbit LED2=P0^1; //定义单片机P0口的第1位 (即P0.1)//为输出 sbit LED3=P0^2; //定义单片机P0口的第2位 (即P0.2)//为输出 sbit LED4=P0^3; //定义单片机P0口的第3位 (即P0.3)//为输出 24 sbit key1=P2^0; //定义单片机P2口的第0位 (即P2.0)//为输入 sbit key2=P2^1; //定义单片机P2口的第1位 (即P2.1)//为输入 sbit key3=P2^2; //定义单片机P2口的第2位 (即P2.2)//为输入 sbit key4=P2^3; //定义单片机P2口的第3位 (即P2.3)//为输入 /******************************************************************** 延时函数 *********************************************************************/ void delay()//延时程序 { uchar m,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--); } /******************************************************************** 主函数 *********************************************************************/ void main() { while(1) { if(key1==0){delay();if(key1==0){LED1=0;while(!key1);LED1=1;}} //如果key1按键按下,P01.0口输 出低电平,指示灯亮。 if(key2==0){delay();if(key2==0){LED2=0;while(!key2);LED2=1;}} //如果key1按键按下,P01.0口输 出低电平,指示灯亮。 if(key3==0){delay();if(key3==0){LED3=0;while(!key3);LED3=1;}} //如果key1按键按下,P01.0口输 出低电平,指示灯亮。 if(key4==0){delay();if(key4==0){LED4=0;while(!key4);LED4=1;}} //如果key1按键按下,P01.0口输 出低电平,指示灯亮。 } } /******************************************************************** 结束 *********************************************************************/ 005、STC12C5A60S2单片机之按键识别的应用: /******************************************************************** 实现功能:按键识别的应用 使用芯片:STC12C5A60S2 25 晶振:11.0592MHZ 波特率:9600 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include //库文件 #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ uchar count; //按键计数,每按一下,count 加1 uchar a,b; //定义字符型变量 uchar temp; //定义字符型变量 sbit BY1=P2^0; //定义按键的输入端(为单片机P2口的P2.1按键) /******************************************************************** 延时函数 *********************************************************************/ void delay10ms(void) //延时程序 { uchar i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } /******************************************************************** 按键判断函数 *********************************************************************/ void key() //按键判断程序 { if(BY1==0) //判断是否按下键盘 { delay10ms(); //延时,软件去干扰 if(BY1==0) //确认按键按下 { count++; //按键计数加1 if(count==8) //计8次重新计数 { count=0;//将count 清零 } } while(BY1==0);//按键锁定,每按一次count 只加1. } 26 } /******************************************************************** 主函数 *********************************************************************/ void main() { temp=0xfe; //定义为11111110 while(1) { key(); //调用按键判断函数 a=temp<>(8-count);//右移8-count位 P0=a|b; //求值 } } /******************************************************************** 结束 *********************************************************************/ 006、STC12C5A60S2单片机之数码管动态显示: /******************************************************************** 实现功能:STC12C5A60S2单片机之数码管动态显示 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:9600 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include //库文件 #include #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ code uchar seg7code[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //显示段码 数码 管字跟 uchar wei[4]={0XEf,0XDf,0XBf,0X7f}; //位的控制端 /******************************************************************** 延时函数 27 *********************************************************************/ void delay(uchar t) { uchar i,j; for(i=0;i0;j--); { ; } } } /******************************************************************** 显示函数 *********************************************************************/ void Led(int date) //显示函数 { /*****************数据转换*****************************/ uint z,x,c,v; z=date/1000; //求千位 x=date%1000/100; //求百位 c=date%100/10; //求十位 v=date%10; //求个位 P2=0XFF; P0=seg7code[z]; P2=wei[0]; delay(80); P2=0XFF; P0=seg7code[x]; P2=wei[1]; delay(80); P2=0XFF; P0=seg7code[c]; P2=wei[2]; delay(80); P2=0XFF; P0=seg7code[v]; P2=wei[3]; delay(80); P2=0XFF; } /******************************************************************** 28 主函数 *********************************************************************/ void main() { { int display_date=1358; //定义并赋值要显示的数据 while(1) { Led(display_date);//调用显示函数显示数据display_date } } } /******************************************************************** 结束 *********************************************************************/ 007、STC12C5A60S2单片机之SD卡读写: /******************************************************************** 芯片 :STC12C5A60S2 :11.0592MHZ 晶振 开发平台:KEIL 功能 :向SD卡读写一个扇区,如果成功则激活P0口流水灯,如果失败则无流水灯。并且随程序运行向串口发送运行状态。 波特率 :9600BPS 日期 :11.5.19 其他 :本程序软件模拟SPI,随后我会改为硬件SPI 注意 :下载完程序后请复位系统后运行~(切记~~) -------------------------------------------------------------*/ #include "STC12C5A60S2.h" #include "uart.h" #include "sd.h" #define uchar unsigned char #define uint unsigned int uchar xdata tab[512]; //定义外部ROM,512个字节,数据缓冲区(一个扇区必须写512字节 ) void delay5ms() { uchar a,b; for(b=19;b>0;b--) for(a=130;a>0;a--); } void delay500ms() 29 { uchar a,b,c; for(c=23;c>0;c--) for(b=152;b>0;b--) for(a=70;a>0;a--); } void main() { int i; uchar flag=0; init(); //初始化串口 txd_s("串口初始化\n"); SD_Reset(); //复位SD卡 txd_s("SD卡复位完\n"); SD_Init(); //初始化SD卡 txd_s("SD卡初始化完\n"); for(i=0;i<512;i++) tab[i]=i; //向数据缓冲区中写入0~255 0~255,共512个字节 txd_s("缓冲区写完\n"); SD_Write_Sector(20,tab); //将数据缓冲区中的512个字节的数据写入SD卡的第20扇区 中 delay5ms(); txd_s("扇区写完\n"); for(i=0;i<512;i++) //清空数据缓冲区 tab[i]=0; txd_s("清缓冲区\n"); SD_Read_Sector(20,tab); //从SD卡的第20扇区中读取512个字节的数据到数据缓冲区 txd_s("读扇区完\n"); for(i=0;i<512;i++) if(((uchar)i)!=tab[i]) //对读出的数据进行匹配,如果不吻合则flag=1,否则 flag=0 { flag=1; break; } delay5ms(); txd_s("匹配完毕\n"); if(flag==0) { delay5ms(); txd_s("匹配对 \n"); P0=0xfe; while(1) { P0=P0>>1|P0<<7; delay500ms(); } 30 } else { delay5ms(); txd_s("匹配错 \n"); } while(1); } /******************************************************************** 结束 *********************************************************************/ 008、STC12C5A60S2单片机之串口一应用: /******************************************************************** 实现功能:STC12C5A60S2单片机之串口一应用 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:9600 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ :串口一收发8位数据。(采用中断方式,T1产生波特率) 功能 其他 :采用查询方式发送稳定,但是接收数据极不稳定由于 官方资料使用的是中断方式,所以建议使用中断方式收发数据。 注意 :下载完程序后请复位系统后运行~(切记~~) *********************************************************************/ #include "STC12C5A60S2.h" //库文件 #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ uchar tab[]={"www.ourhc.cn"}; //程序下载完毕后,连接串口,波特率9600 单片机复位后会自动收到 数据 uchar dat=0; /******************************************************************** 延时函数 *********************************************************************/ void delay ( uchar t ) { uchar i,j; for( i=0; i 格式 pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载 是:(通道口,数据) 注意:通道口必须有模拟量输入数据才有效。 *********************************************************************/ #include "reg52.h" #include "intrins.h" #define FOSC 18432000L #define BAUD 9600 typedef unsigned char BYTE; typedef unsigned int WORD; /******************************************************************** 初始化设置 *********************************************************************/ sfr ADC_CONTR = 0xBC; //ADC 控制寄存器 sfr ADC_RES = 0xBD; //ADC 转换结果寄存器 sfr ADC_LOW2 = 0xBE; //ADC 低2位结果寄存器 sfr P1ASF = 0x9D; //Pl口模拟功能控制寄存器 /******************************************************************** ADC 数据转换函数 *********************************************************************/ #define ADC_POWER 0x80 //ADC 电源控制位 #define ADC_FLAG 0x10 //ADC 转换结束标志位 #define ADC_START 0x08 //ADC 开始转换控制位 #define ADC_SPEEDLL 0x00 //420 个时钟周期转换一次 #define ADC_SPEEDL 0x20 //280 个时钟周期转换一次 #define ADC_SPEEDH 0x40 //140 个时钟周期转换一次 #define ADC_SPEEDHH 0x60 //70 个时钟周期转换一次 /******************************************************************** 延时函数 45 *********************************************************************/ void Delay(WORD n) { WORD x; while (n--) { x = 5000; while (x--); } } /******************************************************************** 串口初始化 *********************************************************************/ void InitUart() { SCON = 0x5a; TMOD = 0x20; TH1 = TL1 = -(FOSC/12/32/BAUD); TR1 = 1; } /******************************************************************** 串口数据输出函数 *********************************************************************/ void SendData(BYTE dat) { while (!TI); //等待数据 TI = 0; //清零标志位 SBUF = dat; //发送数据 } /******************************************************************** ADC 初始化 *********************************************************************/ void InitADC() { P1ASF = 0xff; //设置P1口为开漏模式,使用AD功能 ADC_RES = 0; //AD数据寄存器清空 ADC_CONTR = ADC_POWER | ADC_SPEEDLL; //打开AD电源,转换周期420 Delay(2); //延时 } /******************************************************************** ADC 数据转换函数 *********************************************************************/ BYTE GetADCResult(BYTE ch) { 46 ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;//开始转换 _nop_(); //延时一个机器周期 _nop_(); //延时一个机器周期 _nop_(); //延时一个机器周期 _nop_(); //延时一个机器周期 while (!(ADC_CONTR & ADC_FLAG));//等待转换结束 ADC_CONTR &= ~ADC_FLAG; //关闭AD转换 return ADC_RES; //返回数据 } /******************************************************************** 编辑数据函数 *********************************************************************/ void ShowResult(BYTE ch) { SendData(ch); //发送显示通道 SendData(GetADCResult(ch)); //发送对应通道的数据 // SendData(ADC_LOW2); //如果你想显示10位结果,选择下一行 } /******************************************************************** 主函数 *********************************************************************/ void main() { InitUart(); //串口初始化 InitADC(); //AD转换初始化 while (1) { ShowResult(0); //显示第一通道的数值 ShowResult(1); //显示第二通道的数值 } } /******************************************************************** 结束 *********************************************************************/ 015、STC12C5A60S2单片机之演示(ADC中断方式): /******************************************************************** 实现功能:STC12C5A60S2单片机之演示(ADC中断方式) 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 47 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ 程序说明: 1、P1口八路AD数据转换。 2、将转换的数据通过串口发送出去。 3、发送数据的格式是:(通道口,数据) 注意:通道口必须有模拟量输入数据才有效。 *********************************************************************/ #include "reg52.h" #include "intrins.h" #define FOSC 18432000L #define BAUD 9600 typedef unsigned char BYTE; typedef unsigned int WORD; /*Declare SFR associated with the ADC */ sfr ADC_CONTR = 0xBC; //ADC control register sfr ADC_RES = 0xBD; //ADC hight 8-bit result register sfr ADC_LOW2 = 0xBE; //ADC low 2-bit result register sfr 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 #define ADC_SPEEDLL 0x00 //420 clocks #define ADC_SPEEDL 0x20 //280 clocks #define ADC_SPEEDH 0x40 //140 clocks #define ADC_SPEEDHH 0x60 //70 clocks void InitUart(); void SendData(BYTE dat); void Delay(WORD n); void InitADC(); BYTE ch = 0; //ADC channel NO. void main() 48 { InitUart(); //Init UART, use to show ADC result InitADC(); //Init ADC sfr IE = 0xa0; //Enable ADC interrupt and Open master interrupt switch //Start A/D conversion while (1); } /*---------------------------- ADC interrupt service routine ----------------------------*/ void adc_isr() interrupt 5 using 1 { ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag SendData(ch); //Show Channel NO. SendData(ADC_RES); //Get ADC high 8-bit result and Send to UART //if you want show 10-bit result, uncomment next line // SendData(ADC_LOW2); //Show ADC low 2-bit result if (++ch > 7) ch = 0; //switch to next channel ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch; } /*---------------------------- Initial ADC sfr ----------------------------*/ void InitADC() { P1ASF = 0xff; //Set all P1 as analog input port ADC_RES = 0; //Clear previous result ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch; Delay(2); //ADC power-on delay and Start A/D conversion } /*---------------------------- Initial UART ----------------------------*/ void InitUart() { SCON = 0x5a; //8 bit data ,no parity bit TMOD = 0x20; //T1 as 8-bit auto reload TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate 49 TR1 = 1; //T1 start running } /*---------------------------- Send one byte data to PC Input: dat (UART data) Output:- ----------------------------*/ void SendData(BYTE dat) { while (!TI); //Wait for the previous data is sent TI = 0; //Clear TI flag SBUF = dat; //Send current data } /*---------------------------- Software delay function ----------------------------*/ void Delay(WORD n) { WORD x; while (n--) { x = 5000; while (x--); } } /******************************************************************** 结束 *********************************************************************/ 016、STC12C5A60S2单片机之AT24C04测试程序1T: /******************************************************************** 实现功能:STC12C5A60S2单片机之AT24C04测试程序1T 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ 50 *********************************************************************/ #include "REG52.H" #include "INTRINS.H" typedef unsigned char BYTE; typedef unsigned short WORD; sbit SCL = P3^4; //AT24C04的时钟 sbit SDA = P3^5; //AT24C04的数据 BYTE BUF[16]; //数据缓存区 BYTE code TESTDATA[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }; void Delay5us(); void Delay5ms(); void AT24C04_Start(); void AT24C04_Stop(); void AT24C04_SendACK(bit ack); bit AT24C04_RecvACK(); void AT24C04_SendByte(BYTE dat); BYTE AT24C04_RecvByte(); void AT24C04_ReadPage(); void AT24C04_WritePage(); void main() { AT24C04_WritePage(); Delay5ms(); AT24C04_ReadPage(); while (1); } /************************************** 向AT24C04写1页(16字节)数据 将TESTDATA开始的16个测试数据写如设备的00~0F地址中 **************************************/ void AT24C04_WritePage() 51 { BYTE i; AT24C04_Start(); //起始信号 AT24C04_SendByte(0xa0); //发送设备地址+写信号 AT24C04_SendByte(0x00); //发送存储单元地址 for (i=0; i<16; i++) { AT24C04_SendByte(TESTDATA[i]); } AT24C04_Stop(); //停止信号 } /************************************** 从AT24C04读取1页(16字节)数据 将设备的00~0F地址中的数据读出存放在DATA区的BUF中 **************************************/ void AT24C04_ReadPage() { BYTE i; AT24C04_Start(); //起始信号 AT24C04_SendByte(0xa0); //发送设备地址+写信号 AT24C04_SendByte(0x00); //发送存储单元地址 AT24C04_Start(); //起始信号 AT24C04_SendByte(0xa1); //发送设备地址+读信号 for (i=0; i<16; i++) { BUF[i] = AT24C04_RecvByte(); if (i == 15) { AT24C04_SendACK(1); //最后一个数据需要会NAK } else { AT24C04_SendACK(0); //回应ACK } } AT24C04_Stop(); //停止信号 } /************************************** 延时5微秒(STC12C5A60S2@12M) 不同的工作环境,需要调整此函数 52 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同 **************************************/ void Delay5us() { BYTE n = 4; while (n--) { _nop_(); _nop_(); } } /************************************** 延时5毫秒(STC12C5A60S2@12M) 不同的工作环境,需要调整此函数 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同 **************************************/ 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; //拉低时钟线 } 53 /************************************** 停止信号 **************************************/ void AT24C04_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时 } /************************************** 发送应答信号 入口参数:ack (0:ACK 1:NAK) **************************************/ void AT24C04_SendACK(bit ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } /************************************** 接收应答信号 **************************************/ bit AT24C04_RecvACK() { SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时 return CY; } /************************************** 向IIC总线发送一个字节数据 **************************************/ void AT24C04_SendByte(BYTE dat) 54 { BYTE i; for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } AT24C04_RecvACK(); } /************************************** 从IIC总线接收一个字节数据 **************************************/ BYTE AT24C04_RecvByte() { BYTE i; BYTE dat = 0; SDA = 1; //使能内部上拉,准备读取数据 for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 Delay5us(); //延时 dat |= SDA; //读数据 SCL = 0; //拉低时钟线 Delay5us(); //延时 } return dat; } /******************************************************************** 结束 *********************************************************************/ 017、STC12C5A60S2单片机之AT24C04测试程序12T: /******************************************************************** 55 实现功能:STC12C5A60S2单片机之AT24C04测试程序12T 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" typedef unsigned char BYTE; typedef unsigned short WORD; sbit SCL = P3^4; //AT24C04的时钟 sbit SDA = P3^5; //AT24C04的数据 BYTE BUF[16]; //数据缓存区 BYTE code res[6] _at_ 0x23; BYTE code TESTDATA[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }; void Delay5us(); void Delay5ms(); void AT24C04_Start(); void AT24C04_Stop(); void AT24C04_SendACK(bit ack); bit AT24C04_RecvACK(); void AT24C04_SendByte(BYTE dat); BYTE AT24C04_RecvByte(); void AT24C04_ReadPage(); void AT24C04_WritePage(); void main() { AT24C04_WritePage(); Delay5ms(); 56 AT24C04_ReadPage(); while (1); } /************************************** 向AT24C04写1页(16字节)数据 将TESTDATA开始的16个测试数据写如设备的00~0F地址中 **************************************/ void AT24C04_WritePage() { BYTE i; AT24C04_Start(); //起始信号 AT24C04_SendByte(0xa0); //发送设备地址+写信号 AT24C04_SendByte(0x00); //发送存储单元地址 for (i=0; i<16; i++) { AT24C04_SendByte(TESTDATA[i]); } AT24C04_Stop(); //停止信号 } /************************************** 从AT24C04读取1页(16字节)数据 将设备的00~0F地址中的数据读出存放在DATA区的BUF中 **************************************/ void AT24C04_ReadPage() { BYTE i; AT24C04_Start(); //起始信号 AT24C04_SendByte(0xa0); //发送设备地址+写信号 AT24C04_SendByte(0x00); //发送存储单元地址 AT24C04_Start(); //起始信号 AT24C04_SendByte(0xa1); //发送设备地址+读信号 for (i=0; i<16; i++) { BUF[i] = AT24C04_RecvByte(); if (i == 15) { AT24C04_SendACK(1); //最后一个数据需要会NAK } 57 else { AT24C04_SendACK(0); //回应ACK } } AT24C04_Stop(); //停止信号 } /************************************** 延时5微秒(STC90C52RC@12M) 不同的工作环境,需要调整此函数 当改用1T的MCU时,请调整此延时函数 **************************************/ void Delay5us() { _nop_(); _nop_(); } /************************************** 延时5毫秒(STC90C52RC@12M) 不同的工作环境,需要调整此函数 当改用1T的MCU时,请调整此延时函数 **************************************/ void Delay5ms() { WORD n = 560; while (n--); } /************************************** 起始信号 **************************************/ void AT24C04_Start() { SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 0; //产生下降沿 Delay5us(); //延时 SCL = 0; //拉低时钟线 } 58 /************************************** 停止信号 **************************************/ void AT24C04_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时 } /************************************** 发送应答信号 入口参数:ack (0:ACK 1:NAK) **************************************/ void AT24C04_SendACK(bit ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } /************************************** 接收应答信号 **************************************/ bit AT24C04_RecvACK() { SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时 return CY; } /************************************** 向IIC总线发送一个字节数据 **************************************/ void AT24C04_SendByte(BYTE dat) { 59 BYTE i; for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } AT24C04_RecvACK(); } /************************************** 从IIC总线接收一个字节数据 **************************************/ BYTE AT24C04_RecvByte() { BYTE i; BYTE dat = 0; SDA = 1; //使能内部上拉,准备读取数据 for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 Delay5us(); //延时 dat |= SDA; //读数据 SCL = 0; //拉低时钟线 Delay5us(); //延时 } return dat; } /******************************************************************** 结束 *********************************************************************/ 018、STC12C5A60S2单片机之DS18B20温度传感器1T: /******************************************************************** 实现功能:STC12C5A60S2单片机之DS18B20温度传感器1T 使用芯片:STC12C5A60S2 60 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" typedef unsigned char BYTE; sbit DQ = P3^3; //DS18B20的数据口位P3.3 BYTE TPH; //存放温度值的高字节 BYTE TPL; //存放温度值的低字节 void DelayXus(BYTE n); void DS18B20_Reset(); void DS18B20_WriteByte(BYTE dat); BYTE DS18B20_ReadByte(); void main() { 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不同 **************************************/ void DelayXus(BYTE n) 61 { while (n--) { _nop_(); _nop_(); } } /************************************** 复位DS18B20,并检测设备是否存在 **************************************/ void DS18B20_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字节数据 **************************************/ BYTE DS18B20_ReadByte() { BYTE i; BYTE dat = 0; for (i=0; i<8; i++) //8位计数器 { dat >>= 1; DQ = 0; //开始时间片 DelayXus(1); //延时等待 DQ = 1; //准备接收 DelayXus(1); //接收延时 if (DQ) dat |= 0x80; //读取数据 DelayXus(60); //等待时间片结束 62 } return dat; } /************************************** 向DS18B20写1字节数据 **************************************/ void DS18B20_WriteByte(BYTE dat) { char i; for (i=0; i<8; i++) //8位计数器 { DQ = 0; //开始时间片 DelayXus(1); //延时等待 dat >>= 1; //送出数据 DQ = CY; DelayXus(60); //等待时间片结束 DQ = 1; //恢复数据线 DelayXus(1); //恢复延时 } } /******************************************************************** 结束 *********************************************************************/ 019、STC12C5A60S2单片机之DS18B20温度传感器12T: /******************************************************************** 实现功能:STC12C5A60S2单片机之DS1302应用1T 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" 63 typedef unsigned char BYTE; sbit SCLK = P1^0; //DS1302时钟口P1.0 sbit IO = P1^1; //DS1302数据口P1.1 sbit RST = P1^2; //DS1302片选口P1.2 //秒 分 时 日 月 星期 年 BYTE code init[] = {0x00, 0x00, 0x20, 0x01, 0x01, 0x05, 0x10}; BYTE data now[7]; void DS1302_Initial(); void DS1302_SetTime(BYTE *p); void DS1302_GetTime(BYTE *p); void main() { DS1302_Initial(); //初始化DS1302 DS1302_SetTime(init); //设置初始时间 DS1302_GetTime(now); //读取当前时间 while (1); } /************************************** 延时X微秒(STC12C5A60S2@12M) 不同的工作环境,需要调整此函数 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同 **************************************/ void Delay() { _nop_(); _nop_(); } /************************************** 从DS1302读1字节数据 **************************************/ BYTE DS1302_ReadByte() { BYTE i; BYTE dat = 0; for (i=0; i<8; i++) //8位计数器 { 64 SCLK = 0; //时钟线拉低 Delay(); //延时等待 dat >>= 1; //数据右移一位 if (IO) dat |= 0x80; //读取数据 SCLK = 1; //时钟线拉高 Delay(); //延时等待 } return dat; } /************************************** 向DS1302写1字节数据 **************************************/ void DS1302_WriteByte(BYTE dat) { char i; for (i=0; i<8; i++) //8位计数器 { SCLK = 0; //时钟线拉低 Delay(); //延时等待 dat >>= 1; //移出数据 IO = CY; //送出到端口 SCLK = 1; //时钟线拉高 Delay(); //延时等待 } } /************************************** 读DS1302某地址的的数据 **************************************/ BYTE DS1302_ReadData(BYTE addr) { BYTE dat; RST = 0; Delay(); SCLK = 0; Delay(); RST = 1; Delay(); DS1302_WriteByte(addr); //写地址 dat = DS1302_ReadByte(); //读数据 65 SCLK = 1; RST = 0; return dat; } /************************************** 往DS1302的某个地址写入数据 **************************************/ void DS1302_WriteData(BYTE addr, BYTE dat) { RST = 0; Delay(); SCLK = 0; Delay(); RST = 1; Delay(); DS1302_WriteByte(addr); //写地址 DS1302_WriteByte(dat); //写数据 SCLK = 1; RST = 0; } /************************************** 写入初始时间 **************************************/ void DS1302_SetTime(BYTE *p) { BYTE addr = 0x80; BYTE n = 7; DS1302_WriteData(0x8e, 0x00); //允许写操作 while (n--) { DS1302_WriteData(addr, *p++); addr += 2; } DS1302_WriteData(0x8e, 0x80); //写保护 } /************************************** 读取当前时间 **************************************/ void DS1302_GetTime(BYTE *p) 66 { BYTE addr = 0x81; BYTE n = 7; while (n--) { *p++ = DS1302_ReadData(addr); addr += 2; } } /************************************** 初始化DS1302 **************************************/ void DS1302_Initial() { RST = 0; SCLK = 0; DS1302_WriteData(0x8e, 0x00); //允许写操作 DS1302_WriteData(0x80, 0x00); //时钟启动 DS1302_WriteData(0x90, 0xa6); //一个二极管,4K电阻充电 DS1302_WriteData(0x8e, 0x80); //写保护 } /******************************************************************** 结束 *********************************************************************/ 020、STC12C5A60S2单片机之DS1302应用1T: /******************************************************************** 实现功能:STC12C5A60S2单片机之DS1302应用1T 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" 67 typedef unsigned char BYTE; sbit SCLK = P1^0; //DS1302时钟口P1.0 sbit IO = P1^1; //DS1302数据口P1.1 sbit RST = P1^2; //DS1302片选口P1.2 //秒 分 时 日 月 星期 年 BYTE code init[] = {0x00, 0x00, 0x20, 0x01, 0x01, 0x05, 0x10}; BYTE data now[7]; void DS1302_Initial(); void DS1302_SetTime(BYTE *p); void DS1302_GetTime(BYTE *p); void main() { DS1302_Initial(); //初始化DS1302 DS1302_SetTime(init); //设置初始时间 DS1302_GetTime(now); //读取当前时间 while (1); } /************************************** 延时X微秒(STC12C5A60S2@12M) 不同的工作环境,需要调整此函数 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同 **************************************/ void Delay() { _nop_(); _nop_(); } /************************************** 从DS1302读1字节数据 **************************************/ BYTE DS1302_ReadByte() { BYTE i; BYTE dat = 0; for (i=0; i<8; i++) //8位计数器 68 { SCLK = 0; //时钟线拉低 Delay(); //延时等待 dat >>= 1; //数据右移一位 if (IO) dat |= 0x80; //读取数据 SCLK = 1; //时钟线拉高 Delay(); //延时等待 } return dat; } /************************************** 向DS1302写1字节数据 **************************************/ void DS1302_WriteByte(BYTE dat) { char i; for (i=0; i<8; i++) //8位计数器 { SCLK = 0; //时钟线拉低 Delay(); //延时等待 dat >>= 1; //移出数据 IO = CY; //送出到端口 SCLK = 1; //时钟线拉高 Delay(); //延时等待 } } /************************************** 读DS1302某地址的的数据 **************************************/ BYTE DS1302_ReadData(BYTE addr) { BYTE dat; RST = 0; Delay(); SCLK = 0; Delay(); RST = 1; Delay(); DS1302_WriteByte(addr); //写地址 69 dat = DS1302_ReadByte(); //读数据 SCLK = 1; RST = 0; return dat; } /************************************** 往DS1302的某个地址写入数据 **************************************/ void DS1302_WriteData(BYTE addr, BYTE dat) { RST = 0; Delay(); SCLK = 0; Delay(); RST = 1; Delay(); DS1302_WriteByte(addr); //写地址 DS1302_WriteByte(dat); //写数据 SCLK = 1; RST = 0; } /************************************** 写入初始时间 **************************************/ void DS1302_SetTime(BYTE *p) { BYTE addr = 0x80; BYTE n = 7; DS1302_WriteData(0x8e, 0x00); //允许写操作 while (n--) { DS1302_WriteData(addr, *p++); addr += 2; } DS1302_WriteData(0x8e, 0x80); //写保护 } /************************************** 读取当前时间 **************************************/ 70 void DS1302_GetTime(BYTE *p) { BYTE addr = 0x81; BYTE n = 7; while (n--) { *p++ = DS1302_ReadData(addr); addr += 2; } } /************************************** 初始化DS1302 **************************************/ void DS1302_Initial() { RST = 0; SCLK = 0; DS1302_WriteData(0x8e, 0x00); //允许写操作 DS1302_WriteData(0x80, 0x00); //时钟启动 DS1302_WriteData(0x90, 0xa6); //一个二极管,4K电阻充电 DS1302_WriteData(0x8e, 0x80); //写保护 } /******************************************************************** 结束 *********************************************************************/ 021、STC12C5A60S2单片机之DS1302应用12T: /******************************************************************** 实现功能:STC12C5A60S2单片机之DS1302应用12T 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" 71 #include "INTRINS.H" typedef unsigned char BYTE; sbit SCLK = P1^0; //DS1302时钟口P1.0 sbit IO = P1^1; //DS1302数据口P1.1 sbit RST = P1^2; //DS1302片选口P1.2 //秒 分 时 日 月 星期 年 BYTE code init[] = {0x00, 0x00, 0x20, 0x01, 0x01, 0x05, 0x10}; BYTE data now[7]; void DS1302_Initial(); void DS1302_SetTime(BYTE *p); void DS1302_GetTime(BYTE *p); void main() { DS1302_Initial(); //初始化DS1302 DS1302_SetTime(init); //设置初始时间 DS1302_GetTime(now); //读取当前时间 while (1); } /************************************** 从DS1302读1字节数据 **************************************/ BYTE DS1302_ReadByte() { BYTE i; BYTE dat = 0; for (i=0; i<8; i++) //8位计数器 { SCLK = 0; //时钟线拉低 _nop_(); //延时等待 _nop_(); dat >>= 1; //数据右移一位 if (IO) dat |= 0x80; //读取数据 SCLK = 1; //时钟线拉高 μè′y _nop_(); //?óê? _nop_(); } 72 return dat; } /************************************** 向DS1302写1字节数据 **************************************/ void DS1302_WriteByte(BYTE dat) { char i; for (i=0; i<8; i++) //8位计数器 { SCLK = 0; //时钟线拉低 _nop_(); //延时等待 _nop_(); dat >>= 1; //移出数据 IO = CY; //送出到端口 SCLK = 1; //时钟线拉高 _nop_(); //延时等待 _nop_(); } } /************************************** 读DS1302某地址的的数据 **************************************/ BYTE DS1302_ReadData(BYTE addr) { BYTE dat; RST = 0; _nop_(); //延时等待 _nop_(); SCLK = 0; _nop_(); //延时等待 _nop_(); RST = 1; _nop_(); //延时等待 _nop_(); DS1302_WriteByte(addr); //写地址 dat = DS1302_ReadByte(); //读数据 SCLK = 1; RST = 0; 73 return dat; } /************************************** 往DS1302的某个地址写入数据 **************************************/ void DS1302_WriteData(BYTE addr, BYTE dat) { RST = 0; _nop_(); //延时等待 _nop_(); SCLK = 0; _nop_(); //延时等待 _nop_(); RST = 1; _nop_(); //延时等待 _nop_(); DS1302_WriteByte(addr); //写地址 DS1302_WriteByte(dat); //写数据 SCLK = 1; RST = 0; } /************************************** 写入初始时间 **************************************/ void DS1302_SetTime(BYTE *p) { BYTE addr = 0x80; BYTE n = 7; DS1302_WriteData(0x8e, 0x00); //允许写操作 while (n--) { DS1302_WriteData(addr, *p++); addr += 2; } DS1302_WriteData(0x8e, 0x80); //写保护 } /************************************** 读取当前时间 **************************************/ 74 void DS1302_GetTime(BYTE *p) { BYTE addr = 0x81; BYTE n = 7; while (n--) { *p++ = DS1302_ReadData(addr); addr += 2; } } /************************************** 初始化DS1302 **************************************/ void DS1302_Initial() { RST = 0; SCLK = 0; DS1302_WriteData(0x8e, 0x00); //允许写操作 DS1302_WriteData(0x80, 0x00); //时钟启动 DS1302_WriteData(0x90, 0xa6); //一个二极管,4K电阻充电 DS1302_WriteData(0x8e, 0x80); //写保护 } /******************************************************************** 结束 *********************************************************************/ 022、STC12C5A60S2单片机之串口通信单主单从: /******************************************************************** 实现功能:STC12C5A60S2单片机之串口通信单主单从 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" 75 #define FOSC 18432000L #define BAUD (256 - FOSC / 32 / 115200) typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long DWORD; sfr AUXR = 0x8e; //Auxiliary register sfr SPSTAT = 0xcd; //SPI status register #define SPIF 0x80 //SPSTAT.7 #define WCOL 0x40 //SPSTAT.6 sfr SPCTL = 0xce; //SPI control register #define SSIG 0x80 //SPCTL.7 #define SPEN 0x40 //SPCTL.6 #define DORD 0x20 //SPCTL.5 #define MSTR 0x10 //SPCTL.4 #define CPOL 0x08 //SPCTL.3 #define CPHA 0x04 //SPCTL.2 #define SPDHH 0x00 //CPU_CLK/4 #define SPDH 0x01 //CPU_CLK/16 #define SPDL 0x02 //CPU_CLK/64 #define SPDLL 0x03 //CPU_CLK/128 sfr SPDAT = 0xcf; //SPI data register sbit SPISS = P1^3; //SPI slave select, connect to slave' SS(P1.4) pin void InitUart(); void InitSPI(); void SendUart(BYTE dat); //send data to PC BYTE RecvUart(); //receive data from PC BYTE SPISwap(BYTE dat); //swap SPI data between master and slave /////////////////////////////////////////////////////////// void main() { InitUart(); //initial UART InitSPI(); //initial SPI while (1) { #ifdef MASTER //for master (receive UART data from PC and send it to slave, in the meantime 76 // receive SPI data from slave and send it to PC) SendUart(SPISwap(RecvUart())); #else //for salve (receive SPI data from master and ACC = SPISwap(ACC); // send previous SPI data to master) #endif } } /////////////////////////////////////////////////////////// void InitUart() { SCON = 0x5a; //set UART mode as 8-bit variable baudrate TMOD = 0x20; //timer1 as 8-bit auto reload mode AUXR = 0x40; //timer1 work at 1T mode TH1 = TL1 = BAUD; //115200 bps TR1 = 1; } /////////////////////////////////////////////////////////// void InitSPI() { SPDAT = 0; //initial SPI data SPSTAT = SPIF | WCOL; //clear SPI status #ifdef MASTER SPCTL = SPEN | MSTR; //master mode #else SPCTL = SPEN; //slave mode #endif } /////////////////////////////////////////////////////////// void SendUart(BYTE dat) { while (!TI); //wait pre-data sent TI = 0; //clear TI flag SBUF = dat; //send current data } /////////////////////////////////////////////////////////// BYTE RecvUart() 77 { while (!RI); //wait receive complete RI = 0; //clear RI flag return SBUF; //return receive data } /////////////////////////////////////////////////////////// BYTE SPISwap(BYTE dat) { #ifdef MASTER SPISS = 0; //pull low slave SS #endif SPDAT = dat; //trigger SPI send while (!(SPSTAT & SPIF)); //wait send complete SPSTAT = SPIF | WCOL; //clear SPI status #ifdef MASTER SPISS = 1; //push high slave SS #endif return SPDAT; //return received SPI data } /******************************************************************** 结束 *********************************************************************/ 023、STC12C5A60S2单片机之串口通信互为主从: /******************************************************************** 实现功能:STC12C5A60S2单片机之串口通信互为主从 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" #define FOSC 18432000L #define BAUD (256 - FOSC / 32 / 115200) 78 typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long DWORD; sfr AUXR = 0x8e; //Auxiliary register sfr SPSTAT = 0xcd; //SPI status register #define SPIF 0x80 //SPSTAT.7 #define WCOL 0x40 //SPSTAT.6 sfr SPCTL = 0xce; //SPI control register #define SSIG 0x80 //SPCTL.7 #define SPEN 0x40 //SPCTL.6 #define DORD 0x20 //SPCTL.5 #define MSTR 0x10 //SPCTL.4 #define CPOL 0x08 //SPCTL.3 #define CPHA 0x04 //SPCTL.2 #define SPDHH 0x00 //CPU_CLK/4 #define SPDH 0x01 //CPU_CLK/16 #define SPDL 0x02 //CPU_CLK/64 #define SPDLL 0x03 //CPU_CLK/128 sfr SPDAT = 0xcf; //SPI data register sbit SPISS = P1^3; //SPI slave select, connect to other MCU's SS(P1.4) pin void InitUart(); void InitSPI(); void SendUart(BYTE dat); //send data to PC BYTE RecvUart(); //receive data from PC BYTE SPISwap(BYTE dat); //swap SPI data between master and slave /////////////////////////////////////////////////////////// void main() { InitUart(); //initial UART InitSPI(); //initial SPI while (1) { if (RI) { SPCTL = SPEN | MSTR; //set as master SendUart(SPISwap(RecvUart())); SPCTL = SPEN; //reset as slave 79 } if (SPSTAT & SPIF) { SPSTAT = SPIF | WCOL; //clear SPI status SPDAT = SPDAT; //mov data from receive buffer to send buffer } } } /////////////////////////////////////////////////////////// void InitUart() { SCON = 0x5a; //set UART mode as 8-bit variable baudrate TMOD = 0x20; //timer1 as 8-bit auto reload mode AUXR = 0x40; //timer1 work at 1T mode TH1 = TL1 = BAUD; //115200 bps TR1 = 1; } /////////////////////////////////////////////////////////// void InitSPI() { SPDAT = 0; //initial SPI data SPSTAT = SPIF | WCOL; //clear SPI status SPCTL = SPEN; //slave mode } /////////////////////////////////////////////////////////// void SendUart(BYTE dat) { while (!TI); //wait pre-data sent TI = 0; //clear TI flag SBUF = dat; //send current data } /////////////////////////////////////////////////////////// BYTE RecvUart() { while (!RI); //wait receive complete RI = 0; //clear RI flag 80 return SBUF; //return receive data } /////////////////////////////////////////////////////////// BYTE SPISwap(BYTE dat) { SPISS = 0; //pull low slave SS SPDAT = dat; //trigger SPI send while (!(SPSTAT & SPIF)); //wait send complete SPSTAT = SPIF | WCOL; //clear SPI status SPISS = 1; //push high slave SS return SPDAT; //return received SPI data } /******************************************************************** 结束 *********************************************************************/ 024、STC12C5A60S2单片机之EEPROM: /******************************************************************** 实现功能:STC12C5A60S2单片机之EEPROM 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ *********************************************************************/ #include "REG52.H" #include "INTRINS.H" typedef unsigned char INT8U; typedef unsigned int INT16U; sfr IAP_DATA = 0xC2; sfr IAP_ADDRH = 0xC3; sfr IAP_ADDRL = 0xC4; sfr IAP_CMD = 0xC5; sfr IAP_TRIG = 0xC6; sfr IAP_CONTR = 0xC7; 81 //定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数 //#define ENABLE_ISP 0x80 //系统工作时钟<30MHz 时,对IAP_CONTR 寄存器设置此值 //#define ENABLE_ISP 0x81 //系统工作时钟<24MHz 时,对IAP_CONTR 寄存器设置此值 #define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值 //#define ENABLE_ISP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值 //#define ENABLE_ISP 0x84 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值 //#define ENABLE_ISP 0x85 //系统工作时钟<3MHz 时,对IAP_CONTR 寄存器设置此值 //#define ENABLE_ISP 0x86 //系统工作时钟<2MHz 时,对IAP_CONTR 寄存器设置此值 //#define ENABLE_ISP 0x87 //系统工作时钟<1MHz 时,对IAP_CONTR 寄存器设置此值 #define DEBUG_DATA 0x5A //本测试程序最终存储在 EEPROM 单元的数值 #define DATA_FLASH_START_ADDRESS 0x00 //STC5Axx 系列 EEPROM 测试起始地址 union union_temp16 { INT16U un_temp16; INT8U un_temp8[2]; }my_unTemp16; INT8U Byte_Read(INT16U add); //读一字节,调用前需打开IAP 功能 void Byte_Program(INT16U add, INT8U ch); //字节编程,调用前需打开IAP 功能 void Sector_Erase(INT16U add); //擦除扇区 void IAP_Disable(); //关闭IAP 功能 void Delay(); void main (void) { INT16U eeprom_address; INT8U read_eeprom; P1 = 0xF0; //演示程序开始,让 P1[3:0] 控制的灯亮 Delay(); //延时 P1 = 0x0F; //演示程序开始,让 P1[7:4] 控制的灯亮 Delay() ; //延时 //将EEPROM 测试起始地址单元的内容读出 eeprom_address = DATA_FLASH_START_ADDRESS; //将测试起始地址送eeprom_address read_eeprom = Byte_Read(eeprom_address); //读EEPROM的值,存到read_eeprom if (DEBUG_DATA == read_eeprom) { //数据是对的,亮 P1.7 控制的灯,然后在 P1 口上将 EEPROM 的数据显示出来 P1 = ~0x80; Delay() ; //延时 82 P1 = ~read_eeprom; } else { //数据是错的,亮 P1.3 控制的灯,然后在 P1 口上将 EEPROM 的数据显示出来 //再将该EEPROM所在的扇区整个擦除,将正确的数据写入后,亮 P1.5 控制的灯 P1 = ~0x08; Delay() ; //延时 P1 = ~read_eeprom; Delay() ; //延时 Sector_Erase(eeprom_address); //擦除整个扇区 Byte_Program(eeprom_address, DEBUG_DATA);//将 DEBUG_DATA 写入 EEPROM P1 = ~0x20; //熄灭 P1.3 控制的灯,亮 P1.5 控制的灯 } while (1); //CPU 在此无限循环执行此句 } //读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节 INT8U Byte_Read(INT16U add) { IAP_DATA = 0x00; IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间 IAP_CMD = 0x01; //IAP/ISP/EEPROM 字节读命令 my_unTemp16.un_temp16 = add; IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址 IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址 //EA = 0; IAP_TRIG = 0x5A; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此 IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动 _nop_(); //EA = 1; IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 return (IAP_DATA); } //字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据 void Byte_Program(INT16U add, INT8U ch) { IAP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置Flash 操作等待时间 83 IAP_CMD = 0x02; //IAP/ISP/EEPROM 字节编程命令 my_unTemp16.un_temp16 = add; IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址 IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址 IAP_DATA = ch; //要编程的数据先送进IAP_DATA 寄存器 //EA = 0; IAP_TRIG = 0x5A; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此 IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动 _nop_(); //EA = 1; IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 } //擦除扇区, 入口:DPTR = 扇区地址 void Sector_Erase(INT16U add) { IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间 IAP_CMD = 0x03; //IAP/ISP/EEPROM 扇区擦除命令 my_unTemp16.un_temp16 = add; IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址 IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址 //EA = 0; IAP_TRIG = 0x5A; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此 IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动 _nop_(); //EA = 1; IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 } void IAP_Disable() { //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 IAP_CONTR = 0; //关闭IAP 功能 IAP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用 IAP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用 IAP_ADDRH = 0; IAP_ADDRL = 0; 84 } void Delay() { INT8U i; INT16U d=5000; while (d--) { i=255; while (i--); } } /******************************************************************** 结束 *********************************************************************/ 025、STC12C5A60S2单片机之PWM: /******************************************************************** 实现功能:STC12C5A60S2单片机之PWM 使用芯片:STC12C5A60S2 晶振:11.0592MHZ 波特率:115200 编译环境:Keil 作者:zhangxinchun 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息~ 说明:单片机的P1.3口输出PWM信号 *********************************************************************/ #include #include #define U8 unsigned char #define U16 unsigned int /******************************************************************** 延时函数 *********************************************************************/ void DelayMs(U8 ms) //在11.0592M晶振下,stc10f系列(单周期指令)的ms级延时 { U16 i; while(ms--) { for(i = 0; i < 850; i++); 85 } } /******************************************************************** 初始化定义函数 *********************************************************************/ sfr CCON = 0xD8; //PCA控制寄存器 sfr CMOD = 0xD9; //PCA模式寄存器 sfr CCAPM0 = 0xDA; //PCA模块0模式寄存器 //模块0对应P1.3/CEX0/PCA0/PWM0(STC12C5A60S2系列) sfr CCAPM1 = 0xDB; //PCA模块1模式寄存器 //模块1对应P1.4/CEX1/PCA1/PWM1(STC12C5A60S2系列) sfr CL = 0xE9; //PCA 定时寄存器 低位 sfr CH = 0xF9; //PCA 定时寄存器 高位 sfr CCAP0L = 0xEA; //PCA模块0的 捕获寄存器 低位 sfr CCAP0H = 0xFA; //PCA模块0的 捕获寄存器 高位 sfr CCAP1L = 0xEB; //PCA模块1的 捕获寄存器 低位 sfr CCAP1H = 0xFB; //PCA模块1的 捕获寄存器 高位 sfr PCA_PWM0 = 0xF2; //PCA PWM 模式辅助寄存器0 sfr PCA_PWM1 = 0xF3; //PCA PWM 模式辅助寄存器1 sbit CF = 0xDF; //PCA计数溢出标志位 sbit CR = 0xDE; //PCA计数器 运行控制位 sbit CCF1 = 0xD9; //PCA模块1中断标志 sbit CCF0 = 0xD8; //PCA模块0中断标志 //* CCAPOH = CCAPOL = 0XC0; //模块0输出 占空因数为25% //* CCAPOH = CCAPOL = 0X80; //模块0输出 占空因数为50% //* CCAPOH = CCAPOL = 0X40; //模块0输出 占空因数为75% /******************************************************************** PWN时钟函数 *********************************************************************/ void PWM_clock(U8 clock) { CMOD |= (clock<<1); CL = 0x00; CH = 0x00; } /******************************************************************** PWM输出函数函数 *********************************************************************/ void PWM_start(U8 module,U8 mode) { /********************设置PWM信号输出值*******************************/ CCAP0L = 0Xc0; 86 CCAP0H = 0Xc0; //模块0初始输出 占空因数为25% CCAP1L = 0Xc0; CCAP1H = 0Xc0; //模块1初始输出 占空因数为25% if(module==0) { switch(mode) { case 0: CCAPM0 = 0X42;break; //模块0设置为8位PWM输出,无中断 case 1: CCAPM0 = 0X53;break; //模块0设置为8位PWM输出,下降沿产生中断 case 2: CCAPM0 = 0X63;break; //模块0设置为8位PWM输出,上升沿产生中断 case 3: CCAPM0 = 0X73;break; //模块0设置为8位PWM输出,跳变沿产生中断 default: break; } } else if(module==1) { switch(mode) { case 0: CCAPM1 = 0X42;break; //模块1设置为8位PWM输出,无中断 case 1: CCAPM1 = 0X53;break; //模块1设置为8位PWM输出,下降沿产生中断 case 2: CCAPM1 = 0X63;break; //模块1设置为8位PWM输出,上升沿产生中断 case 3: CCAPM1 = 0X73;break; //模块1设置为8位PWM输出,跳变沿产生中断 default: break; } } else if(module==2) { switch(mode) { case 0: CCAPM0 = CCAPM1 = 0X42;break; //模块0和1设置为8位PWM输出,无中断 case 1: CCAPM0 = CCAPM1 = 0X53;break; //模块0和1设置为8位PWM输出,下降沿产生中断 case 2: CCAPM0 = CCAPM1 = 0X63;break; //模块0和1设置为8位PWM输出,上升沿产生中断 case 3: CCAPM0 = CCAPM1 = 0X73;break; //模块0和1设置为8位PWM输出,跳变沿产生中断 default: break; } } CR=1; //PCA计数器开始计数 } /******************************************************************** 定时器函数 *********************************************************************/ 87 void PCA_Intrrpt(void) interrupt 7 { if(CCF0) CCF0=0; if(CCF1) CCF1=0; //软件清零 if(CF) CF=0; //软件清零 } /******************************************************************** 主函数 *********************************************************************/ void main() { TMOD|=0x02; /* timer 0 mode 2: 8-Bit reload */ TH0=0xff; TR0=1; PWM_clock(2); // PCA/PWM时钟源为 定时器0的溢出 PWM_start(0,0); // 模块0,设置为PWM输出,无中断,初始占空因素为25% while(1) { DelayMs(250); } } /******************************************************************** 结束 *********************************************************************/ 88
本文档为【STC12C5A60S2精简开发板带232及485产品使用手册】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_321575
暂无简介~
格式:doc
大小:691KB
软件:Word
页数:0
分类:工学
上传时间:2017-10-21
浏览量:16