嵌入式学习之基础编程

前言

在编写代码时,要添加头文件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(key2
0)
{
count4++;
}
}
void main()
{
Init();
while(1)
{
if(flag4)//修正位选位置 可放在中断程序外 放在中断外 效果更好
flag=0;
if(count1
30)//消抖大概6ms 总共统计次数 30次
{
if(count2>=20)// 如果低电平的有效次数为 2/3 以上
{
if(status_P1)
{
status_P=0;
number++;
}
}
else
status_P=1;
count1=0;
count2=0;
}
if(count3
30)//消抖大概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() //延时[email protected]
{
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;
}
}

Guess you like

Origin blog.csdn.net/qq_52297656/article/details/119462880