前言
在编写代码时,要添加头文件STC15F2K60S2.h>#ifndef _STC15F2K60S2_H #define _STC15F2K60S2_H //包含本头文件后,不用另外再包含"REG51.H" //内核特殊功能寄存器 // 复位值 描述 sfr ACC = 0xE0; //0000,0000 累加器Accumulator sfr B = 0xF0; //0000,0000 B寄存器 sfr PSW = 0xD0; //0000,0000 程序状态字 sbit CY = PSW^7; sbit AC = PSW^6; sbit F0 = PSW^5; sbit RS1 = PSW^4; sbit RS0 = PSW^3; sbit OV = PSW^2; sbit P = PSW^0; sfr SP = 0x81; //0000,0111 堆栈指针 sfr DPL = 0x82; //0000,0000 数据指针低字节 sfr DPH = 0x83; //0000,0000 数据指针高字节 //I/O 口特殊功能寄存器 sfr P0 = 0x80; //1111,1111 端口0 sbit P00 = P0^0; sbit P01 = P0^1; sbit P02 = P0^2; sbit P03 = P0^3; sbit P04 = P0^4; sbit P05 = P0^5; sbit P06 = P0^6; sbit P07 = P0^7; sfr P1 = 0x90; //1111,1111 端口1 sbit P10 = P1^0; sbit P11 = P1^1; sbit P12 = P1^2; sbit P13 = P1^3; sbit P14 = P1^4; sbit P15 = P1^5; sbit P16 = P1^6; sbit P17 = P1^7; sfr P2 = 0xA0; //1111,1111 端口2 sbit P20 = P2^0; sbit P21 = P2^1; sbit P22 = P2^2; sbit P23 = P2^3; sbit P24 = P2^4; sbit P25 = P2^5; sbit P26 = P2^6; sbit P27 = P2^7; sfr P3 = 0xB0; //1111,1111 端口3 sbit P30 = P3^0; sbit P31 = P3^1; sbit P32 = P3^2; sbit P33 = P3^3; sbit P34 = P3^4; sbit P35 = P3^5; sbit P36 = P3^6; sbit P37 = P3^7; sfr P4 = 0xC0; //1111,1111 端口4 sbit P40 = P4^0; sbit P41 = P4^1; sbit P42 = P4^2; sbit P43 = P4^3; sbit P44 = P4^4; sbit P45 = P4^5; sbit P46 = P4^6; sbit P47 = P4^7; sfr P5 = 0xC8; //xxxx,1111 端口5 sbit P50 = P5^0; sbit P51 = P5^1; sbit P52 = P5^2; sbit P53 = P5^3; sbit P54 = P5^4; sbit P55 = P5^5; sbit P56 = P5^6; sbit P57 = P5^7; sfr P6 = 0xE8; //0000,0000 端口6 sbit P60 = P6^0; sbit P61 = P6^1; sbit P62 = P6^2; sbit P63 = P6^3; sbit P64 = P6^4; sbit P65 = P6^5; sbit P66 = P6^6; sbit P67 = P6^7; sfr P7 = 0xF8; //0000,0000 端口7 sbit P70 = P7^0; sbit P71 = P7^1; sbit P72 = P7^2; sbit P73 = P7^3; sbit P74 = P7^4; sbit P75 = P7^5; sbit P76 = P7^6; sbit P77 = P7^7; sfr P0M0 = 0x94; //0000,0000 端口0模式寄存器0 sfr P0M1 = 0x93; //0000,0000 端口0模式寄存器1 sfr P1M0 = 0x92; //0000,0000 端口1模式寄存器0 sfr P1M1 = 0x91; //0000,0000 端口1模式寄存器1 sfr P2M0 = 0x96; //0000,0000 端口2模式寄存器0 sfr P2M1 = 0x95; //0000,0000 端口2模式寄存器1 sfr P3M0 = 0xB2; //0000,0000 端口3模式寄存器0 sfr P3M1 = 0xB1; //0000,0000 端口3模式寄存器1 sfr P4M0 = 0xB4; //0000,0000 端口4模式寄存器0 sfr P4M1 = 0xB3; //0000,0000 端口4模式寄存器1 sfr P5M0 = 0xCA; //0000,0000 端口5模式寄存器0 sfr P5M1 = 0xC9; //0000,0000 端口5模式寄存器1 sfr P6M0 = 0xCC; //0000,0000 端口6模式寄存器0 sfr P6M1 = 0xCB; //0000,0000 端口6模式寄存器1 sfr P7M0 = 0xE2; //0000,0000 端口7模式寄存器0 sfr P7M1 = 0xE1; //0000,0000 端口7模式寄存器1 //系统管理特殊功能寄存器 sfr PCON = 0x87; //0001,0000 电源控制寄存器 sfr AUXR = 0x8E; //0000,0000 辅助寄存器 sfr AUXR1 = 0xA2; //0000,0000 辅助寄存器1 sfr P_SW1 = 0xA2; //0000,0000 外设端口切换寄存器1 sfr CLK_DIV = 0x97; //0000,0000 时钟分频控制寄存器 sfr BUS_SPEED = 0xA1; //xx10,x011 总线速度控制寄存器 sfr P1ASF = 0x9D; //0000,0000 端口1模拟功能配置寄存器 sfr P_SW2 = 0xBA; //xxxx,x000 外设端口切换寄存器 //中断特殊功能寄存器 sfr IE = 0xA8; //0000,0000 中断控制寄存器 sbit EA = IE^7; sbit ELVD = IE^6; sbit EADC = IE^5; sbit ES = IE^4; sbit ET1 = IE^3; sbit EX1 = IE^2; sbit ET0 = IE^1; sbit EX0 = IE^0; sfr IP = 0xB8; //0000,0000 中断优先级寄存器 sbit PPCA = IP^7; sbit PLVD = IP^6; sbit PADC = IP^5; sbit PS = IP^4; sbit PT1 = IP^3; sbit PX1 = IP^2; sbit PT0 = IP^1; sbit PX0 = IP^0; sfr IE2 = 0xAF; //0000,0000 中断控制寄存器2 sfr IP2 = 0xB5; //xxxx,xx00 中断优先级寄存器2 sfr INT_CLKO = 0x8F; //0000,0000 外部中断与时钟输出控制寄存器 //定时器特殊功能寄存器 sfr TCON = 0x88; //0000,0000 T0/T1控制寄存器 sbit TF1 = TCON^7; sbit TR1 = TCON^6; sbit TF0 = TCON^5; sbit TR0 = TCON^4; sbit IE1 = TCON^3; sbit IT1 = TCON^2; sbit IE0 = TCON^1; sbit IT0 = TCON^0; sfr TMOD = 0x89; //0000,0000 T0/T1模式寄存器 sfr TL0 = 0x8A; //0000,0000 T0低字节 sfr TL1 = 0x8B; //0000,0000 T1低字节 sfr TH0 = 0x8C; //0000,0000 T0高字节 sfr TH1 = 0x8D; //0000,0000 T1高字节 sfr T4T3M = 0xD1; //0000,0000 T3/T4模式寄存器 sfr T3T4M = 0xD1; //0000,0000 T3/T4模式寄存器 sfr T4H = 0xD2; //0000,0000 T4高字节 sfr T4L = 0xD3; //0000,0000 T4低字节 sfr T3H = 0xD4; //0000,0000 T3高字节 sfr T3L = 0xD5; //0000,0000 T3低字节 sfr T2H = 0xD6; //0000,0000 T2高字节 sfr T2L = 0xD7; //0000,0000 T2低字节 sfr WKTCL = 0xAA; //0000,0000 掉电唤醒定时器低字节 sfr WKTCH = 0xAB; //0000,0000 掉电唤醒定时器高字节 sfr WDT_CONTR = 0xC1; //0000,0000 看门狗控制寄存器 //串行口特殊功能寄存器 sfr SCON = 0x98; //0000,0000 串口1控制寄存器 sbit SM0 = SCON^7; sbit SM1 = SCON^6; sbit SM2 = SCON^5; sbit REN = SCON^4; sbit TB8 = SCON^3; sbit RB8 = SCON^2; sbit TI = SCON^1; sbit RI = SCON^0; sfr SBUF = 0x99; //xxxx,xxxx 串口1数据寄存器 sfr S2CON = 0x9A; //0000,0000 串口2控制寄存器 sfr S2BUF = 0x9B; //xxxx,xxxx 串口2数据寄存器 sfr S3CON = 0xAC; //0000,0000 串口3控制寄存器 sfr S3BUF = 0xAD; //xxxx,xxxx 串口3数据寄存器 sfr S4CON = 0x84; //0000,0000 串口4控制寄存器 sfr S4BUF = 0x85; //xxxx,xxxx 串口4数据寄存器 sfr SADDR = 0xA9; //0000,0000 从机地址寄存器 sfr SADEN = 0xB9; //0000,0000 从机地址屏蔽寄存器 //ADC 特殊功能寄存器 sfr ADC_CONTR = 0xBC; //0000,0000 A/D转换控制寄存器 sfr ADC_RES = 0xBD; //0000,0000 A/D转换结果高8位 sfr ADC_RESL = 0xBE; //0000,0000 A/D转换结果低2位 //SPI 特殊功能寄存器 sfr SPSTAT = 0xCD; //00xx,xxxx SPI状态寄存器 sfr SPCTL = 0xCE; //0000,0100 SPI控制寄存器 sfr SPDAT = 0xCF; //0000,0000 SPI数据寄存器 //IAP/ISP 特殊功能寄存器 sfr IAP_DATA = 0xC2; //0000,0000 EEPROM数据寄存器 sfr IAP_ADDRH = 0xC3; //0000,0000 EEPROM地址高字节 sfr IAP_ADDRL = 0xC4; //0000,0000 EEPROM地址第字节 sfr IAP_CMD = 0xC5; //xxxx,xx00 EEPROM命令寄存器 sfr IAP_TRIG = 0xC6; //0000,0000 EEPRPM命令触发寄存器 sfr IAP_CONTR = 0xC7; //0000,x000 EEPROM控制寄存器 //PCA/PWM 特殊功能寄存器 sfr CCON = 0xD8; //00xx,xx00 PCA控制寄存器 sbit CF = CCON^7; sbit CR = CCON^6; sbit CCF2 = CCON^2; sbit CCF1 = CCON^1; sbit CCF0 = CCON^0; sfr CMOD = 0xD9; //0xxx,x000 PCA 工作模式寄存器 sfr CL = 0xE9; //0000,0000 PCA计数器低字节 sfr CH = 0xF9; //0000,0000 PCA计数器高字节 sfr CCAPM0 = 0xDA; //0000,0000 PCA模块0的PWM寄存器 sfr CCAPM1 = 0xDB; //0000,0000 PCA模块1的PWM寄存器 sfr CCAPM2 = 0xDC; //0000,0000 PCA模块2的PWM 寄存器 sfr CCAP0L = 0xEA; //0000,0000 PCA模块0的捕捉/比较寄存器低字节 sfr CCAP1L = 0xEB; //0000,0000 PCA模块1的捕捉/比较寄存器低字节 sfr CCAP2L = 0xEC; //0000,0000 PCA模块2的捕捉/比较寄存器低字节 sfr PCA_PWM0 = 0xF2; //xxxx,xx00 PCA模块0的PWM寄存器 sfr PCA_PWM1 = 0xF3; //xxxx,xx00 PCA模块1的PWM寄存器 sfr PCA_PWM2 = 0xF4; //xxxx,xx00 PCA模块1的PWM寄存器 sfr CCAP0H = 0xFA; //0000,0000 PCA模块0的捕捉/比较寄存器高字节 sfr CCAP1H = 0xFB; //0000,0000 PCA模块1的捕捉/比较寄存器高字节 sfr CCAP2H = 0xFC; //0000,0000 PCA模块2的捕捉/比较寄存器高字节
流水灯
#include “STC15F2K60S2.H” #define uint unsigned int #define uchar unsigned char sbit sbtSel0 = P2 ^ 0; // sbit sbtSel1 = P2 ^ 1; // sbit sbtSel2 = P2 ^ 2; //位选的三个引脚控制位 uchar ucDig1Tmp; uchar ucDig2Tmp; uchar ucDig3Tmp; uchar ucDig4Tmp; uchar ucDig5Tmp; uchar ucDig6Tmp; uchar ucDig7Tmp; uchar ucDig8Tmp;//show_wi(i=1,2,3,4,…,8)分别是对应左到右的各个数码管上的显示的数字 uchar ucSeg7State; uchar ucCount; uchar arrSegSelect[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x40, 0x00}; //段选 uchar arrDigSelect[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; //位选 void Init() { P2M0 = 0xff; P2M1 = 0x00; P0M0 = 0xff; P0M1 = 0x00; //推挽输出 ucSeg7State = 0; ucCount = 0; ucDig1Tmp = 0;//初始化数码管从左到右显示0~7 ucDig2Tmp = 1; ucDig3Tmp = 2; ucDig4Tmp = 3; ucDig5Tmp = 4; ucDig6Tmp = 5; ucDig7Tmp = 6; ucDig8Tmp = 7; TMOD = 0x01; //定时器0,方式1 ET0 = 1; //开启定时器中断 TH0 = ( 65535 - 1000 ) / 256; //定时器0的高八位设置 TL0 = ( 65535 - 1000 ) % 256; //定时器0的低八位设置,这里总体就是设置定时器的初值是1ms TR0 = 1; //启动定时器 EA = 1; //打开总中断 } void T0_Process() interrupt 1 //把数码管显示提到中断来了 { TH0 = ( 65535 - 1000 ) / 256; //重载定时器0的初始值,为下一次定时器溢出做准备 TL0 = ( 65535 - 1000 ) % 256; ucSeg7State++; //分频作用和扫描过程中显示第ucSeg7State个数码管的作用 if( ucSeg7State == 8 ) //进行分频,每中断八次才让ucCount的值加一次 { ucSeg7State = 0; ucCount++; } if( ucCount == 100 ) //考虑到扫描频率很高这里再次分频,ucCount加到100次才执行 { ucCount = 0; ucDig1Tmp++; //从左到右每个数码管值加1 ucDig2Tmp++; ucDig3Tmp++; ucDig4Tmp++; ucDig5Tmp++; ucDig6Tmp++; ucDig7Tmp++; ucDig8Tmp++; } //当定时器0初始值不断加一最终溢出时激发的处理方法 P0 = 0; P2 = arrDigSelect[ucSeg7State]; switch( ucSeg7State ) { case 0: P0 = arrSegSelect[ucDig1Tmp % 10]; break; case 1: P0 = arrSegSelect[ucDig2Tmp % 10]; break; case 2: P0 = arrSegSelect[ucDig3Tmp % 10]; break; case 3: P0 = arrSegSelect[ucDig4Tmp % 10]; break; case 4: P0 = arrSegSelect[ucDig5Tmp % 10]; break; case 5: P0 = arrSegSelect[ucDig6Tmp % 10]; break; case 6: P0 = arrSegSelect[ucDig7Tmp % 10]; break; default: P0 = arrSegSelect[ucDig8Tmp % 10]; break; } } void main() { Init(); while( 1 ) { } }
八位数码管动态扫描
#include “STC15F2K60S2.H” #define uint unsigned int #define uchar unsigned char sbit sbtSel0 = P2 ^ 0; // sbit sbtSel1 = P2 ^ 1; // sbit sbtSel2 = P2 ^ 2; //位选的三个引脚控制位 uchar ucDig1Tmp; uchar ucDig2Tmp; uchar ucDig3Tmp; uchar ucDig4Tmp; uchar ucDig5Tmp; uchar ucDig6Tmp; uchar ucDig7Tmp; uchar ucDig8Tmp;//show_wi(i=1,2,3,4,…,8)分别是对应左到右的各个数码管上的显示的数字 uchar ucSeg7State; uchar ucCount; uchar arrSegSelect[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x40, 0x00}; //段选 uchar arrDigSelect[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; //位选 void Init() { P2M0 = 0xff; P2M1 = 0x00; P0M0 = 0xff; P0M1 = 0x00; //推挽输出 ucSeg7State = 0; ucCount = 0; ucDig1Tmp = 0;//初始化数码管从左到右显示0~7 ucDig2Tmp = 1; ucDig3Tmp = 2; ucDig4Tmp = 3; ucDig5Tmp = 4; ucDig6Tmp = 5; ucDig7Tmp = 6; ucDig8Tmp = 7; TMOD = 0x01; //定时器0,方式1 ET0 = 1; //开启定时器中断 TH0 = ( 65535 - 1000 ) / 256; //定时器0的高八位设置 TL0 = ( 65535 - 1000 ) % 256; //定时器0的低八位设置,这里总体就是设置定时器的初值是1ms TR0 = 1; //启动定时器 EA = 1; //打开总中断 } void T0_Process() interrupt 1 //把数码管显示提到中断来了 { TH0 = ( 65535 - 1000 ) / 256; //重载定时器0的初始值,为下一次定时器溢出做准备 TL0 = ( 65535 - 1000 ) % 256; ucSeg7State++; //分频作用和扫描过程中显示第ucSeg7State个数码管的作用 if( ucSeg7State == 8 ) //进行分频,每中断八次才让ucCount的值加一次 { ucSeg7State = 0; ucCount++; } if( ucCount == 100 ) //考虑到扫描频率很高这里再次分频,ucCount加到100次才执行 { ucCount = 0; ucDig1Tmp++; //从左到右每个数码管值加1 ucDig2Tmp++; ucDig3Tmp++; ucDig4Tmp++; ucDig5Tmp++; ucDig6Tmp++; ucDig7Tmp++; ucDig8Tmp++; } //当定时器0初始值不断加一最终溢出时激发的处理方法 P0 = 0; P2 = arrDigSelect[ucSeg7State]; switch( ucSeg7State ) { case 0: P0 = arrSegSelect[ucDig1Tmp % 10]; break; case 1: P0 = arrSegSelect[ucDig2Tmp % 10]; break; case 2: P0 = arrSegSelect[ucDig3Tmp % 10]; break; case 3: P0 = arrSegSelect[ucDig4Tmp % 10]; break; case 4: P0 = arrSegSelect[ucDig5Tmp % 10]; break; case 5: P0 = arrSegSelect[ucDig6Tmp % 10]; break; case 6: P0 = arrSegSelect[ucDig7Tmp % 10]; break; default: P0 = arrSegSelect[ucDig8Tmp % 10]; break; } } void main() {Init(); while( 1 ) { } }
八位数码管+流水灯
#include <STC15F2K60S2.h> #define uint unsigned int #define uchar unsigned char uchar arrSeg7Select[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f}; //段选0-8 uchar arrDigitSelect[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; //位选0-7 sbit sbtLedSel = P2 ^ 3; //使能E3,控制数码管与LED切换的引脚 uchar uiLed = 0x01; //控制亮起的LED uint uiLedCnt = 0; //LED计数 uchar i = 0; //数码管循环扫描 void Init() { P0M1 = 0x00; P0M0 = 0xff; P2M1 = 0x00; P2M0 = 0x08; sbtLedSel = 0; //初始化先选择数码管亮 } void delay_ms( uint n ) { while( n ) { uchar i, j; i = 11; j = 190; do { while ( --j ); } while ( --i ); n–; } } void main() { Init(); while( 1 ) { sbtLedSel = 0;//置0数码管扫描 for( i = 0; i < 8; i++ ) { P0 = 0; P2 = arrDigitSelect[i]; P0 = arrSeg7Select[i + 1]; delay_ms( 1 ); } uiLedCnt++;//LED计数 sbtLedSel = 1;//切换成LED P0 = uiLed; //LED赋值 delay_ms( 1 ); if( uiLedCnt == 50 )//LED计数达到50,向左移位 { if( uiLed == 0x80 ) //最左边灯亮起后切换至最右边的灯 uiLed = 0x01; else uiLed = uiLed << 1; //流水灯 uiLedCnt = 0;//计数清零 } } }
八位数码管滚动显示
#include “STC15F2K60S2.H” #define uint unsigned int #define uchar unsigned char /---------引脚别名定义---------/ sbit sbtSel0 = P2 ^ 0; // sbit sbtSel1 = P2 ^ 1; // sbit sbtSel2 = P2 ^ 2; //位选的三个引脚控制位 /---------变量定义---------/ uchar ucDig1Tmp; uchar ucDig2Tmp; uchar ucDig3Tmp; uchar ucDig4Tmp; uchar ucDig5Tmp; uchar ucDig6Tmp; uchar ucDig7Tmp; uchar ucDig8Tmp;//show_wi(i=1,2,3,4,……,8)分别是对应左到右的各个数码管上的显示的数字 uchar ucSeg7State; uchar ucCount; uchar arrSegSelect[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x40, 0x00}; //段选,显示0-f uchar arrDigSelect[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; //位选,选择是0-7中的一个数码管 /---------初始化函数---------/ void Init() { P2M0 = 0xff; P2M1 = 0x00; P0M0 = 0xff; P0M1 = 0x00; //P0,P2都设置为推挽输出 ucSeg7State = 0; ucCount = 0; ucDig1Tmp = 0; //最开始数码管从左到右显示0-7 ucDig2Tmp = 1; ucDig3Tmp = 2; ucDig4Tmp = 3; ucDig5Tmp = 4; ucDig6Tmp = 5; ucDig7Tmp = 6; ucDig8Tmp = 7; TMOD = 0x01; //定时器0,方式1 ET0 = 1; //开启定时器中断 TH0 = ( 65535 - 1000 ) / 256; //定时器0的高八位设置 TL0 = ( 65535 - 1000 ) % 256; //定时器0的低八位设置,这里总体就是设置定时器0的初始值是1ms TR0 = 1; //启动定时器 EA = 1; //打开总的中断 } /---------定时器T0中断服务函数---------/ void T0_Process() interrupt 1 //把数码管的显示提到中断里面来了 { TH0 = ( 65535 - 1000 ) / 256; //重新装载定时器0的初始值,为了下一次定时器溢出准备 TL0 = ( 65535 - 1000 ) % 256; ucSeg7State++; //这变量两个作用:具有下面分频作用,和扫描过程中显示第ucSeg7State个数码管的作用 if( ucSeg7State == 8 ) //进行分频,每中断八次才让ucCount的值加一次 { ucSeg7State = 0; ucCount++; } if( ucCount == 100 ) //考虑到扫描频率很高这里再次分频,ucCount加到100才执行 { ucCount = 0; ucDig1Tmp++; //让从左到右各个数码管上的数字都加一 ucDig2Tmp++; ucDig3Tmp++; ucDig4Tmp++; ucDig5Tmp++; ucDig6Tmp++; ucDig7Tmp++; ucDig8Tmp++; } P0 = 0; //让数码管显示更加好,不受上一次P0赋的值的影响 P2 = arrDigSelect[ucSeg7State]; //位选,选第ucSeg7State个数码管 switch( ucSeg7State ) //每次中断显示一个数码管来显示 { case 0: P0 = arrSegSelect[ucDig1Tmp % 10]; break;//从左到右,第一个数码管显示 case 1: P0 = arrSegSelect[ucDig2Tmp % 10]; break;//从左到右,第二个数码管显示 case 2: P0 = arrSegSelect[ucDig3Tmp % 10]; break;//从左到右,第三个数码管显示 case 3: P0 = arrSegSelect[ucDig4Tmp % 10]; break;//从左到右,第四个数码管显示 case 4: P0 = arrSegSelect[ucDig5Tmp % 10]; break;//从左到右,第五个数码管显示 case 5: P0 = arrSegSelect[ucDig6Tmp % 10]; break;//从左到右,第六个数码管显示 case 6: P0 = arrSegSelect[ucDig7Tmp % 10]; break;//从左到右,第七个数码管显示 default: P0 = arrSegSelect[ucDig8Tmp % 10]; break;//从左到右,第八个数码管显示 } } /---------主函数---------/ void main() { Init(); //初始化 while( 1 ) { } }
扫描频率可改变的的电子钟
#include “STC15F2K60S2.h” #include “intrins.h” #define uint unsigned int #define uchar unsigned char #define i1 interrupt 1 sbit ledSel = P2 ^3; // led or digital tube sbit key1 = P3 ^2; //控制数码管扫描频率 uchar baseSevenSegment[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //七段码 unsigned char const line = 0x40; //横杠的七段码 char timeAddOneFlag = 0; //标记为1,此时需要秒+1 char key1ActionFlag = 0; //值为1时表示按键操作需要执行 unsigned int ledOnFlag = 0; //led灯亮 char tubeOnFlag = 0; //数码管亮 int ledValue = 1; //led显示的数值 int myDisplay[8] = {0}; //数码管显示的内容 unsigned int timeCount = 1; //时间计时器 unsigned int currHour = 0; unsigned int currMinute = 0; unsigned int currSecond = 0; unsigned int interruptCount = 0; unsigned int keyDownTime = 0; unsigned int scanTime = 1; //扫描时间 unsigned int currBit = 0; //当前显示的位 void Delay5us() { unsigned char i; nop();//空操作 i = 11; while (–i); } / / 设置ledSel,转为数码管显示 void switchToTube() { ledSel = 0; } // 设置ledSel,转为led设置 void switchToLed() { P0 = 0; ledSel = 1; }/** 改变其中一位的内容 * bitNum 位数(第几位)(例如最左那位,则调用1) * value 改变后的数字,需确保大于0小于10 / void change1Bit(int bitNum, int value) { myDisplay[bitNum - 1] = baseSevenSegment[value]; } / 改变其中一位的内容(设置七段码) bitNum 位数(第几位)(例如最左那位,则调用1) sevenSegCode 目标七段码 / void change1Bit_seven(int bitNum, int sevenSegCode) { myDisplay[bitNum - 1] = sevenSegCode; } / * 数码管设置为显示指定的数值 num 数字 / void changeAll(long num) { int i; for (i = 7; i >= 0; --i) { int foo = num % 10; myDisplay[i] = baseSevenSegment[foo]; num /= 10; } } / * led亮 / void displayLed() { if (ledOnFlag) { switchToLed(); P0 = ledValue; } } / * 显示数码管 / void showTube() { if (tubeOnFlag) { switchToTube(); P0 = 0; P2 = currBit; P0 = myDisplay[currBit]; Delay5us(); } } / * 初始化定时器 / void timer0Initialize() //0.1毫秒,12MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0xAE; //设置定时器初值 TH0 = 0xFB; //设置定时器初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 EA = 1; //打开总的中断 ET0 = 1; //打开定时器0中断 } / * / void initialize() { P0M0 = 0xFF; P0M1 = 0x00; P2M0 = 0x0f; //设置P2.0-3为推挽工作状态 P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; ledSel = 0; timer0Initialize(); changeAll(0); / * 第三位和第六位设置为 ‘-’ / change1Bit_seven(3, line); change1Bit_seven(6, line); } / * 时间自增1秒 * / * void addTime() { ++currSecond; if (currSecond == 60) { ++currMinute; currSecond = 0; if (currMinute == 60) { ++currHour; currMinute = 0; if (currHour == 24) currHour = 0; change1Bit(2, currHour % 10); change1Bit(1, currHour / 10); } change1Bit(5, currMinute % 10); change1Bit(4, currMinute / 10); } change1Bit(8, currSecond % 10); change1Bit(7, currSecond / 10); } / * 按下key1要做的事 * / void key1Action() { if (key1ActionFlag) { if (ledValue == 0x80) ledValue = 0x01; else ledValue <<= 1; if (ledValue == 1) scanTime = 1; else if (ledValue == 2) scanTime = 50; else if (ledValue == 4) scanTime = 100; else if (ledValue == 8) scanTime = 200; else if (ledValue == 16) scanTime = 500; else if (ledValue == 32) scanTime = 1000; else if (ledValue == 64) scanTime = 2000; else if (ledValue == 128) scanTime = 5000; key1ActionFlag = 0; } } / * 收到中断的信号(是时候自增时间了) * * / * * void timeSignalHandler( * ) { * if (timeAddOneFlag) { addTime(); timeAddOneFlag = 0; } } / * 单片机运行 * / * void run() { while (1) { timeSignalHandler(); displayLed(); showTube(); key1Action(); } } / * 每0.1毫秒进入一次定时器中断 * */ * void interruptFunction() i1 { static const int KEY_TIME_THRESHOLD = 500; interruptCount = (interruptCount + 1) % 20000; //led显示的频率应该低些才有好的显示效果 if (interruptCount % 12 > 10) { ledOnFlag = 1; tubeOnFlag = 0; } else { tubeOnFlag = 1; ledOnFlag = 0; } // 数码管的扫描 if (interruptCount % scanTime == 0) currBit = (currBit + 1) % 8; //读秒 if (interruptCount % 10000 == 0) timeAddOneFlag = 1; // 按键功能设置 if (key1 == 0) { if (keyDownTime < KEY_TIME_THRESHOLD) ++keyDownTime; } else { if (keyDownTime >= KEY_TIME_THRESHOLD) key1ActionFlag = 1; keyDownTime = 0; } } int main() { initialize(); run(); return 0; }
按键消抖计数
#include “STC15F2K60S2.h” #include<intrins.h> #define uchar unsigned char #define uint unsigned int //数码管段选信号 从0到9 uchar code duanxuan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管位选信号 显示在第4到7位 uchar code weixuan[4]={0x04,0x05,0x06,0x07}; sbit led_sel=P2^3;//74HC138 的一个使能位 sbit key1=P3^2;//按键k1 sbit key2=P3^3;//按键k2 uint number;//显示在数码管上的值 uint flag;//位选的位置 int count1,count2,count3,count4;//用于消抖计数 bit status_P,status_P2;//记录按键前一状态 void Init() { /************************** 将P0设置成推挽输出 P2的低四位设置成推挽输出 P3不需要设置成推挽输出 **************************/ P0M0=0XFF; P0M1=0X00; P2M0=0X0F; P2M1=0X00; led_sel=0; P0=0; number=5000;//初始化number=5000 count1=0; count2=0; count3=0; count4=0; status_P=0; status_P2=0; flag=0; TMOD=0X00; EA=1; ET0=1; TH0=(65536-200)/256; TL0=(65536-200)%256; TR0=1; } void InterruptTimer0()interrupt 1 { switch(flag) { case 0:P0=0;P2=weixuan[flag];P0=duanxuan[number/1000];break; case 1:P0=0;P2=weixuan[flag];P0=duanxuan[(number/100)%10];break; case 2:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)/10];break; case 3:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)%10];break; } flag++; count1++; if(key10) { count2++; } count3++; if(key20) { count4++; } } void main() { Init(); while(1) { if(flag4)//修正位选位置 可放在中断程序外 放在中断外 效果更好 flag=0; if(count130)//消抖大概6ms 总共统计次数 30次 { if(count2>=20)// 如果低电平的有效次数为 2/3 以上 { if(status_P1) { status_P=0; number++; } } else status_P=1; count1=0; count2=0; } if(count330)//消抖大概6ms 总共统计次数 60次 { if(count4>=20)// 如果低电平的有效次数为 2/3 以上 { if(status_P2==1) { status_P2=0; number–; } } else status_P2=1; count3=0; count4=0; } } }
三按键测试
#include <STC15F2K60S2.H> sbit sbtKey1 = P3 ^ 2; sbit sbtKey2 = P3 ^ 3; sbit sbtKey3 = P1 ^ 7; sbit sbtLedSel = P2 ^ 3; void Init() { P0M0 = 0XFF; P0M1 = 0X00; P2M0 = 0X08; P2M1 = 0X00; sbtLedSel = 1; P0 = 0; void main() { Init(); while( 1 ) { if( sbtKey1 == 0 ) //检测按键1是否按下 P0 |= 0x01; //按下则L0发光 else P0 &= ~0x01; //否则L0熄灭 if( sbtKey2 == 0 ) //检测按键2是否按下 P0 |= 0x02; //按下则L1发光 else P0 &= ~0x02; //否则L1熄灭 if( sbtKey3 == 0 ) //检测按键3是否被按下 P0 |= 0x04; //按下则L2发光 else P0 &= ~0x04; //否则L2熄灭 } }
霍尔磁场检测
#include <STC15F2K60S2.H> #define uint unsigned int #define uchar unsigned char sbit sbtLedSel = P2 ^ 3; //发光二极管和数码管管选择口 sbit sbtHall = P1 ^ 2; 霍尔引脚别名定义 uchar ucLed;//接收霍尔元件的值 void Init() { P2M1 = 0x00; P2M0 = 0xff; P0M1 = 0x00; P0M0 = 0xff; P1M1 = 0x00; P1M0 = 0xff; sbtLedSel = 1; } void main() { Init(); while( 1 ) { ucLed = sbtHall;//ucled再传到P0口显示 P0 = ucLed; } }
数码管显示demo
#include “STC15F2K60S2.H” #define Dis_B 0 #define Dis_E 8 unsigned char Dis_flag=0; //记录显示位 unsigned char count_1mS=0; unsigned char count_10mS=0; bit flag_1mS=0; //=1 1mS时刻标记 bit flag_10mS=0; bit flag_100mS=0; char disp[9]; //8 —— 对应流水灯; >8 虚拟 // //void GPIO_Init(); //void Timer0_Init(); void Func_1mS(); //Function for 1ms void Func_10mS(); void Func_100mS(); //void Display(char, char); //void LED_print(char,char,char,char,char,char,char,char); //void L_print(char); void Display(char Dis_min, char Dis_max) { char selData[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00}; // 数码管显示译码表 /* 序号: 0 1 2 3 4 5 6 7 8 9 10 11 / / 显示: 0 1 2 3 4 5 6 7 8 9 - (无) */ // while(Dis_flag<8 && disp[Dis_flag] == 11) ++Dis_flag; //如果L7——L0无内容显示,则跳过 P0 =0; //关闭段选,消影 P2 = (P2 & 0xf0) | (Dis_flag & 0x0f); //位选控制:保留P2高4位不变,低4位取Dis_flag if (Dis_flag<9) {if(Dis_flag == 8) P0 = disp[Dis_flag]; //段选:LED灯时 else P0 = selData[disp[Dis_flag]]; //段选:数码管时 } if( ++Dis_flag > Dis_max ) Dis_flag = Dis_min; } void LED_print(char d0,char d1,char d2,char d3,char d4,char d5,char d6,char d7) { disp[0]=d0; disp[1]=d1; disp[2]=d2; disp[3]=d3; disp[4]=d4; disp[5]=d5; disp[6]=d6; disp[7]=d7; } //void L_print(char d) //{ // disp[8]=d; //} void GPIO_Init(void) { P0M1=0x00; //设置P0为推挽模式,点亮数码管 P0M0=0xff; P2M1=0x00; P2M0=0x08; //将P2^3设置为推挽模式,其余为准双向口模式 } void Timer0_Init(void) //主频选择@12.000MHz { AUXR &= 0x7f; //12T模式 TMOD &= 0xf0; //使用定时器0,16位自动重装载模式,TH0、TL0全用 TH0=(65535-999)/256; //高8位赋初值,定时1000周期 TL0=(65535-999)%256; //低8位赋初值 TR0=1; //启动定时器0 ET0=1; //开启定时器0中断 } void Timer0_isr() interrupt 1 { flag_1mS = 1; count_1mS++; if( count_1mS == 10 ) { count_1mS = 0; flag_10mS = 1; count_10mS++; } if( count_10mS == 10 ) { count_10mS = 0; flag_100mS = 1; } } void Func_1mS() { Display(Dis_B,Dis_E); } void Func_10ms() { } void Func_100ms() { } void main() { GPIO_Init(); Timer0_Init(); EA = 1; //总中断允许位 LED_print(3,3,4,1,5,6,7,10); disp[8]=9; Dis_flag=0; while(1) { if( flag_1mS ) { flag_1mS = 0; Func_1mS(); } if( flag_10mS ) { flag_10mS = 0; Func_10mS(); } if( flag_100mS ) { flag_100mS = 0; Func_100mS();} } }
步进电机
#include <STC15F2K60S2.h> #define uint unsigned int uint i=1; //控制步进电机不同IO口脉冲位置 /********************** 引脚别名定义 */ sbit s1 =P4^1; //步进电机IO口 sbit s2 =P4^2; sbit s3 =P4^3; sbit s4 =P4^4; //sbit LED=P2^3; //LED与数码管切换 / 函数名称:void time0() 功能描述:定时器中断,控制脉冲转换 入口参数:无 出口参数:无 */ void time0() interrupt 1 { switch(i++) //控制步进电机不同IO口脉冲电平 { case 1: s1=1;s2=0;s3=0;s4=0;break; case 2: s1=0;s2=1;s3=0;s4=0;break; case 3: s1=0;s2=0;s3=1;s4=0;break; case 4: s1=0;s2=0;s3=0;s4=1;break; } if(i==5) i=1; } / 函数名称:init_sys() 功能描述:系统初始化,功能是配置IO口 入口参数:无 出口参数:无 */ void init_sys() { //P4口推挽输出 P4M0=0Xff; P4M1=0X00; // LED =0; //设置为数码管显示 P4 =0X00; //P4口设置低电平,避免复位时对步进电机5V电平接口的影响 TMOD = 0x00; //设置定时器0 16位自动重装模式 TH0 = (65536-10000)/256; //设置定时5ms TL0 = (65536-10000)%256; TCON = 0X10; //定时器0开始计时 IE = 0x82; //开启CPU中断,开启定时器0中断 } / 函数名称:main() 功能描述:调用函数初始化 入口参数:无 出口参数:无 ***********************/ void main() { init_sys(); while(1) { } }
可控步进电机
#include <STC15F2K60S2.h> #define uint unsigned int /---------宏定义---------/ #define cstKeyMaxNum 100 //100次读取按键值 uint code arrSegSelect[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x40, 0x00 }; //数码管显示0~4的16进制代码 /---------引脚别名定义---------/ sbit sbtKey1 = P3 ^ 2; //按键1 sbit sbtKey2 = P3 ^ 3; //按键2 sbit sbtKey3 = P1 ^ 7; //按键3 sbit sbtS1 = P4 ^ 1; sbit sbtS2 = P4 ^ 2; sbit sbtS3 = P4 ^ 3; sbit sbtS4 = P4 ^ 4; /---------变量定义---------/ uint uiKey1Cnt; uint uiKey2Cnt; uint uiKey3Cnt; uint uiKeyAllCnt; uint uiSpeed = 1; //控制控制步进电机的速度 uint i = 1; //控制脉冲对应的IO口位置 bit btKey1Current = 1; //Key1当前的状态 bit btKey1Past = 1; //Key1前一个状态 bit btKey2Current = 1; //Key2当前的状态 bit btKey2Past = 1; //Key2前一个状态 bit btKey3Current = 1; //Key3当前的状态 bit btKey3Past = 1; //Key3前一个状态 bit btRotationFlag = 0; //标记步进电机转向 /---------初始化函数--------/ void InitSys() //功能是配置IO口,启动定时器0和1 { P0M0 = 0xff; //P0口设置推挽输出 P0M1 = 0x00; P4M0 = 0x3f; //P4口设置推挽输出 P4M1 = 0xe1; P4 = 0xe1; //设置P4口为低电平,避免复位时步进电机5V电平接口的影响 P2M0 = 0x07; //P2.3口设置推挽输出 P2M1 = 0x00; P2 = 0X07; //设置数码管显示 uiKey1Cnt = 0x80 + cstKeyMaxNum / 3 * 2; uiKey2Cnt = 0x80 + cstKeyMaxNum / 3 * 2; uiKey3Cnt = 0x80 + cstKeyMaxNum / 3 * 2; uiKeyAllCnt = cstKeyMaxNum; AUXR = 0X00; //定时器0和定时器1 时钟1T模式 TMOD = 0X00; //设置定时器0和定时器1 16位自动重装模式 TL0 = ( 65536 - 250 ) % 256; //设置定时0定时为 250μs TH0 = ( 65536 - 250 ) / 256; TH1 = ( 65536 - 5000 * uiSpeed ) / 256; //设置定时1定时为 5msuiSpeed TL1 = ( 65536 - 5000 * uiSpeed ) % 256; TCON = 0X50; //定时器0和1开始计时 IE = 0x8A; //定时器0和1开启中断,CPU开启中断 } /---------T1定时器中断服务处理函数--------/ void T1_Process() interrupt 3 //控制脉冲频率 { TH1 = ( 65536 - 5000 * uiSpeed ) / 256; //通过在定时器1的时间来改变脉冲频率 TL1 = ( 65536 - 5000 * uiSpeed ) % 256; if( btRotationFlag == 0 ) //控制步进电机正转 { switch( i++ ) //循环改变不同IO脚的脉冲电平 { case 1: sbtS1 = 1; sbtS2 = 0; sbtS3 = 0; sbtS4 = 0; break; case 2: sbtS1 = 0; sbtS2 = 1; sbtS3 = 0; sbtS4 = 0; break; case 3: sbtS1 = 0; sbtS2 = 0; sbtS3 = 1; sbtS4 = 0; break; case 4: sbtS1 = 0; sbtS2 = 0; sbtS3 = 0; sbtS4 = 1; break; } if( i == 5 ) i = 1; } else //控制步进电机反转 { switch( i++ ) { case 1: sbtS1 = 0; sbtS2 = 0; sbtS3 = 0; sbtS4 = 1; break; case 2: sbtS1 = 0; sbtS2 = 0; sbtS3 = 1; sbtS4 = 0; break; case 3: sbtS1 = 0; sbtS2 = 1; sbtS3 = 0; sbtS4 = 0; break; case 4: sbtS1 = 1; sbtS2 = 0; sbtS3 = 0; sbtS4 = 0; break; } if( i == 5 ) i = 1; } } /---------T0定时器中断服务处理函数--------/ void T0_Process() interrupt 1 //按键消抖+中断处理(控制步进电机转向和速度) { if( sbtKey1 == 0 ) uiKey1Cnt–; if( sbtKey2 == 0 ) uiKey2Cnt–; if( sbtKey3 == 0 ) uiKey3Cnt–; //按键是按下状态 uiKeyAllCnt–; //总的次数减1 if( uiKeyAllCnt == 0 ) //100次完了 { if( uiKey1Cnt < 0x80 ) { btKey1Current = 0; if( btKey1Past == 1 ) //下降沿(按键则步进电机的转速改变,//uiSpeed值越大,转速越慢) { btKey1Past = 0; uiSpeed++; if( uiSpeed == 12 ) uiSpeed = 1; } } if( uiKey1Cnt >= 0x80 ) { btKey1Current = 1; if( btKey1Past == 0 ) btKey1Past = 1; //上升沿(假设不做动作那就继续) } if( uiKey2Cnt < 0x80 ) { btKey2Current = 0; if( btKey2Past == 1 ) //下降沿(按键改变步进电机转向) { btKey2Past = 0; btRotationFlag = ~btRotationFlag; } } if( uiKey2Cnt >= 0x80 ) { btKey2Current = 1; if( btKey2Past == 0 ) btKey2Past = 1; //上升沿(假设不做动作那就继续) } if( uiKey3Cnt < 0x80 ) { btKey3Current = 0; if( btKey3Past == 1 ) //下降沿(按键改变步进电机转向) { btKey3Past = 0; TR1 = ~TR1; } } if( uiKey3Cnt >= 0x80 ) { btKey3Current = 1; if( btKey3Past == 0 ) btKey3Past = 1; //上升沿(假设不做动作那就继续) } uiKey1Cnt = 0x80 + cstKeyMaxNum / 3 * 2; //新一轮的判断 uiKey2Cnt = 0x80 + cstKeyMaxNum / 3 * 2; uiKey3Cnt = 0x80 + cstKeyMaxNum / 3 * 2; uiKeyAllCnt = cstKeyMaxNum; } } /---------主函数---------*/ void main() { InitSys(); while( 1 ) { P0 = arrSegSelect[uiSpeed]; // P0口显示步进电机速度,范围1-4,1档速度最快 } }
蜂鸣器
#include <STC15F2K60S2.H> #define uint unsigned int #define uchar unsigned char /---------引脚别名定义---------/ sbit sbtBeep = P3 ^ 4; //蜂鸣器引脚 sbit sbtKey1 = P3 ^ 2; //按键1引脚 /---------变量定义---------/ bit btBeepFlag; //控制蜂鸣器开关的标志位 /---------初始化函数--------/ void init() { P3M1 = 0x00; P3M0 = 0x10; //设置P3^4为推挽模式 TMOD = 0x00; //设置定时器0,工作方式0,16位自动重装定时器 TH0 = 0xff; //设定定时器0的初值 TL0 = 0x03; EA = 1; //打开总中断 ET0 = 1; //打开定时器0中断允许位 TR0 = 1; btBeepFlag = 0; //标志位置0 P0 = 0x00; //关闭P0端口 sbtBeep = 0; //蜂鸣器引脚置0,以保护蜂鸣器} /---------延时子函数--------/ void delay( uint xms ) { uchar i; for( ; xms > 0; xms-- ) for( i = 114; i > 0; i-- ) { ; } } /---------主函数--------/ void main(){ init(); while( 1 ) { if( sbtKey1 == 0 ) { delay( 10 ); //延时消抖 if( sbtKey1 == 0 ) { while( !sbtKey1 ); btBeepFlag = ~btBeepFlag; //蜂鸣器开关标志位翻转 } } } } /---------T0定时器中断服务处理函数--------/ void T0_Process() interrupt 1 { if( btBeepFlag ) { sbtBeep = ~sbtBeep; //产生方波使得蜂鸣器发声 } else { sbtBeep = 0; //停止发声,并将sbtBeep端口置于低电平 } }
可变调的蜂鸣器
/********************** myBeep2 可变调蜂的鸣器 型号:STC15F2K60S2 主频:11.0592MHz **********/ #include <STC15F2K60S2.H> #define uint unsigned int #define uchar unsigned char /---------引脚别名定义---------/ sbit sbtBeep = P3 ^ 4; //蜂鸣器引脚 sbit sbtKey1 = P3 ^ 2; //按键1引脚 sbit sbtKey2 = P3 ^ 3; //按键2引脚 sbit sbtSel0 = P2 ^ 0; //位选信号位 sbit sbtSel1 = P2 ^ 1; //位选信号位 sbit sbtSel2 = P2 ^ 2; //位选信号位 sbit sbtSel3 = P2 ^ 3; //LED与数码管显示的控制位 /---------变量定义---------/ uint sbtKey1_state = 0; //0:Key1未按下 1:Key1已按下 uint sbtKey2_state = 0; //0:Key2未按下 1:Key1已按下 bit btBeepFlag; //控制蜂鸣器开关的标志位 uint uiToneNum = 0; //音调 uchar arrSegSelect[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; //段选0-f /---------初始化函数--------/ void Init() { P0M0 = 0xff; P0M1 = 0x00; P2M0 = 0x08; P2M1 = 0x00; //设置P3^4为推挽模式 P3M1 = 0x00; P3M0 = 0x10; AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式为16位自动重装 TL0 = 0xCD; //设置定时初值 TH0 = 0xF4; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 btBeepFlag = 0; P0 = 0x00; //数码管和LED显示清零 sbtSel0 = 1; //位选设置为第七位 sbtSel1 = 1; sbtSel2 = 1; sbtBeep = 0; //蜂鸣器引脚置0,以保护蜂鸣器 ET0 = 1; EA = 1; /---------延时子函数--------/ void DelayMs( uint xms ) { uchar i; for( ; xms > 0; xms-- ) for( i = 114; i > 0; i-- ) { ; } } /---------显示子函数--------/ void DisplaySeg7Led() { P0 = 0; sbtSel3 = 0; P0 = arrSegSelect[uiToneNum]; DelayMs( 1 ); P0 = 0; sbtSel3 = 1; P0 = 0x08; DelayMs( 1 ); } /---------主函数--------/ void main() { Init(); while( 1 ) { if( sbtKey1 == 0 ) { if( sbtKey1_state == 0 ) //判断按键1是否按下 { DelayMs( 10 ); //延时消除抖动 if( sbtKey1 == 0 ) { uiToneNum++; //声调改变 if( uiToneNum == 10 ) uiToneNum = 0; TH0 = 0xF4 - uiToneNum; //减小重装值,从而减小 //定时器中断(蜂鸣器振动)频率 sbtKey1_state = 1; //设置按键1为已按下 } } } else sbtKey1_state = 0; if( sbtKey2 == 0 ) { if( sbtKey2_state == 0 ) //判断按键2是否按下 { DelayMs( 10 ); //延时消除抖动 if( sbtKey2 == 0 ) { btBeepFlag = !btBeepFlag; //蜂鸣器开关切换 sbtKey2_state = 1; //设置按键1为已按下 } } } else sbtKey2_state = 0; DisplaySeg7Led(); } } /---------T0定时器中断服务处理函数--------/ void T0_Process() interrupt 1 { if( btBeepFlag ) { sbtBeep = ~sbtBeep; //产生方波使得蜂鸣器发声 } else sbtBeep = 0; //如果开关关闭,则蜂鸣器断电以保护蜂鸣器 }
振动传感器
#include <STC15F2K60S2.h> #include <intrins.h> //nop(); #define uchar unsigned char uchar code arrLed[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; //Led值 /---------引脚别名定义---------/ sbit sbtVib = P2 ^ 4; //振动传感器 sbit sbtLedSel = P2 ^ 3; //数码管与LED灯切换引脚 /---------延时函数---------/ void Delay40ms() //延时40ms@11.0592MHz { unsigned char i, j, k; nop(); nop(); i = 2; j = 175; k = 75; do { do { while ( --k ); } while ( --j ); } while ( --i ); } /---------初始化函数---------/ void Init() { P0M0 = 0xff; P0M1 = 0x00; P2M0 = 0x08; //P2.3口推挽输出 P2M1 = 0x00; sbtLedSel = 1; } /---------主函数---------/ void main() { uchar i = 0; Init(); sbtVib = 1; P0 = 0x00; //初始LED灯为灭 while( 1 ) { if( sbtVib == 0 ) //若检测到低电平说明振动发生,点亮LED { i = 0; while( i < 9 ) { P0 = arrLed[i]; Delay40ms(); //延时 i++; } } else P0 = 0x00; } }
|