From 5c785573beb6d3f7093a77127061afd1e5d6a04a Mon Sep 17 00:00:00 2001 From: cyp0633 Date: Thu, 30 Jun 2022 10:40:46 +0800 Subject: [PATCH] Initial commit --- 1919810_2/191980_2.uvopt | 214 +++++++++++++++++ 1919810_2/191980_2.uvproj | 395 +++++++++++++++++++++++++++++++ 1919810_2/inc/Beep.h | 28 +++ 1919810_2/inc/DS1302.h | 75 ++++++ 1919810_2/inc/EXT.h | 64 +++++ 1919810_2/inc/FM_Radio.h | 49 ++++ 1919810_2/inc/IR.h | 85 +++++++ 1919810_2/inc/Key.H | 34 +++ 1919810_2/inc/M24C02.h | 32 +++ 1919810_2/inc/STC15F2K60S2.H | 237 +++++++++++++++++++ 1919810_2/inc/StepMotor.h | 50 ++++ 1919810_2/inc/Vib.h | 21 ++ 1919810_2/inc/adc.h | 79 +++++++ 1919810_2/inc/displayer.h | 26 ++ 1919810_2/inc/hall.H | 24 ++ 1919810_2/inc/music.h | 100 ++++++++ 1919810_2/inc/sys.H | 63 +++++ 1919810_2/inc/uart1.h | 58 +++++ 1919810_2/inc/uart2.h | 65 +++++ 1919810_2/source/STCBSP_V3.6.LIB | Bin 0 -> 61916 bytes 1919810_2/source/main.c | 43 ++++ key/inc/Beep.h | 28 +++ key/inc/DS1302.h | 75 ++++++ key/inc/EXT.h | 64 +++++ key/inc/FM_Radio.h | 49 ++++ key/inc/IR.h | 85 +++++++ key/inc/Key.H | 34 +++ key/inc/M24C02.h | 32 +++ key/inc/STC15F2K60S2.H | 237 +++++++++++++++++++ key/inc/StepMotor.h | 50 ++++ key/inc/Vib.h | 21 ++ key/inc/adc.h | 79 +++++++ key/inc/displayer.h | 26 ++ key/inc/hall.H | 24 ++ key/inc/music.h | 100 ++++++++ key/inc/sys.H | 63 +++++ key/inc/uart1.h | 58 +++++ key/inc/uart2.h | 65 +++++ key/key.uvopt | 197 +++++++++++++++ key/key.uvproj | 395 +++++++++++++++++++++++++++++++ key/source/STCBSP_V3.6.LIB | Bin 0 -> 61916 bytes key/source/main.c | 81 +++++++ 42 files changed, 3505 insertions(+) create mode 100644 1919810_2/191980_2.uvopt create mode 100644 1919810_2/191980_2.uvproj create mode 100644 1919810_2/inc/Beep.h create mode 100644 1919810_2/inc/DS1302.h create mode 100644 1919810_2/inc/EXT.h create mode 100644 1919810_2/inc/FM_Radio.h create mode 100644 1919810_2/inc/IR.h create mode 100644 1919810_2/inc/Key.H create mode 100644 1919810_2/inc/M24C02.h create mode 100644 1919810_2/inc/STC15F2K60S2.H create mode 100644 1919810_2/inc/StepMotor.h create mode 100644 1919810_2/inc/Vib.h create mode 100644 1919810_2/inc/adc.h create mode 100644 1919810_2/inc/displayer.h create mode 100644 1919810_2/inc/hall.H create mode 100644 1919810_2/inc/music.h create mode 100644 1919810_2/inc/sys.H create mode 100644 1919810_2/inc/uart1.h create mode 100644 1919810_2/inc/uart2.h create mode 100644 1919810_2/source/STCBSP_V3.6.LIB create mode 100644 1919810_2/source/main.c create mode 100644 key/inc/Beep.h create mode 100644 key/inc/DS1302.h create mode 100644 key/inc/EXT.h create mode 100644 key/inc/FM_Radio.h create mode 100644 key/inc/IR.h create mode 100644 key/inc/Key.H create mode 100644 key/inc/M24C02.h create mode 100644 key/inc/STC15F2K60S2.H create mode 100644 key/inc/StepMotor.h create mode 100644 key/inc/Vib.h create mode 100644 key/inc/adc.h create mode 100644 key/inc/displayer.h create mode 100644 key/inc/hall.H create mode 100644 key/inc/music.h create mode 100644 key/inc/sys.H create mode 100644 key/inc/uart1.h create mode 100644 key/inc/uart2.h create mode 100644 key/key.uvopt create mode 100644 key/key.uvproj create mode 100644 key/source/STCBSP_V3.6.LIB create mode 100644 key/source/main.c diff --git a/1919810_2/191980_2.uvopt b/1919810_2/191980_2.uvopt new file mode 100644 index 0000000..453299e --- /dev/null +++ b/1919810_2/191980_2.uvopt @@ -0,0 +1,214 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + Target 1 + 0x0 + MCS-51 + + 35000000 + + 1 + 1 + 1 + 0 + 0 + + + 0 + 65535 + 0 + 0 + 0 + + + 120 + 65 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + -1 + + + + + + + + + + + + + + + 0 + 0 + 2 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + E:\Code\keil\1919810_2\main.c + + +
+
+ + 0 + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + Source Group 1 + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 1 + 0 + 0 + .\source\main.c + main.c + 0 + 0 + + + 1 + 2 + 4 + 0 + 0 + 0 + E:\Code\keil\1919810_2\source\STCBSP_V3.6.LIB + STCBSP_V3.6.LIB + 0 + 0 + + + +
diff --git a/1919810_2/191980_2.uvproj b/1919810_2/191980_2.uvproj new file mode 100644 index 0000000..fa4de15 --- /dev/null +++ b/1919810_2/191980_2.uvproj @@ -0,0 +1,395 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + Target 1 + 0x0 + MCS-51 + 0 + + + STC15F2K60S2 Series + STC + IRAM(0-0xFF) XRAM(0-0x6FF) IROM(0-0xEFF8) CLOCK(35000000) MODP2 + + "LIB\STARTUP.A51" ("Standard 8051 Startup Code") + + 62472 + STC15F2K60S2.H + + + + + + + + + + + 0 + 0 + + + + STC\ + STC\ + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + 191980_2 + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 0 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + 65535 + + + S8051.DLL + + DP51.DLL + -pDP8051 + S8051.DLL + + TP51.DLL + -p51 + + + + 0 + 0 + 0 + 0 + 16 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + + 0 + -1 + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + 0 + 0 + -1 + + 0 + + + + + + + 0 + + + + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0x0 + 0xffff + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0xeff9 + + + 0 + 0x0 + 0x100 + + + 0 + 0x0 + 0x700 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + + + 0 + 0 + 1 + 0 + 1 + 3 + 8 + 2 + 1 + 1 + 0 + 0 + + + + + .\inc + + + + 0 + 1 + 0 + 0 + + + + + + + + + 0 + 0 + 1 + 0 + 2 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source Group 1 + + + main.c + 1 + .\source\main.c + + + STCBSP_V3.6.LIB + 4 + E:\Code\keil\1919810_2\source\STCBSP_V3.6.LIB + + + + + + + +
diff --git a/1919810_2/inc/Beep.h b/1919810_2/inc/Beep.h new file mode 100644 index 0000000..a95550e --- /dev/null +++ b/1919810_2/inc/Beep.h @@ -0,0 +1,28 @@ +/**********************************Beep V2.0 说明 ************************************************************************ +Beep用于控制“STC-B学习板”上无源蜂鸣器的发声。Beep模块共提供1个驱动函数、2个应用函数: + (1) BeepInit():蜂鸣器模块驱动函数 + (2) Set_Beep(unsigned int Beep_freq, unsigned char Beep_time):控制蜂鸣器发声,非阻塞型 + 函数参数: + Beep_freq:指定发声频率,单位Hz。小于10将无输出 + Beep_time:指定发声时长。发声时长=10*Beep_time (mS) ,最长 655350mS + 函数返回值:enumSetBeepOK:调用成功,enumSetBeepFail:调用失败(或因蜂鸣器正在发音) + (3) GetBeepStatus(void): 获取Beep当前状态,enmuBeepFree:空闲, enumBeepBusy ,正在发音 + (4) Beep模块使用了STC内部CCP模块1通道 + +编写:徐成(电话18008400450) 2021年3月3日设计,2021年3月26日更新 +*/ + +#ifndef _beep_H_ +#define _beep_H_ + +extern void BeepInit(); // 蜂鸣器初始化 + +extern char SetBeep(unsigned int Beep_freq, unsigned int Beep_time); // 发指定频率声音, 发声时长=10×Beep_time (mS) ,最长 655350mS + // Beep_freq < 10 Hz, 不发音 + // 函数返回 enumSetBeepOK:调用成功, enumSetBeepFail:调用失败(调用时正在发音) + +extern unsigned char GetBeepStatus(void); // 获取状态,enumBeepFree:自由, enumBeepBusy,正在发声 + +enum BeepActName {enumBeepFree=0,enumBeepBusy,enumSetBeepOK,enumSetBeepFail}; + +#endif \ No newline at end of file diff --git a/1919810_2/inc/DS1302.h b/1919810_2/inc/DS1302.h new file mode 100644 index 0000000..377b96e --- /dev/null +++ b/1919810_2/inc/DS1302.h @@ -0,0 +1,75 @@ +/**********************************DS1302 V1.1 说明 ************************************************************************ +DS1302模块用于控制“STC-B学习板”上DS1302芯片操作。 +DS1302提供RTC(实时时钟)和NVM(非易失存储器)功能(断电后,RTC和NVM是依靠纽扣电池BAT维持工作的)。其中: + RTC提供:年、月、日、星期、时、分、秒功能 + NVM提供:31 Bytes非易失存储器功能(地址为:0~30)。其中,地址为30的单元被DS1302Init()函数用于检测DS1302是否掉电,用户不能使用) +DS1302模块共提供1个驱动函数、4个应用函数: + + (1) void DS1302Init(struct_DS1302_RTC time):DS1302驱动函数。使用DS1302,需用该函数初始化和驱动一次 + 函数参数:结构struct_DS1302_RTC time + 如果DS1302掉电(初始化时检测RTC数据失效),则以参数time定义的时间初始化RTC + 函数返回值:无 + + (2) struct_DS1302_RTC RTC_Read(void):读取DS1302内部实时时钟RTC内容 + 函数参数:无 + 函数返回值:结构struct_DS1302(见结构struct_DS1302定义) + + (3) void RTC_Write(struct_DS1302_RTC time) :写DS1302内部实时时钟RTC内容 + 函数参数:结构struct_DS1302 time(见结构struct_DS1302定义) + 函数返回值:无 + + (4) unsigned char NVM_Read(unsigned char NVM_addr): 读取NVM一个指定地址内容 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值0~30(共31个单元) + 函数返回值:当函数参数正常时,返回NVM中对应单元的存储数值(1Byte) + 当函数参数错误时,返回enumDS1302_error + + (5) unsigned char NVM_Write(unsigned char NVM_addr, unsigned char NVM_data):向NVM一个指定地址写入新值 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值:0~30(共31个单元。其中,第30单元被DS1302Init()函数用于检测DS1302是否掉电,用户不能使用)) + NVM_data:待写入NVM单元的新值(1Byte) + 函数返回值:当函数参数正常时,返回enumDS1302_OK + 当函数参数错误时,返回enumDS1302_error + +结构struct_DS1302_RTC定义:(参见DS1302Z数据手册) +typedef struct + { unsigned char second; //秒(BCD码,以下均为BCD码) + unsigned char minute; //分 + unsigned char hour; //时 + unsigned char day; //日 + unsigned char month; //月 + unsigned char week; //星期 + unsigned char year; //年 + } struct_DS1302_RTC; + +关于DS1302内部非易失性存储器补充说明: + DS1302提供的非易失性存储器为低功耗RAM结构,靠纽扣电池保持掉电后其存储内容不变。 + 与M24C01区别:容量小(仅31字节),但无”写“寿命问题,且写周期很短(可忽略:即两次写操作之间无需等待); + 读、写DS1302内部NVM每一个字节均需要花费一定操作时间(数十uS); + 仅在需要时使用以上读或写函数读写需要的特定字节内容,应避免对其进行无效、大量、重复操作! + +编写:徐成(电话18008400450) 2021年8月5日设计,2021年8月15日改进 +*/ + +#ifndef _DS1302_H_ +#define _DS1302_H_ + +typedef struct + { unsigned char second; //秒(BCD码,以下均为BCD码) + unsigned char minute; //分 + unsigned char hour; //时 + unsigned char day; //日 + unsigned char month; //月 + unsigned char week; //星期 + unsigned char year; //年 + } struct_DS1302_RTC; + +extern void DS1302Init(struct_DS1302_RTC time); //DS1302初始化 +extern struct_DS1302_RTC RTC_Read(void); //读RTC(读RTC时钟内容) +extern void RTC_Write(struct_DS1302_RTC time); //写RTC(校对RTC时钟) +extern unsigned char NVM_Read(unsigned char NVM_addr); //读NVM(读DS1302中的非易失存储单元内容) +extern unsigned char NVM_Write(unsigned char NVM_addr, unsigned char NVM_data); //写NVM(写DS1302中的非易失存储单元) + +enum DS1302name {enumDS1302_OK,enumDS1302_error}; + +#endif \ No newline at end of file diff --git a/1919810_2/inc/EXT.h b/1919810_2/inc/EXT.h new file mode 100644 index 0000000..65b8b87 --- /dev/null +++ b/1919810_2/inc/EXT.h @@ -0,0 +1,64 @@ +/********************************** EXT V1.0 说明 *********************************************** + +EXT模块用于控制“STC-B学习板”上扩展接口EXT上相关操作。 +EXT模块根据应用需要,在外接相应模块或部件后,可实现多种相应功能。这里提供部分应用驱动和API函数。 +EXT模块这里提供1个驱动函数和若干个应用层API函数。 +EXT模块的API函数不是同时有效的,而是根据初始化函数参数不同而分别有效。 + + (1) void EXTInit(char EXTfunction):EXT初始化函数。 + 函数参数:EXTfunction。定义EXT接口功能 + EXTfunction 取值:enumEXTWeight(秤重:由HX710、HX711组成的电子秤) + enumEXTPWM (脉宽调制:可用于控制直流电机正反转、速度,灯亮度等) + enumEXTDecode(增量式计数) + enumEXTUltraSonic (超声波测距) + 函数返回值:无 + 注意:当EXT扩展接口用于串口2时(TTL Uart,可用于串行通信、蓝牙模块连接等),在使用Uart2Init()函数初始化EXT后,不要再使用EXTInit()函数,以免引起功能冲突 + + (2)API函数 + (a) 电子秤。当EXTInit(char EXTfunction)使用enumEXTWeight参数时,GetWeight函数有效。 + int GetWeight(void) //获取电子秤ADC秤重数据(16bit,带符号整数。未清零、未标定。参见HX710、HX711数据手册(高16bit)) + + (b) PWM脉宽调制输出。当EXTInit(char EXTfunction)使用enumEXTPWM参数时,SetPWM函数有效。 + void SetPWM(unsigned char PWM1, unsigned char freq1, unsigned char PWM2, unsigned char freq2); + //设置EXT上输出PWM(参数PWM为占空比(输出高电平时间的比例):0~100,单位%)。freqx为频率:1~255Hz) + //实际频率 = 1000/int(1000/freqx)。即:1000/i=4,5,6...1000,或250,200,167,143,125,111,100,91,83...1 + //可用于控制直流电机正反转、转速(配合H型桥式电路),灯亮度,等 + + (c) 旋转编码器、或增量式编码器。当EXTInit(char EXTfunction)使用enumEXTDecode参数时,GetDecode函数有效。 + int GetDecode(void); //获取增量编码器增量值(相对上次读取后的新增量) + + (d) 超声波测距。当EXTInit(char EXTfunction)使用enumEXTUltraSonic参数时,GetUltraSonic函数有效。 + int GetUltraSonic(void); //获取超声波测距值(每秒5次测量,返回值单位:cm) + + (e) RFID读卡(暂缓) + (g) (蓝牙、串口)见串口2 + (h) (气敏、数据采集、电子尺、额温)见ADC +编程注意事项: + + +编写:徐成(电话18008400450) 2021年8月24日设计 +*/ + +#ifndef _EXT_H_ +#define _EXT_H_ + +extern void EXTInit(char EXTfunction); //扩展接口初始化 +enum EXTname {enumEXTWeight //电子秤 + ,enumEXTPWM, //PWM,控制直流电机转动方向、快慢 + ,enumEXTDecode //增量式计数(旋转编码器) + ,enumEXTUltraSonic //超声波测距 + //串口2,蓝牙:见uart2模块 + //气敏、数据采集、电子尺、额温枪等:见ADC + }; +extern int GetWeight(void); //获取电子秤ADC秤重数据(HX710、HX711输出高16bit,带符号数整数。未清零、未标定) +extern int GetDecode(void); //获取增量编码器增量值(相对上次读取后的新增量) +extern int GetUltraSonic(void); //获取超声波测距值(每秒5次测量,返回值单位:cm) +extern void SetPWM(unsigned char PWM1, unsigned char freq1, unsigned char PWM2, unsigned char freq2); + //设置EXT上输出PWM(参数PWM为占空比(输出高电平时间的比例):0~100,单位%)。freqx为频率:1~255Hz) + //实际频率 = 1000/int(1000/freqx)。即:1000/i=4,5,6...1000,或250,200,167,143,125,111,100,91,83...1 + //可用于控制直流电机正反转、转速(配合H型桥式电路),灯亮度,等 + + + + +#endif \ No newline at end of file diff --git a/1919810_2/inc/FM_Radio.h b/1919810_2/inc/FM_Radio.h new file mode 100644 index 0000000..3b15155 --- /dev/null +++ b/1919810_2/inc/FM_Radio.h @@ -0,0 +1,49 @@ +/********************************** FMRadio V1.1 说明 ************************************************************************ +FMRadio模块用于控制“STC-B学习板”上FM收音机操作。 +FMRadio模块模块共提供1个初始化函数、2个应用函数 + + (1) void FMRadioInit(struct_FMRadio FMRadio); //收音机模块初始化函数。该函数只执行一次。初始化后,以下各应用函数方可正确使用。 + 函数参数:FMRadio (见结构struct_FMRadio定义) + 函数返回值:无 + + (2) void SetFMRadio(struct_FMRadio FMRadio); //设置FM收音机控制参数。 + 函数参数:FMRadio (见结构struct_FMRadio定义) + 函数返回值:无 + + (3) struct_FMRadio GetFMRadio(void); //获取当前FM收音机参数。 + 函数参数:无 + 函数返回值:返回FM控制模型数据(见结构struct_FMRadio定义) + +结构struct_FMRadio定义: + typedef struct //FM收音机控制模型 + { unsigned int frequency; // FM收音机收音频率 (frequency参数范围:887~1080。单位:0.1MHz,如887代表88.7MHz)。错误参数或参数与当前值无变化,将忽略 + unsigned char volume; // FM收音机音量 (volume参数范围:0~15。0为最小音量)。错误参数或参数与当前值无变化,将忽略 + unsigned char GP1; // FM指示灯1。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP2; // FM指示灯2。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP3; // FM指示灯3。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + } struct_FMRadio; + +编程注意事项: + 1,本版本暂未输出调谐、自动搜索、电台信号等控制和状态信息,因此,暂不能完成自动搜索电台等收音机功能。 + 2,FM收音机借用USB转串口模块(CH340)时钟(硬件设计原因),需要连接USB接口(供电、通信)到USB主设备,CH340方有时钟产生和输出。 + 故STC-B学习板的USB接口需要连接到一个USB主设备方可收音,仅USB供电时(如USB充电宝、或计算机休眠时的USB接口),FM收音机可能不工作 + +编写:徐成(电话18008400450) 2021年8月10日设计,2021年8月16日改进 +*/ + +#ifndef _FM_Radio_H_ +#define _FM_Radio_H_ + +typedef struct //FM收音机控制模型 + { unsigned int frequency; // FM收音机收音频率 (frequency参数范围:887~1080。单位:0.1MHz,如887代表88.7MHz)。错误参数或参数与当前值无变化,将忽略 + unsigned char volume; // FM收音机音量 (volume参数范围:0~15。0为最小音量)。错误参数或参数与当前值无变化,将忽略 + unsigned char GP1; // FM指示灯1。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP2; // FM指示灯2。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP3; // FM指示灯3。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + } struct_FMRadio; + +extern void FMRadioInit(struct_FMRadio FMRadio); //收音机模块初始化函数。输入FM控制模型数据,无返回值。初始化后,以下各应用函数方可正确使用 +extern void SetFMRadio(struct_FMRadio FMRadio); //设置FM收音机控制参数。输入FM控制模型数据,无返回值。 +extern struct_FMRadio GetFMRadio(void); //获取当前FM收音机参数。无输入参数,返回FM控制模型数据 + +#endif \ No newline at end of file diff --git a/1919810_2/inc/IR.h b/1919810_2/inc/IR.h new file mode 100644 index 0000000..2ae2d39 --- /dev/null +++ b/1919810_2/inc/IR.h @@ -0,0 +1,85 @@ +/********************************** IR V3.5a 说明 *********************************************** + +IR模块用于控制“STC-B学习板”上红外发送与接收控制,支持PWM、PPM红外编码协议的发送,PWM红外编码的接收,可用于制作红外遥控器、红外通信等。 +IR模块提供1个驱动函数、5个API应用函数、1个红外接收事件(enumEventIrRxd:红外Ir上收到一个数据包)。 +IR模块已不与串口通信(uart和uart2)冲突,可用与它们同时工作。(以前冲突) + + (1) void IrInit(unsigned char Protocol):IR模块初始化函数。 + 函数参数:unsigned char Protocol,定义红外协议。 + Protocol 暂仅提供取值:NEC_R05d(定义红外协议基本时间片时长 = 13.1*Protocol uS) + 函数返回值:无 + + (2) char IrTxdSet(unsigned char *pt,unsigned char num):以自由编码方式控制IR发送:可用于编写任意编码协议的红外发送,如各种电器红外遥控器等 + 函数参数:unsigned char *pt,指向待发送红外编码数据的首地址。编码规则如下: + 码1红外发送时长,码1红外发送停止时长 //单位:协议基本时间片的个数值,最大255。如当协议基本时间片为0.56mS时, + ,码2红外发送时长,码2红外发送停止时长 //如当协议基本时间片为0.56mS时,数值1代表0.56mS时长,3代表1.68mS时长,...... + ...... + ...... + ,码n红外发送时长,码n红外发送停止时长 + unsigned char num,待发送红外编码数据的大小(字节数) + 函数返回值:enumIrTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumIrTxFailure:调用失败(主要原因是:红外发送正忙(上一数据包未发完)、或红外正在接收一个数据包进行中 + (同IrPrint()函数返回值) + 补充说明:参照该格式定义和电器遥控器编码格式,可实现任何38KHz红外遥控器功能。 + + (3) char IrPrint(void *pt, unsigned char num)://以NEC的PWM编码方式发送数据,可用于符合该函数发送格式的部分电器遥控器;与GetIrRxNum()、SetIrRxd()配合,可进行红外双机通信;等 + //红外发送数据格式为:引导码:发(16*基本时间片),停(8*基本时间片)。0.56mS时:发9mS、停4.5mS + 数据编码:"0" -- 发(1*基本时间片),停(1*基本时间片) + "1" -- 发(1*基本时间片),停(3*基本时间片) + 先发高位、后发低位 + 结束码:发(1*基本时间片),停(1*基本时间片) + //非阻塞函数,该函数从被调用到返回大约1uS左右时间,但所指定的数据经红外发送完毕则需要较长时间(每字节大约需要10mS量级时间)。 + //IrPrint()函数用法完全类似与uart模块的Uart1Print()和Uart2Print()用法,(仅num参数为unsigned char,可参照使用) + 函数参数:void *pt :指定发送数据包位置(数据包不含引导码、结束码信息,仅待发送的有效数据) + unsigned char num:发送数据包大小(字节数,不含引导码、结束码) + 函数返回值:enumIrTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumIrTxFailure:调用失败(主要原因是:红外发送正忙(上一数据包未发完)、或红外正在接收一个数据包进行中 + (同IrTxdSet()函数返回值) + + (4) void SetIrRxd(void *RxdPt,unsigned char RxdNmax):设置红外接收数据包存放位置、每个数据包最大字节数。 + 收到一个数据包(至少1字节数据)时将产生numEventIrRxd事件。与它机IrPrint()函数配合,可实现红外数据通信 + 函数参数: void char *RxdPt:指定接收数据包存放区(首地址) + unsigned char RxdNmax:指定每个数据包接收最大字节数。当收到的数据大于Nmax后,将被丢弃。 + 函数返回值:无 + + (5) unsigned char GetIrRxNum(void):获取收到的红外接收数据包实际字节数。与SetIrRxd()配合,可实现红外数据包接收。(它机应使用IrPrint()函数发送数据包) + 返回取值 <= Ir接收缓冲区最大字节数(RxdNmax定义)。如果实际红外数据包字节数大于RxdNmax,收到的多余字节数将不被存储(也不进行计数) + 函数参数: 无 + 函数返回值:红外接收数据包大小(字节数)。 + 当收到一个数据包的numEventIrRxd事件产生后,可用该函数获取红外接收数据包的大小(字节数)。其它时间访问,其值不确定 + + (6) char GetIrStatus(void): 获取Ir状态 + 函数返回值:enumIrFree:红外空闲 + enumIrBusy:红外正忙(正在发送数据包,或正在接收数据包) + + (7) 红外接收事件enumEventIrRxd:红外Ir上收到一个符合格式的数据包(红外格式见IrPrint()函数说明)。 + 如果接收数据包实际字节数大于Ir接收缓冲区最大字节数(RxdNmax定义),也在收到数据包结束符后产生enumEventIrRxd事件 + +补充说明: + (1) 串口1、串口2波特率可独立设置,互不影响. + (2) 串口1、串口2、红外通信可同时工作,互不影响 + (3) 串口1、串口2用法基本上完全一致,红外通信用法也基本相同。不同地方是: + a,串口1固定在USB接口上,可用于与计算机通信;而串口2可初始化在EXT扩展、或485接口上(在485接口上时仅单工工作); + b,红外通信速率固定不可变(大约相当于500~800 bps),通信时没有包头匹配功能。红外模块除通信功能外,还提供用于电器红外遥控的应用函数; + c,红外通信模块仅为单工工作。不发送时自动进入接收状态;有数据发送时自动进入发送状态,但正在接收数据包过程中不会进入发送状态。 + +编写:徐成(电话18008400450) 2021年8月24日设计,2021年11月5日更新 +*/ + +#ifndef _IR_H_ +#define _IR_H_ + +extern void IrInit(unsigned char Protocol); //IR模块初始化。参数:定义红外IR基本周期 +enum IrProtocalName {NEC_R05d=43}; //定义红外IR协议基本周期 = 43*1000/76 = 566 (uS) + +extern char IrTxdSet(unsigned char *pt,unsigned char num); //以自由编码方式控制IR发送:可用于编写任意编码协议的红外发送,如各种电器红外遥控器等 +extern char IrPrint(void *pt, unsigned char num); //以NEC的PWM编码方式发送数据,可用于符合该函数发送格式的部分电器遥控器;与SetIrRxd()配合,可进行红外双机通信;等 +extern void SetIrRxd(void *RxdPt,unsigned char RxdNmax); //设置红外接收数据包存放位置、每个数据包最大字节数。收到一个数据包(至少1字节数据)时将产生numEventIrRxd事件。与它机IrPrint()函数配合,可实现红外数据通信 +extern unsigned char GetIrRxNum(void); //当收到一个数据包的numEventIrRxd事件产生后,可用该函数获取红外接收数据包的大小(字节数)。其它时间访问,其值不确定 +extern char GetIrStatus(void); //获取Ir状态,enumIrFree:红外接口空闲, enumIrBusy,红外接口正忙 + +enum IrActName {enumIrFree=0 //红外发送空闲 + ,enumIrBusy // 忙 + ,enumIrTxOK // 发送成功 + ,enumIrTxFailure}; // 发送失败(正忙) +#endif \ No newline at end of file diff --git a/1919810_2/inc/Key.H b/1919810_2/inc/Key.H new file mode 100644 index 0000000..57f6d07 --- /dev/null +++ b/1919810_2/inc/Key.H @@ -0,0 +1,34 @@ +/**********************************key V2.0 说明 ************************************************************************ +Key模块用于获取“STC-B学习板”上三个按键的状态。提供按键模块加载和一个应用函数,一个“按键事件:enumEventKey: + (1) KeyInit():按键模块加载函数; + (2) char GetKeyAct(char Key):获取按键状态。 + 函数参数:Key,指定要获取状态的按键。Key取值: + enumKey1 + enumKey2 + enumKey3 +(当参数取值超出有效范围,函数将返回fail) + 函数返回值: + enumKeyNull(无按键动作) + enumKeyPress(按下) + enumKeyRelease(抬起) + enumKeyFail(失败) + 返回值是经过多次检测按键实时状态和统计检测结果后(软件消抖)的有效事件。 + 每个按键查询一次后,事件值变成enumKeyNull。事件值仅查询一次有效。 + (3) 按键事件:enumEventKey + 当三个按键(enumKey1,enumKey2,enumKey3)中任意一个按键有”按下“或”抬起“动作时,将产生一个”按键事件“,响应按键事件的用户处理函数由用户编写,并有sys中提供的SetEventCallBack函数设置. + +补充说明:如果启用了ADC模块,按键3(Key3)任何操作在本模块不可检测到和有任何信息反应,这时按键3(Key3)任何操作将在ADC模块中检测和反应。使用方法相同,具体见ADC模块说明。 + +编写:徐成(电话18008400450) 2021年3月5日设计,2021年8月26日更新 +*/ + +#ifndef _key_H_ +#define _key_H_ + +extern void KeyInit(); +extern unsigned char GetKeyAct(char Key) ; //获取按键enumKey1,enumKey2,enumKey3事件 + //返回值:enumKeyNull——无,enumKeyPress——下降沿,enumKeyRelease——上升沿,enumKeyFail——错误 +enum KeyName {enumKey1,enumKey2,enumKey3}; //按键名 +enum KeyActName {enumKeyNull,enumKeyPress,enumKeyRelease,enumKeyFail}; //按键动作名 + +#endif \ No newline at end of file diff --git a/1919810_2/inc/M24C02.h b/1919810_2/inc/M24C02.h new file mode 100644 index 0000000..fc135cd --- /dev/null +++ b/1919810_2/inc/M24C02.h @@ -0,0 +1,32 @@ +/**********************************M24C02 V1.0 说明 ************************************************************************ +M24C02模块用于控制“STC-B学习板”上IIC接口的非易失存储器(NVM)M24C02芯片操作。 +M24C02提供2K bits(256 Bytes)非易失存储器(NVM)功能(非易失存储器单元地址为:00~0xff)。 +M24C0402模块共提供2个应用函数(本模块不需要初始化) + + (1) unsigned char M24C02_Read(unsigned char NVM_addr): 读取M24C02一个指定地址内容 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值00~0xff(共256个单元) + 函数返回值:返回M24C02中对应单元的存储数值(1Byte) + + (2) void M24C02_Write(unsigned char NVM_addr, unsigned char NVM_data):向M24C02一个指定地址写入新值 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值:00~0xff(共256个单元) + NVM_data:待写入M24C02单元的新值(1Byte) + +补充说明: + M24C02为非易失性存储器,其主要特点是:存储的内容在断电后能继续保存,一般用于保存断电需保留的工作系统参数; + 但读、写M24C02内部每一个字节均需要花费一定时间(每次读写操作大约数十uS,写周期为5~10mS),且有”写“寿命限制(每一单元大约”写“寿命为10万次量级寿命); + 与DS1302内部NVM区别:容量大(M24C02提供256字节,M24CXX系列最大可提供64K字节),但有“写”寿命限制(一般为数十万次“写”寿命“,且写周期长(5~10mS) + 因此,两次写操作之间需间隔5~10mS以上; + 仅在需要时使用以上读或写函数读写需要的特定字节内容,应避免对其进行无效、大量、重复操作! + +编写:徐成(电话18008400450) 2021年8月8日设计 +*/ + +#ifndef _M24C02_H_ +#define _M24C02_H_ + +extern unsigned char M24C02_Read(unsigned char NVM_addr); //读NVM(读M24C02中的非易失存储单元内容) +extern void M24C02_Write(unsigned char NVM_addr, unsigned char NVM_data); //写NVM(写M24C02中的非易失存储单元) + +#endif \ No newline at end of file diff --git a/1919810_2/inc/STC15F2K60S2.H b/1919810_2/inc/STC15F2K60S2.H new file mode 100644 index 0000000..96d807b --- /dev/null +++ b/1919810_2/inc/STC15F2K60S2.H @@ -0,0 +1,237 @@ +#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的捕捉/比较寄存器高字节 + +///////////////////////////////////////////////// + +#endif + diff --git a/1919810_2/inc/StepMotor.h b/1919810_2/inc/StepMotor.h new file mode 100644 index 0000000..6bbd1e8 --- /dev/null +++ b/1919810_2/inc/StepMotor.h @@ -0,0 +1,50 @@ +/**********************************StepMotor 说明 ************************************************************************ +StepMotor用于STC-B板控制步进电机。共提供1个驱动函数、3个应用函数: + (1) StepMotorInit():步进电机模块驱动函数 + (2) SetStepMotor(char StepMotor,unsigned char speed ,int steps ) 指定步进电机、按指定转动速度、转动指定步 + 函数参数:StepMotor 指定步进电机,取值(enum StepMotorName中定义) + enumStepMotor1: SM 接口上的步进电机 + enumStepMotor2: 此时,用L0~L3四个LED模拟一个4相步进电机 + enumStepMotor3: 此时,用L4~L7四个LED模拟一个4相步进电机 + speed 步进电机转动速度(0~255),单位:步/S。 (实际每步时间=int(1000mS/speed) mS),与设置速度可能存在一定误差 + steps 步进电机转动步数(-32768~32767),负值表示反转 + 函数返回:enumSetStepMotorOK: 调用成功(enum StepMotorActName中定义) + enumSetStepMotorFail:调用失败(电机名不在指定范围,或speed=0,或调用时正在转动) + (3)EmStop(char StepMotor) 紧急停止指定步进电机转动 + 函数参数:StepMotor 指定步进电机。函数参数不对将返回0值。 + 函数返回:剩余未转完的步数 + (4)GetStepMotorStatus(char StepMotor) 获取指定步进电机状态 + 函数参数:StepMotor 指定步进电机 + 函数返回:enumStepMotorFree:自由(enum StepMotorActName中定义) + enumStepMotorBusy,忙(正在转动) + enumSetStepMotorFail:调用失败(步进电机名不在指定范围) + +编写:徐成(电话18008400450) 2021年4月16日设计,2021年4月18日更新 +*/ + +#ifndef _StepMotor_H_ +#define _StepMotor_H_ + +extern void StepMotorInit(); // 步进电机模块初始化 +extern char SetStepMotor(char StepMotor,unsigned char speed ,int steps ); // 指定步进电机、按指定转动速度、转动指定步 + // 函数参数:StepMotor 指定步进电机,取值(enum StepMotorName中定义) + // enumStepMotor1: SM 接口上的步进电机 + // enumStepMotor2: 此时,用L0~L3四个LED模拟一个4相步进电机 + // enumStepMotor3: 此时,用L4~L7四个LED模拟一个4相步进电机 + // speed 步进电机转动速度(0~255),单位:步/S (实际每步时间=int(1000mS/speed) mS),与设置速度可能存在一定误差 + // steps 步进电机转动步数(-32768~32767),负值表示反转 + // 函数返回: + // enumSetStepMotorOK:调用成功 + // enumSetStepMotorFail:调用失败(电机名不在指定范围,或speed=0,或调用时正在转动) +extern int EmStop(char StepMotor); // 紧急停止指定步进电机转动 + // 函数参数:StepMotor 指定步进电机(函数参数不对将返回0值) + // 函数返回:剩余未转完的步数 +extern unsigned char GetStepMotorStatus(char StepMotor); // 获取指定步进电机状态 + // 函数参数:StepMotor 指定步进电机 + // 函数返回:enumStepMotorFree:自由 + // enumStepMotorBusy,忙(正在转动) + // enumSetStepMotorFail:调用失败(步进电机名不在指定范围) +enum StepMotorName {enumStepMotor1=0,enumStepMotor2,enumStepMotor3}; +enum StepMotorActName {enumStepMotorFree,enumStepMotorBusy,enumSetStepMotorOK,enumSetStepMotorFail}; + +#endif \ No newline at end of file diff --git a/1919810_2/inc/Vib.h b/1919810_2/inc/Vib.h new file mode 100644 index 0000000..ff8a281 --- /dev/null +++ b/1919810_2/inc/Vib.h @@ -0,0 +1,21 @@ +/**********************************振动传感器SV V2.0 说明 ************************************************************************ +SV用于获取"STC-B学习板"上Vib传感器状态.提供一个模块加载函数和一个应用函数,一个Vib事件enumEventVib: + (1) VibInit():振动传感器Vib模块初始化函数; + (2) char GetVibAct():获取Vib事件。 + 函数返回值:返回当前Vib传感器事件,返回值:enumVibNull——无,enumVibQuake——发生过振动 + 查询一次后,事件值变成 enumVibNull (仅查询一次有效) + (3) Vib传感器事件enumEventVib: + 当Vib检测到有”振动“事件时,将产生一个”振动事件“,响应事件的用户处理函数由用户编写, + 并有sys中提供的SetEventCallBack()函数设置. + +编写:徐成(电话18008400450) 2021年3月5日设计,2021年3月26日更新 +*/ + +#ifndef _Vib_H_ +#define _Vib_H_ + +extern void VibInit(); +extern unsigned char GetVibAct(void) reentrant; //获取Vib事件 +enum VibActName {enumVibNull,enumVibQuake}; //返回值:enuVibNull——无,enuVibQuake——发生过振动 + +#endif \ No newline at end of file diff --git a/1919810_2/inc/adc.h b/1919810_2/inc/adc.h new file mode 100644 index 0000000..eaf1a2c --- /dev/null +++ b/1919810_2/inc/adc.h @@ -0,0 +1,79 @@ +/**********************************ADC V3.5a 说明 ************************************************************************ +ADC模块用于“STC-B学习板”上与ADC相关电路:温度Rt、光照Rop、导航按键Nav、扩展接口EXT上的ADC转换。提供ADC模块初始化函数、2个应用函数,2个事件: + (1) AdcInit(char ADCsel):ADC模块初始化函数; + 函数参数: ADCsel选择扩展接口EXT是否用作ADC功能,取值: + ADCincEXT : 含对扩展接口EXT设置ADC功能(EXT上P1.0、P1.1不可作数字IO功能使用) + ADCexpEXT : 不含对扩展接口EXT设置ADC功能(EXT上P1.0、P1.1可作数字IO功能使用) + (2) struct_ADC GetADC():获取ADC值。 + 函数参数:无 + 函数返回值:返回数据结构 struct_ADC。 + 数据结构定义: + typedef struct //ADC转换结果 + { unsigned int EXT_P10; // 扩展接口EXT上P1.0脚ADC(10bit) + unsigned int EXT_P11; // 扩展接口EXT上P1.1脚ADC(10bit) + unsigned int Rt; // 热敏电阻上ADC(10bit) + unsigned int Rop; // 光敏电阻上ADC(10bit) + unsigned int Nav; // 导航按键上ADC(10bit) + } struct_ADC; + +说明1:每个数字表示 VCC/1024(单位:V),其中VCC为电路板供电电压(USB接口一般为5V左右) +说明2:对于导航按键,下面GetAdcNavAct函数输出消抖后导航按键事件和状态,更方便使用; + + (3) char GetAdcNavAct(char Nav_button):获取导航按键(包含K3)状态 + 函数参数:Nav_button:指定要获取状态的导航按键。取值: + enumAdcNavKey3(K3键), + enumAdcNavKeyRight(右按), + enumAdcNavKeyDown(下按), + enumAdcNavKeyCenter(中心按) + enumAdcNavKeyLeft(左按), + enumAdcNavKeyUp(上按). +(当参数取值不在有效范围,函数将返回enumKeyFail) + 函数返回值:返回当前按键事件,返回值:(同Key模块GetAdcKeyAct()返回值) + enumKeyNull(无按键动作), + enumKeyPress(按下), + enumKeyRelease(抬起), + enumKeyFail(失败) + 返回值是经过多次检测按键实时状态和统计检测结果后(软件消抖)的有效事件。 + 每个按键查询一次后,事件值变成 enumKeyNull (仅查询一次有效) + (4) 导航按键事件“:enumEventNav + 当导航按键5个方向或按键K3有任意”按下“或”抬起“动作时,将产生一个”导航按键事件“enumEventNav。响应导航按键事件的用户回调函数由用户编写,并由sys提供的SetEventCallBack()函数设置响应函数. + (5) 扩展接口EXT上P1.0、P1.1两个端口有新的AD值事件“:enumEventXADC + 当ADC模块对P1.0、P1.1进行ADC转换,获得了它们新的ADC结果时,将产生enumEventXADC事件,通知用户进行处理。响应enumEventXADC事件的用户回调函数由用户编写,并有sys提供的SetEventCallBack()函数设置响应函数. + ADC模块对P1.0、P1.1进行ADC转换速度为3mS,也即每3mS或每秒钟333次转换. + (6) 补充说明: + a:对EXT上P1.0、P1.0的转换速度为3mS,也即每秒钟提供333次转换结果,提供了有新转换结果事件:enumEventXADC,方便用户处理 +b:对于Rt、Rop,转换速度为9mS,也即每秒钟提供111次转换结果。没有提供相应“事件”,用户随时用函数GetAdcResult()查询和使用 + c:对导航按键进行了软件消抖处理,最快可支持导航按键每秒12次操作速度,提供了导航按键发生了操作事件:enumEventNav + d:由于导航按键与K3键共用了单片机同一个端口(P1.7),启用ADC模块后,P1.7口IO功能失效,只能用GetAdcNavAct(char Nav_button)函数获取K3按键的事件或状态。 + e: STC-B板上Rt型号为:10K/3950 NTC热敏电阻,光敏电阻Rop型号为:GL5516. 它们的ADC值与温度、光照强度关系请参阅它们的数据手册与STC-B电路图进行换算。 + + +编写:徐成(电话18008400450) 2021年3月25日设计,2021年8月30日修改 +*/ + +#ifndef _adc_H_ +#define _adc_H_ + +#define ADCincEXT 0x9B +#define ADCexpEXT 0x98 + +typedef struct //ADC转换结果 + { unsigned int EXT_P10; // 扩展接口EXT上P1.0脚ADC + unsigned int EXT_P11; // 扩展接口EXT上P1.1脚ADC + unsigned int Rt; // 热敏电阻上ADC + unsigned int Rop; // 光敏电阻上ADC + unsigned int Nav; // 导航按键上ADC + } struct_ADC; + +extern void AdcInit(char ADCsel); + +extern struct_ADC GetADC(); +extern unsigned char GetAdcNavAct(char Nav_button); //获取导航按键5个方向(右、下、中心、左、上)操作,以及按键K3操作的事件 + //返回值:enuKeyNull(无按键动作),enuKeyPress(按下),enuKeyRelease(抬起),enuKeyFail(失败) +enum KN_name {enumAdcNavKey3=0, //导航按键:按键K3 + enumAdcNavKeyRight, //导航按键:右 + enumAdcNavKeyDown, //导航按键:下 + enumAdcNavKeyCenter, //导航按键:中心 + enumAdcNavKeyLeft, //导航按键:左 + enumAdcNavKeyUp}; //导航按键:上 +#endif \ No newline at end of file diff --git a/1919810_2/inc/displayer.h b/1919810_2/inc/displayer.h new file mode 100644 index 0000000..9cd02dc --- /dev/null +++ b/1919810_2/inc/displayer.h @@ -0,0 +1,26 @@ +/**********************************display V2.0 说明 ************************************************************************ +displayer用于控制“STC-B学习板”上8个7段数码管(Seg7)和8个指示灯(Led)工作.提供显示模块加载和三个应用函数: + + (1) displayerInit():显示模块加载函数; + + (2) SetDisplayerArea(char Begin_of_scan,char Ending_of_Scan):设置LED启用区域。8个数码管从左至右编号分别为0——7,函数参数 + Begin_of_scan设定启用数码管起始编号,Ending_of_Scan为结束编号。设定范围内的数码管才工作和显示。 + 注:正常情况下,两个参数取值范围为0——7,且Ending_of_Scan>Begin_of_scan。但利用动态扫描和人眼视觉效果,可设置超出 + 该范围的参数,以实现特殊显示效果:如软件调整显示亮度,或非灯亮度显示,等; + + (3) Seg7Print(char d0,char d1,char d2,char d3,char d4,char d5,char d6,char d7):将8个参数值分别译码显示到对应的数码管上。 + 显示译码表(code char decode_table[])在main.c中,用户可以修改和增减. + + (4) LedPrint(char led_val):控制8个指示灯开关。参数light_val的8个bit位对应8个指示灯的开关,“1”——指示灯“亮” + +编写:徐成(电话18008400450) 2021年2月26日设计,2021年3月15日更新 +*/ + +#ifndef _displayer_H_ +#define _displayer_H_ +extern void DisplayerInit(); //加载显示模块工作 +extern void SetDisplayerArea(char Begin_of_scan,char Ending_of_Scan); //设置有效显示区域 +extern void Seg7Print(char d0,char d1,char d2,char d3,char d4,char d5,char d6,char d7); //在数码管上输出 +extern void LedPrint(char led_val); +#endif + diff --git a/1919810_2/inc/hall.H b/1919810_2/inc/hall.H new file mode 100644 index 0000000..bfcc3b1 --- /dev/null +++ b/1919810_2/inc/hall.H @@ -0,0 +1,24 @@ +/**********************************hall V2.0 说明 ************************************************************************ +Hall模块用于获取“STC-B学习板”上hall传感器状态。hall模块共提供1个加载函数、1个应用函数,一个Hall事件:enumEventHall + (1)HallInit():hall模块初始化函数 + (2)unsigned char GetHallAct(void):获取hall事件。 + 函数返回值: + enumHallNull(无变化) + enumHallGetClose(磁场接近) + enumHallGetAway(磁场离开) + 查询一次后,事件值变成enumEventHall (仅查询一次有效) + (3)hall传感器事件: + 当Hall检测到有"磁场接近"或"磁场离开"事件时,将产生一个Hall传感器事件(enumEventHall).响应事件的用户处理函数由用户编写, 并有sys中提供的SetEventCallBack()函数设置事件响应函数. + + +编写:徐成(电话18008400450) 2021年3月15日设计 2021年3月26日修改 +*/ + +#ifndef _hall_H_ +#define _hall_H_ + +extern void HallInit(void); //加载hall模块 +extern unsigned char GetHallAct(void); //获取hall事件 +enum HallActName {enumHallNull,enumHallGetClose,enumHallGetAway}; //返回值:enumHallNull——无,enumHallGetClose——下降沿(磁场接近),enumHallGetAway——上升沿(磁场离开) + +#endif \ No newline at end of file diff --git a/1919810_2/inc/music.h b/1919810_2/inc/music.h new file mode 100644 index 0000000..0c219a9 --- /dev/null +++ b/1919810_2/inc/music.h @@ -0,0 +1,100 @@ +/********************************** music V2.0 说明 ************************************************************************ +Music模块在Beep和Displayer模块基础上再次封装,用于控制“STC-B学习板”上播放音乐。加载该模块,将同时加载Beep模块、displayer模块。music模块共提供1个music驱动函数、4个应用函数: + (1)MusicPlayerInit():驱动music模块; + (2)char PlayTone(unsigned char tone, unsigned char beatsPM ,unsigned char scale, unsigned char beats):播放音乐音阶,实现用指定音调、指定节拍率、发指定音阶、发音节拍数。 +函数参数: + tone:指定音调,有效值:0xFA、0xFB、0xFC、0xFD、0xFE、0xFF、0xF9分别对应音乐A、B、C、D、E、F、G调 + beatsPM:节拍率,即每分钟节拍数,值范围10~255拍/分钟 + scale:音乐简谱音高,1字节。 +0x00——休止符 +高4位:1——低8度音 2——中8度音 3——高8度音 +低3位:1-7对应简谱音。其它值无效。 +如:0x13表示低音3(mi) + beats:音长(节拍数),单位1/16拍。 +如:16(0x10)对应1拍,32(0x20)对应2拍,8(0x08)对应半拍...... 。 +函数返回值:enumBeepOK:调用成功 + enumBeepBusy:忙(上一音未按设定发完,或因蜂鸣器正在发音) + enumBeepFail:调用失败(音调参数tone不对,或音高编码scale不对) + (见Beep.h中定义BeepActName) + (3)SetMusic(unsigned char beatsPM, unsigned char tone, unsigned char *pt, unsigned int datasize, unsigned char display):设定或改变要播放音乐和播放参数。 +函数参数: + beatsPM:节拍率,即每分钟节拍数,值范围10~255拍/分钟,如果参数值为enumModeInvalid将不改变原beatsPM; + tone:指定音调, 有效值:0xFA、0xFB、0xFC、0xFD、0xFE、0xFF、0xF9分别对应音乐A、B、C、D、E、F、G调,参数值为enumModeInvalid或其它值将不改变原tone + *pt :指向要播放的音乐编码的首地址 。*pt 和 datasize 只有有一个参数 = enumModeInvalid,将不改变 *pt 和 datasize + datasize:要播放的音乐编码的长度(字节数) 。*pt 和 datasize 只有有一个参数 = enumModeInvalid,将不改变 *pt 和 datasize + display:Seg7和Led是否用来显示播放音乐信息,取值: + enumMscNull —— 不用 + enumMscDrvSeg7 —— 用7段数码管Seg7(显示信息) + enumMscDrvLed —— 用Led指示灯(打拍) enumMscDrvSeg7andLed —— 用Seg7 和 Led + 参数值为enumModeInvalid或其它值将不改变原display +音乐编码规则: +1,常规音乐简谱发音编码(成对出现,不可分开,中间不能插入其它编码和控制字) + 基本格式:音高(1字节),节拍数(1字节),音高,节拍,...... + 其中“音高”部分: +0x11 — 0x17 :对应低音 do、re、mi、fa、so、la、si、 0x21 — 0x27 :对应中音 do、re、mi、fa、so、la、si + 0x31 — 0x37 :对应高音 do、re、mi、fa、so、la、si + 其中“节拍数”部分: +0x01-0xFF:单位1/16拍。也即十六进制中,高4位表示整拍数,低4位表示分拍数(1/16) + 如:发音2拍: 0x20 + 发音半拍: 0x08 + 发音1拍半:0x18 + 2,音乐编码中可以插入以下控制字,用于设定音乐播放参数等(前6个也可以通过函数,用程序设定和实现): + enumMscNull : 不用 + enumMscDrvSeg7 : 用7段数码管Seg7(显示信息) + enumMscDrvLed : 用Led指示灯(打拍) + enumMscDrvSeg7andLed : 用Seg7 和 Led + enumMscSetBeatsPM : 设置节拍率, 后面再跟 节拍率(1字节) + enumMscSetTone : 设置音调, 后面再跟 音调(1字节) +0xFA 或 0xFB 或 0xFC 或 0xFD 或 0xFE 或 0xFF 或 0xF9 +分别对应音乐:A调 或B调……… + enumMscRepeatBegin : 设置音乐播放重复开始处。重复一次(暂不支持多次),暂不能嵌套(嵌套无效或可能导致不可预期结果) + enumMscRepeatEnd : 设置音乐播放重复结束处 + + (4)SetPlayerMode(unsigned char play_ctrl) :音乐播放控制函数。 + 函数参数: + play_ctrl:enumModePlay : ”播放“ + enumModePause : ”暂停“ + enumModeStop :”停止/结束“ + (其它参数无效) +所有操作在当前”音“播放完成后生效; + (5)char GetPlayerMode(void): 获取当前播放状态 + 函数返回值:(play_ctrl值) + enumModePlay : 播放状态 + enumModePause : 暂停状态 + enumModeStop : 停止/结束 +(其它功能应用型函数可根据需要设置和增加) + + +编写:徐成(电话18008400450) 2021年3月5日设计,2021年9月5日更新 +*/ + +#ifndef _music_H_ +#define _music_H_ + +extern void MusicPlayerInit(); +extern char PlayTone(unsigned char tone, unsigned char beatsPM ,unsigned char scale, unsigned char beats); + // tone: 音调。F9,FA,FB,FC,FD,FE,FF分别对应G\A\B\C\D\E\F调,其它值无效 + // beatsPM:节凑,单位:每分钟节拍数 + // scale: 音高。0x00——休止符,高4位:1——低8度音 2——中8度音 3——高8度音,低3位:1-7简谱音。其它无效 + // beats: 音长(节拍数),单位1/16拍。16(0x10)对应1拍,32(0x20)对应2拍,8(0x08)对应半拍...... +extern void SetMusic(unsigned char beatsPM, unsigned char tone, unsigned char *pt, unsigned int datasize, unsigned char display); + //可设置或改变:全部、或部分播放参数(节拍率、音调、显示方式、音乐原数据) + //其中节拍率、音调、显示方式 也可以在音乐编码中设置 +extern void SetPlayerMode(unsigned char play_ctrl); + //操作播放:enumModePlay 或 enumModePause 或 enumModeStop,分别设置音乐”播放“、”暂停“、”停止/结束“,所有操作在当前”音“播放完成后生效; +extern char GetPlayerMode(void); //获取当前播放状态 + +enum PlayerMode {enumModeInvalid=0, //播放模式非法 + enumModePlay, //播放 + enumModePause, //暂停(可恢复续放) + enumModeStop}; //停止(结束) +enum MusicKeyword {enumMscNull=0xF0, //播放音乐时,不用7段数码管、LED指示灯(显示音乐播放相关信息) + enumMscDrvSeg7, //播放音乐时, 用7段数码管 + enumMscDrvLed, //播放音乐时, 用 LED指示灯 + enumMscDrvSeg7andLed, //播放音乐时, 用7段数码管、LED指示灯 + enumMscSetBeatsPM, //音乐编码中关键字: 设置 音乐节拍 + enumMscSetTone, //音乐编码中关键字: 设置 音调 + enumMscRepeatBegin, //音乐编码中关键字: 设置 重复开始 + enumMscRepeatEnd}; //音乐编码中关键字: 设置 重复结束 + +#endif \ No newline at end of file diff --git a/1919810_2/inc/sys.H b/1919810_2/inc/sys.H new file mode 100644 index 0000000..c03d3d8 --- /dev/null +++ b/1919810_2/inc/sys.H @@ -0,0 +1,63 @@ +/******************************* sys Ver3.6 说明 ************************************************ + (1) sys.c构成STC程序基本架构。提供: + a, 系统初始化MySTC_Init(),系统调度函数MySTC_OS(),加载用户回调函数SetEventCallBack() + b, 若干可设置和触发回调函数的事件; + enumEventSys1mS : 1mS定时到 + enumEventSys10mS : 10mS定时到 + enumEventSys100mS : 100mS定时到 + enumEventSys1S : 1S定时到 + enumEventKey : 按键事件 + enumEventNav : 导航按键事件“ + enumEventHall : hall传感器事件 + enumEventVib : 振动传感器事件 + enumEventXADC : 扩展接口上新的AD值事件 + enumEventUart1Rxd : 串口1上收到一个符合格式定义的数据包事件。串口1:USB上与PC机通信 + enumEventUart2Rxd : 串口2上收到一个符合格式定义的数据包事件。串口2:485上UART、EXT上UART、或485上ModBus协议(2022年5月2日新增) + enumEventIrRxd : 红外收到一个数据包事件 + c, 获取系统运行性能评价参数 + + (2) MySTC_Init():sys初始化函数,必须执行一次。 + (3) MySTC_OS(): sys调度函数,应在while(1)循环中。 + (4) SetEventCallBack(char event, void *(user_callback)):加载"事件"用户回调函数. + (5) SysPerF GetSysPerformance(void) :获取系统运行性能评估参数 + 函数参数:无 + 函数返回值:结构 struct SysPerF。定义如下: + typedef struct //系统性能评估参数,每秒更新一次 + { unsigned long MainLoops; //SysPerformance.MainLoops 每秒主循环次数(应大于1000以上) + unsigned char PollingMisses; //SysPerformance.PollingMisses 每秒轮询丢失次数(理想值为0。如果有非0情况,说明用户程序或算法存在问题) + } SysPerF; + + (6) 补充说明: + sys.c 基本调度时间为1mS,非抢占式,要求用户程序片段,其单次循环执行时间累加起来应小于1mS。 + +编写:徐成(电话18008400450) 2021年2月26日设计,2022年5月2日更新 +*/ + +#ifndef _sys_h_ +#define _sys_h_ + +typedef struct //系统性能评估参数,每秒更新一次 + { unsigned long MainLoops; //SysPerformance.MainLoops 每秒主循环次数(应大于1000以上) + unsigned char PollingMisses; //SysPerformance.PollingMisses 每秒轮询丢失次数(理想值为0。如果有非0情况,说明用户程序或算法存在问题) + } struct_SysPerF; + +extern void MySTC_Init(); //sys初始化函数 +extern void MySTC_OS(); //sys调度函数,应在while(1)循环中 +extern void SetEventCallBack(char event, void *(user_callback)); //加载"事件"用户回调函数. +extern struct_SysPerF GetSysPerformance(void); + +enum event{enumEventSys1mS, //系统1mS事件 + enumEventSys10mS, //系统10mS事件 + enumEventSys100mS, //系统100mS事件 + enumEventSys1S, //系统1S事件 + enumEventKey, //按键事件 + enumEventHall, //hall传感器事件 + enumEventVib, //振动传感器事件 + enumEventNav, //导航按键事件“ + enumEventXADC, //扩展接口上新的AD值事件 + enumEventUart1Rxd, //串口1上收到一个符合格式定义的事件 + enumEventUart2Rxd, //串口2上收到一个符合格式定义("数据包格式"、或"ModBus协议+数据包格式")的事件。 (2022年5月2日新增) + enumEventIrRxd //红外Ir上收到一个数据包 + }; + +#endif \ No newline at end of file diff --git a/1919810_2/inc/uart1.h b/1919810_2/inc/uart1.h new file mode 100644 index 0000000..ef39ba0 --- /dev/null +++ b/1919810_2/inc/uart1.h @@ -0,0 +1,58 @@ +/**********************************Uart1串行通信模块 V2.0 说明 ************************************************************************ +Uart1模块提供Uart1模块初始化函数、3个应用函数,1个事件(enumEventRxd): +(1) Uart1Init(unsigned long band):Uart1模块初始化函数。 + 函数参数:unsigned long band定义串口1的通信波特率(单位:bps)(8个数据位、1个停止位,无奇偶校验位) + 函数返回值:无 + +(2) void SetUart1Rxd(char *RxdPt, unsigned int Nmax, char *matchhead, unsigned int matchheadsize); + 设置串口1接收参数:数据包存放位置、大小,包头匹配字符、匹配字符个数。收到符合条件的数据包时将产生enumEventRxd事件。 + 函数参数: char *RxdPt:指定接收数据包存放区(首地址) + unsigned int Nmax:接收数据包大小(字节数),最大65535。当收到的数据大于Nmax后,将被丢弃 (2022年5月2日更改) + char *matchhead: 需要匹配的数据包头(首地址) + unsigned int matchheadsize:需要匹配的字节数 + 补充说明: + Nmax=1:为单字节接收,即收到一个字节就产生enumUart1EventRxd事件(如果定义了匹配,还需满足匹配条件); + 0 < matchheadsize < Nmax:要求接收数据中连续matchheadsize个字节与*matchhead处数据完全匹配,才在收到Nmax数据时产生enumEventRxd事件; + matchheadsize = Nmax:设定接收数据包完全匹配 + matchheadsize=0 或 matchheadsize > Nmax:将不做匹配,接收到任意Nmax数据时产生enumEventRxd事件; + 在enumEventRxd事件发出后,用户回调函数返回才接收下一个数据包 (2022年5月2日更改) + 函数返回值:无 + + (3) char Uart1Print(void *pt, unsigned int num):发送数据包,非阻塞函数(即函数不等到所设定任务全部完成才返回),该函数从被调用到返回大约1uS左右时间。 + 函数参数: void *pt :指定发送数据包位置 + unsigned int num:发送数据包大小; + 函数返回值:enumTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumTxFailure:调用失败(主要原因是:串口正忙(上一数据包未发完) + 补充说明:串口上发送1个字节数据大约需要时间0.1mS~10mS(视所设定的波特率),对计算机来说,如果发送多个字节是一个很要时间才能完成的事。类似于 + 前面用蜂鸣器演奏音乐,对这类事件与程序"异步"的问题,编程时不仅要注意程序逻辑性、还有注意程序时效性。(这个问题其实总是要注意、必须要注意的) + + (4) char GetUart1TxStatus(void): 获取Uart1发送状态 + 函数返回值:enumUart1TxFree:串口1发送空闲 + enumUart1TxBusy,串口1发送正忙 + + (5) Uart1接收事件:enumEventUart1Rxd。表示收到了一个符合指定要求(数据包头匹配、数据包大小一致)的数据包。 + 补充说明:串口(1和2)上收到的两个数据包之时间间隔要求不小于1mS(原因:系统内部调度方法限制) + +补充说明: + (1) 串口1、串口2波特率可独立设置,互不影响. + (2) 串口1、串口2、红外通信可同时工作,互不影响 + (3) 串口1、串口2用法基本上完全一致,红外通信用法也基本相同。不同地方是: + a,串口1固定在USB接口上,可用于与计算机通信;而串口2可初始化在EXT扩展、或485接口上(在485接口上时仅单工工作); + b,红外通信速率固定不可变(大约相当于500~800 bps),通信时没有包头匹配功能。红外模块除通信功能外,还提供用于电器红外遥控的应用函数; + c,红外通信模块仅为单工工作。不发送时自动进入接收状态;有数据发送时自动进入发送状态,但正在接收数据包过程中不会进入发送状态。 + + +编写:徐成(电话18008400450) 2021年3月28日设计 2021年11月8日更新 +*/ + + +#ifndef _uart1_H_ +#define _uart1_H_ + +extern void Uart1Init(unsigned long band); //串口初始化,参数:波特率 +extern void SetUart1Rxd(void *RxdPt, unsigned int Nmax, void *matchhead, unsigned int matchheadsize); //设置接收条件:数据包存放位置、大小,包头匹配字符、匹配字符个数。符合条件的包将产生enumEventRxd事件 +extern char Uart1Print(void *pt, unsigned int num); //发送数据包。非阻塞函数。数据包位置、大小。返回值enumTxOK调用成功,enumTxFailure失败(串口忙,上一数据包未发完) +extern char GetUart1TxStatus(void); //获取串口1发送状态,enumUart1TxFree:串口1发送空闲, enumUart1TxBusy,串口1发送正忙 +enum Uart1ActName {enumUart1TxFree=0,enumUart1TxBusy,enumUart1TxOK,enumUart1TxFailure}; + +#endif \ No newline at end of file diff --git a/1919810_2/inc/uart2.h b/1919810_2/inc/uart2.h new file mode 100644 index 0000000..0d68121 --- /dev/null +++ b/1919810_2/inc/uart2.h @@ -0,0 +1,65 @@ +/********************************** Uart2串行通信模块 V2.0 说明 *************************************************************** +Uart2模块提供Uart2模块初始化函数、3个应用函数,1个事件(enumUart2EventRxd): +(1) Uart2Init(unsigned long band,unsigned char Uart2mode):Uart2模块初始化函数。 + 函数参数:unsigned long band:定义串口2的通信波特率(单位:bps)(固定8个数据位、1个停止位,无奇偶校验位) + unsigned char Uart2mode:定义串口2位置 + 取值:Uart2UsedforEXT —— 串口2在EXT扩展插座上(TTL标准串口) + Uart2Usedfor485 —— 串口2用于485通信(半双工。发送数据包时不能接收数据) + Uart2Usedfor485ModBus —— 串口2用于485上,ModBus协议收发 (2022年5月2日新增) +(2) void SetUart2Rxd(char *RxdPt, unsigned int Nmax, char *matchhead, unsigned int matchheadsize); + 设置串口2接收参数:数据包存放位置、大小,包头匹配字符、匹配字符个数。收到符合条件的数据包时将产生enumEventRxd事件。 + 函数参数: char *RxdPt:指定接收数据包存放区(首地址) + unsigned int Nmax:接收数据包大小(字节数),最大65535。当收到的数据大于Nmax后,将被丢弃 (2022年5月2日更改) + char *matchhead: 需要匹配的数据包头(首地址) + unsigned int matchheadsize:需要匹配的字节数 + 补充说明: + Nmax=1:为单字节接收,即收到一个字节就产生enumEventUart2Rxd事件(如果定义了匹配,还需满足匹配条件); + 0 < matchheadsize < Nmax:要求接收数据中连续matchheadsize个字节与*matchhead处数据完全匹配,才在收到Nmax数据时产生enumEventRxd事件; + matchheadsize = Nmax:设定接收数据包完全匹配 + matchheadsize=0 或 matchheadsize > Nmax:将不做匹配,接收到任意Nmax数据时产生enumEventRxd事件; + 在enumEventRxd事件发出后,用户回调函数返回才接收下一个数据包 (2022年5月2日更改) +(3) char Uart2Print(void *pt, unsigned int num):发送数据包,非阻塞函数(即函数不等到所设定任务全部完成才返回),该函数从被调用到返回大约1uS左右时间。 + 函数参数: void *pt :指定发送数据包位置 + unsigned int num:发送数据包大小; + 函数返回值:enumTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumTxFailure:调用失败(主要原因是:串口正忙(上一数据包未发完) + 补充说明:串口上发送1个字节数据大约需要时间0.1mS~10mS(视所设定的波特率),对计算机来说,如果发送多个字节是一个很要时间才能完成的事。 + 类似于前面用蜂鸣器演奏音乐,对这类事件与程序"异步"的问题,编程时不仅要注意程序逻辑性、还有注意程序时效性。(这个问题其实总是要注意、必须要注意的) +(4) char GetUart2TxStatus(void): 获取Uart2发送状态 + 函数返回值:enumUart2TxFree:串口2发送空闲 + enumUart2TxBusy,串口2发送正忙 +(5) Uart2接收事件:enumUart2EventRxd。表示收到了一个符合指定要求(数据包头匹配、数据包大小一致)的数据包。 + 当串口2工作于: Uart2UsedforEXT 或 Uart2Usedfor485 方式时, + Uart2接收事件为:同串口1性质一致,即:数据包头匹配、数据包大小一致 + 当串口2工作于: Uart2Usedfor485ModBus 方式时, (2022年5月2日新增) + Uart2接收事件为:收到一个ModBus数据帧(数据包内字节间间隔<4字节收发时间),且帧内包头内容与设定内容匹配 + 但:1,数据帧内未进行CRC校验。建议用户在回调函数中,为了验证数据包正确性,应对数据包进行CRC校验 + 2,未返回ModBus数据帧有效字节数。用户可从收到的指令类型(第2字节)及对应帧内数据(一般第5、6字节)判断帧字节数 + 补充说明:串口(1和2)上收到的两个数据包之时间间隔要求不小于1mS(原因:系统内部调度方法限制) + +补充说明: + (1) 串口1、串口2波特率可独立设置,互不影响. + (2) 串口1、串口2、红外通信可同时工作,互不影响 + (3) 串口1、串口2(除开ModBus)用法基本上完全一致,红外通信用法也基本相同。不同地方是: + a,串口1固定在USB接口上,可用于与计算机通信;而串口2可初始化在EXT扩展、或485接口上(在485接口上时仅单工工作); + b,红外通信速率固定不可变(大约相当于500~800 bps),通信时没有包头匹配功能。红外模块除通信功能外,还提供用于电器红外遥控的应用函数; + c,红外通信模块仅为单工工作。不发送时自动进入接收状态;有数据发送时自动进入发送状态,但正在接收数据包过程中不会进入发送状态。 + (4)2022年5月2日新增串口2在485接口上支持ModBus协议数据帧监测功能,使"STC-B学习板"方便实现ModBus协议的节点等功能 (2022年5月2日新增) + +编写:徐成(电话18008400450) 2021年3月28日设计 2022年5月2日更新 +*/ + + +#ifndef _uart2_H_ +#define _uart2_H_ + +extern void Uart2Init(unsigned long band,unsigned char Uart2mode); //串口2初始化,参数:波特率、串口2位置 +enum Uart2PortName {Uart2UsedforEXT,Uart2Usedfor485,Uart2Usedfor485ModBus}; // Uart2UsedforEXT —— 串口2在EXT扩展插座上(TTL标准串口) + // Uart2Usedfor485 —— 串口2用于485通信(半双工。发送数据包时不能接收数据) + // Uart2Usedfor485ModBus —— 串口2用于485上,ModBus协议收发 +extern void SetUart2Rxd(void *RxdPt, unsigned int Nmax, void *matchhead, unsigned int matchheadsize); //设置接收条件:数据包存放位置、大小,包头匹配字符、匹配字符个数。符合条件的包将产生enumUart2EventRxd事件 +extern char Uart2Print(void *pt, unsigned int num); //发送数据包。非阻塞函数。数据包位置、大小。返回值enumUart2TxOK调用成功,enumUart2TxFailure失败(串口忙,上一数据包未发完) +extern char GetUart2TxStatus(void); //获取串口2发送状态,enumUart2TxFree:串口2发送空闲, enumUart2TxBusy,串口2发送正忙 +enum Uart2ActName {enumUart2TxFree=0,enumUart2TxBusy,enumUart2TxOK,enumUart2TxFailure}; + +#endif \ No newline at end of file diff --git a/1919810_2/source/STCBSP_V3.6.LIB b/1919810_2/source/STCBSP_V3.6.LIB new file mode 100644 index 0000000000000000000000000000000000000000..bf42f13d33a4d56bc1231fd14c66ad66708b8fe2 GIT binary patch literal 61916 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 literal 0 HcmV?d00001 diff --git a/1919810_2/source/main.c b/1919810_2/source/main.c new file mode 100644 index 0000000..e754455 --- /dev/null +++ b/1919810_2/source/main.c @@ -0,0 +1,43 @@ +// This project is used for demonstrating digital tubes of BSP library. +#include "STC15F2K60S2.H" +#include "displayer.h" +#include "sys.H" + +code unsigned long SysClock = 11059200; //蹇呴』銆傚畾涔夌郴缁熷伐浣滄椂閽熼鐜(Hz)锛岀敤鎴峰繀椤讳慨鏀规垚涓庡疄闄呭伐浣滈鐜囷紙涓嬭浇鏃堕夋嫨鐨勶級涓鑷 +#ifdef _displayer_H_ //鏄剧ず妯″潡閫夌敤鏃跺繀椤汇傦紙鏁扮爜绠℃樉绀鸿瘧鐮佽〃锛岀敤鎴跺彲淇敼銆佸鍔犵瓑锛 +code char decode_table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x00, 0x08, 0x40, 0x01, 0x41, 0x48, + /* 搴忓彿: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + /* 鏄剧ず: 0 1 2 3 4 5 6 7 8 9 (鏃) 涓- 涓- 涓- 涓婁腑- 涓笅- */ + 0x3f | 0x80, 0x06 | 0x80, 0x5b | 0x80, 0x4f | 0x80, 0x66 | 0x80, 0x6d | 0x80, 0x7d | 0x80, 0x07 | 0x80, 0x7f | 0x80, 0x6f | 0x80}; +/* 甯﹀皬鏁扮偣 0 1 2 3 4 5 6 7 8 9 */ +#endif + +void switch_status() +{ + static int status; + if (status == 0) + { + SetDisplayerArea(2, 7); + Seg7Print(0, 0, 1, 1, 4, 5, 1, 4); + status = 1; + } + else + { + SetDisplayerArea(1, 7); + Seg7Print(0, 1, 9, 1, 9, 8, 1, 0); + status = 0; + } +} + +void main() +{ + DisplayerInit(); + SetDisplayerArea(0, 7); + LedPrint(0); + SetEventCallBack(enumEventSys1S, switch_status); + MySTC_Init(); + while (1) + { + MySTC_OS(); + } +} diff --git a/key/inc/Beep.h b/key/inc/Beep.h new file mode 100644 index 0000000..a95550e --- /dev/null +++ b/key/inc/Beep.h @@ -0,0 +1,28 @@ +/**********************************Beep V2.0 说明 ************************************************************************ +Beep用于控制“STC-B学习板”上无源蜂鸣器的发声。Beep模块共提供1个驱动函数、2个应用函数: + (1) BeepInit():蜂鸣器模块驱动函数 + (2) Set_Beep(unsigned int Beep_freq, unsigned char Beep_time):控制蜂鸣器发声,非阻塞型 + 函数参数: + Beep_freq:指定发声频率,单位Hz。小于10将无输出 + Beep_time:指定发声时长。发声时长=10*Beep_time (mS) ,最长 655350mS + 函数返回值:enumSetBeepOK:调用成功,enumSetBeepFail:调用失败(或因蜂鸣器正在发音) + (3) GetBeepStatus(void): 获取Beep当前状态,enmuBeepFree:空闲, enumBeepBusy ,正在发音 + (4) Beep模块使用了STC内部CCP模块1通道 + +编写:徐成(电话18008400450) 2021年3月3日设计,2021年3月26日更新 +*/ + +#ifndef _beep_H_ +#define _beep_H_ + +extern void BeepInit(); // 蜂鸣器初始化 + +extern char SetBeep(unsigned int Beep_freq, unsigned int Beep_time); // 发指定频率声音, 发声时长=10×Beep_time (mS) ,最长 655350mS + // Beep_freq < 10 Hz, 不发音 + // 函数返回 enumSetBeepOK:调用成功, enumSetBeepFail:调用失败(调用时正在发音) + +extern unsigned char GetBeepStatus(void); // 获取状态,enumBeepFree:自由, enumBeepBusy,正在发声 + +enum BeepActName {enumBeepFree=0,enumBeepBusy,enumSetBeepOK,enumSetBeepFail}; + +#endif \ No newline at end of file diff --git a/key/inc/DS1302.h b/key/inc/DS1302.h new file mode 100644 index 0000000..377b96e --- /dev/null +++ b/key/inc/DS1302.h @@ -0,0 +1,75 @@ +/**********************************DS1302 V1.1 说明 ************************************************************************ +DS1302模块用于控制“STC-B学习板”上DS1302芯片操作。 +DS1302提供RTC(实时时钟)和NVM(非易失存储器)功能(断电后,RTC和NVM是依靠纽扣电池BAT维持工作的)。其中: + RTC提供:年、月、日、星期、时、分、秒功能 + NVM提供:31 Bytes非易失存储器功能(地址为:0~30)。其中,地址为30的单元被DS1302Init()函数用于检测DS1302是否掉电,用户不能使用) +DS1302模块共提供1个驱动函数、4个应用函数: + + (1) void DS1302Init(struct_DS1302_RTC time):DS1302驱动函数。使用DS1302,需用该函数初始化和驱动一次 + 函数参数:结构struct_DS1302_RTC time + 如果DS1302掉电(初始化时检测RTC数据失效),则以参数time定义的时间初始化RTC + 函数返回值:无 + + (2) struct_DS1302_RTC RTC_Read(void):读取DS1302内部实时时钟RTC内容 + 函数参数:无 + 函数返回值:结构struct_DS1302(见结构struct_DS1302定义) + + (3) void RTC_Write(struct_DS1302_RTC time) :写DS1302内部实时时钟RTC内容 + 函数参数:结构struct_DS1302 time(见结构struct_DS1302定义) + 函数返回值:无 + + (4) unsigned char NVM_Read(unsigned char NVM_addr): 读取NVM一个指定地址内容 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值0~30(共31个单元) + 函数返回值:当函数参数正常时,返回NVM中对应单元的存储数值(1Byte) + 当函数参数错误时,返回enumDS1302_error + + (5) unsigned char NVM_Write(unsigned char NVM_addr, unsigned char NVM_data):向NVM一个指定地址写入新值 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值:0~30(共31个单元。其中,第30单元被DS1302Init()函数用于检测DS1302是否掉电,用户不能使用)) + NVM_data:待写入NVM单元的新值(1Byte) + 函数返回值:当函数参数正常时,返回enumDS1302_OK + 当函数参数错误时,返回enumDS1302_error + +结构struct_DS1302_RTC定义:(参见DS1302Z数据手册) +typedef struct + { unsigned char second; //秒(BCD码,以下均为BCD码) + unsigned char minute; //分 + unsigned char hour; //时 + unsigned char day; //日 + unsigned char month; //月 + unsigned char week; //星期 + unsigned char year; //年 + } struct_DS1302_RTC; + +关于DS1302内部非易失性存储器补充说明: + DS1302提供的非易失性存储器为低功耗RAM结构,靠纽扣电池保持掉电后其存储内容不变。 + 与M24C01区别:容量小(仅31字节),但无”写“寿命问题,且写周期很短(可忽略:即两次写操作之间无需等待); + 读、写DS1302内部NVM每一个字节均需要花费一定操作时间(数十uS); + 仅在需要时使用以上读或写函数读写需要的特定字节内容,应避免对其进行无效、大量、重复操作! + +编写:徐成(电话18008400450) 2021年8月5日设计,2021年8月15日改进 +*/ + +#ifndef _DS1302_H_ +#define _DS1302_H_ + +typedef struct + { unsigned char second; //秒(BCD码,以下均为BCD码) + unsigned char minute; //分 + unsigned char hour; //时 + unsigned char day; //日 + unsigned char month; //月 + unsigned char week; //星期 + unsigned char year; //年 + } struct_DS1302_RTC; + +extern void DS1302Init(struct_DS1302_RTC time); //DS1302初始化 +extern struct_DS1302_RTC RTC_Read(void); //读RTC(读RTC时钟内容) +extern void RTC_Write(struct_DS1302_RTC time); //写RTC(校对RTC时钟) +extern unsigned char NVM_Read(unsigned char NVM_addr); //读NVM(读DS1302中的非易失存储单元内容) +extern unsigned char NVM_Write(unsigned char NVM_addr, unsigned char NVM_data); //写NVM(写DS1302中的非易失存储单元) + +enum DS1302name {enumDS1302_OK,enumDS1302_error}; + +#endif \ No newline at end of file diff --git a/key/inc/EXT.h b/key/inc/EXT.h new file mode 100644 index 0000000..65b8b87 --- /dev/null +++ b/key/inc/EXT.h @@ -0,0 +1,64 @@ +/********************************** EXT V1.0 说明 *********************************************** + +EXT模块用于控制“STC-B学习板”上扩展接口EXT上相关操作。 +EXT模块根据应用需要,在外接相应模块或部件后,可实现多种相应功能。这里提供部分应用驱动和API函数。 +EXT模块这里提供1个驱动函数和若干个应用层API函数。 +EXT模块的API函数不是同时有效的,而是根据初始化函数参数不同而分别有效。 + + (1) void EXTInit(char EXTfunction):EXT初始化函数。 + 函数参数:EXTfunction。定义EXT接口功能 + EXTfunction 取值:enumEXTWeight(秤重:由HX710、HX711组成的电子秤) + enumEXTPWM (脉宽调制:可用于控制直流电机正反转、速度,灯亮度等) + enumEXTDecode(增量式计数) + enumEXTUltraSonic (超声波测距) + 函数返回值:无 + 注意:当EXT扩展接口用于串口2时(TTL Uart,可用于串行通信、蓝牙模块连接等),在使用Uart2Init()函数初始化EXT后,不要再使用EXTInit()函数,以免引起功能冲突 + + (2)API函数 + (a) 电子秤。当EXTInit(char EXTfunction)使用enumEXTWeight参数时,GetWeight函数有效。 + int GetWeight(void) //获取电子秤ADC秤重数据(16bit,带符号整数。未清零、未标定。参见HX710、HX711数据手册(高16bit)) + + (b) PWM脉宽调制输出。当EXTInit(char EXTfunction)使用enumEXTPWM参数时,SetPWM函数有效。 + void SetPWM(unsigned char PWM1, unsigned char freq1, unsigned char PWM2, unsigned char freq2); + //设置EXT上输出PWM(参数PWM为占空比(输出高电平时间的比例):0~100,单位%)。freqx为频率:1~255Hz) + //实际频率 = 1000/int(1000/freqx)。即:1000/i=4,5,6...1000,或250,200,167,143,125,111,100,91,83...1 + //可用于控制直流电机正反转、转速(配合H型桥式电路),灯亮度,等 + + (c) 旋转编码器、或增量式编码器。当EXTInit(char EXTfunction)使用enumEXTDecode参数时,GetDecode函数有效。 + int GetDecode(void); //获取增量编码器增量值(相对上次读取后的新增量) + + (d) 超声波测距。当EXTInit(char EXTfunction)使用enumEXTUltraSonic参数时,GetUltraSonic函数有效。 + int GetUltraSonic(void); //获取超声波测距值(每秒5次测量,返回值单位:cm) + + (e) RFID读卡(暂缓) + (g) (蓝牙、串口)见串口2 + (h) (气敏、数据采集、电子尺、额温)见ADC +编程注意事项: + + +编写:徐成(电话18008400450) 2021年8月24日设计 +*/ + +#ifndef _EXT_H_ +#define _EXT_H_ + +extern void EXTInit(char EXTfunction); //扩展接口初始化 +enum EXTname {enumEXTWeight //电子秤 + ,enumEXTPWM, //PWM,控制直流电机转动方向、快慢 + ,enumEXTDecode //增量式计数(旋转编码器) + ,enumEXTUltraSonic //超声波测距 + //串口2,蓝牙:见uart2模块 + //气敏、数据采集、电子尺、额温枪等:见ADC + }; +extern int GetWeight(void); //获取电子秤ADC秤重数据(HX710、HX711输出高16bit,带符号数整数。未清零、未标定) +extern int GetDecode(void); //获取增量编码器增量值(相对上次读取后的新增量) +extern int GetUltraSonic(void); //获取超声波测距值(每秒5次测量,返回值单位:cm) +extern void SetPWM(unsigned char PWM1, unsigned char freq1, unsigned char PWM2, unsigned char freq2); + //设置EXT上输出PWM(参数PWM为占空比(输出高电平时间的比例):0~100,单位%)。freqx为频率:1~255Hz) + //实际频率 = 1000/int(1000/freqx)。即:1000/i=4,5,6...1000,或250,200,167,143,125,111,100,91,83...1 + //可用于控制直流电机正反转、转速(配合H型桥式电路),灯亮度,等 + + + + +#endif \ No newline at end of file diff --git a/key/inc/FM_Radio.h b/key/inc/FM_Radio.h new file mode 100644 index 0000000..3b15155 --- /dev/null +++ b/key/inc/FM_Radio.h @@ -0,0 +1,49 @@ +/********************************** FMRadio V1.1 说明 ************************************************************************ +FMRadio模块用于控制“STC-B学习板”上FM收音机操作。 +FMRadio模块模块共提供1个初始化函数、2个应用函数 + + (1) void FMRadioInit(struct_FMRadio FMRadio); //收音机模块初始化函数。该函数只执行一次。初始化后,以下各应用函数方可正确使用。 + 函数参数:FMRadio (见结构struct_FMRadio定义) + 函数返回值:无 + + (2) void SetFMRadio(struct_FMRadio FMRadio); //设置FM收音机控制参数。 + 函数参数:FMRadio (见结构struct_FMRadio定义) + 函数返回值:无 + + (3) struct_FMRadio GetFMRadio(void); //获取当前FM收音机参数。 + 函数参数:无 + 函数返回值:返回FM控制模型数据(见结构struct_FMRadio定义) + +结构struct_FMRadio定义: + typedef struct //FM收音机控制模型 + { unsigned int frequency; // FM收音机收音频率 (frequency参数范围:887~1080。单位:0.1MHz,如887代表88.7MHz)。错误参数或参数与当前值无变化,将忽略 + unsigned char volume; // FM收音机音量 (volume参数范围:0~15。0为最小音量)。错误参数或参数与当前值无变化,将忽略 + unsigned char GP1; // FM指示灯1。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP2; // FM指示灯2。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP3; // FM指示灯3。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + } struct_FMRadio; + +编程注意事项: + 1,本版本暂未输出调谐、自动搜索、电台信号等控制和状态信息,因此,暂不能完成自动搜索电台等收音机功能。 + 2,FM收音机借用USB转串口模块(CH340)时钟(硬件设计原因),需要连接USB接口(供电、通信)到USB主设备,CH340方有时钟产生和输出。 + 故STC-B学习板的USB接口需要连接到一个USB主设备方可收音,仅USB供电时(如USB充电宝、或计算机休眠时的USB接口),FM收音机可能不工作 + +编写:徐成(电话18008400450) 2021年8月10日设计,2021年8月16日改进 +*/ + +#ifndef _FM_Radio_H_ +#define _FM_Radio_H_ + +typedef struct //FM收音机控制模型 + { unsigned int frequency; // FM收音机收音频率 (frequency参数范围:887~1080。单位:0.1MHz,如887代表88.7MHz)。错误参数或参数与当前值无变化,将忽略 + unsigned char volume; // FM收音机音量 (volume参数范围:0~15。0为最小音量)。错误参数或参数与当前值无变化,将忽略 + unsigned char GP1; // FM指示灯1。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP2; // FM指示灯2。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + unsigned char GP3; // FM指示灯3。 =0 输出低,GP1亮; !=0 输出高,GP1灭 + } struct_FMRadio; + +extern void FMRadioInit(struct_FMRadio FMRadio); //收音机模块初始化函数。输入FM控制模型数据,无返回值。初始化后,以下各应用函数方可正确使用 +extern void SetFMRadio(struct_FMRadio FMRadio); //设置FM收音机控制参数。输入FM控制模型数据,无返回值。 +extern struct_FMRadio GetFMRadio(void); //获取当前FM收音机参数。无输入参数,返回FM控制模型数据 + +#endif \ No newline at end of file diff --git a/key/inc/IR.h b/key/inc/IR.h new file mode 100644 index 0000000..2ae2d39 --- /dev/null +++ b/key/inc/IR.h @@ -0,0 +1,85 @@ +/********************************** IR V3.5a 说明 *********************************************** + +IR模块用于控制“STC-B学习板”上红外发送与接收控制,支持PWM、PPM红外编码协议的发送,PWM红外编码的接收,可用于制作红外遥控器、红外通信等。 +IR模块提供1个驱动函数、5个API应用函数、1个红外接收事件(enumEventIrRxd:红外Ir上收到一个数据包)。 +IR模块已不与串口通信(uart和uart2)冲突,可用与它们同时工作。(以前冲突) + + (1) void IrInit(unsigned char Protocol):IR模块初始化函数。 + 函数参数:unsigned char Protocol,定义红外协议。 + Protocol 暂仅提供取值:NEC_R05d(定义红外协议基本时间片时长 = 13.1*Protocol uS) + 函数返回值:无 + + (2) char IrTxdSet(unsigned char *pt,unsigned char num):以自由编码方式控制IR发送:可用于编写任意编码协议的红外发送,如各种电器红外遥控器等 + 函数参数:unsigned char *pt,指向待发送红外编码数据的首地址。编码规则如下: + 码1红外发送时长,码1红外发送停止时长 //单位:协议基本时间片的个数值,最大255。如当协议基本时间片为0.56mS时, + ,码2红外发送时长,码2红外发送停止时长 //如当协议基本时间片为0.56mS时,数值1代表0.56mS时长,3代表1.68mS时长,...... + ...... + ...... + ,码n红外发送时长,码n红外发送停止时长 + unsigned char num,待发送红外编码数据的大小(字节数) + 函数返回值:enumIrTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumIrTxFailure:调用失败(主要原因是:红外发送正忙(上一数据包未发完)、或红外正在接收一个数据包进行中 + (同IrPrint()函数返回值) + 补充说明:参照该格式定义和电器遥控器编码格式,可实现任何38KHz红外遥控器功能。 + + (3) char IrPrint(void *pt, unsigned char num)://以NEC的PWM编码方式发送数据,可用于符合该函数发送格式的部分电器遥控器;与GetIrRxNum()、SetIrRxd()配合,可进行红外双机通信;等 + //红外发送数据格式为:引导码:发(16*基本时间片),停(8*基本时间片)。0.56mS时:发9mS、停4.5mS + 数据编码:"0" -- 发(1*基本时间片),停(1*基本时间片) + "1" -- 发(1*基本时间片),停(3*基本时间片) + 先发高位、后发低位 + 结束码:发(1*基本时间片),停(1*基本时间片) + //非阻塞函数,该函数从被调用到返回大约1uS左右时间,但所指定的数据经红外发送完毕则需要较长时间(每字节大约需要10mS量级时间)。 + //IrPrint()函数用法完全类似与uart模块的Uart1Print()和Uart2Print()用法,(仅num参数为unsigned char,可参照使用) + 函数参数:void *pt :指定发送数据包位置(数据包不含引导码、结束码信息,仅待发送的有效数据) + unsigned char num:发送数据包大小(字节数,不含引导码、结束码) + 函数返回值:enumIrTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumIrTxFailure:调用失败(主要原因是:红外发送正忙(上一数据包未发完)、或红外正在接收一个数据包进行中 + (同IrTxdSet()函数返回值) + + (4) void SetIrRxd(void *RxdPt,unsigned char RxdNmax):设置红外接收数据包存放位置、每个数据包最大字节数。 + 收到一个数据包(至少1字节数据)时将产生numEventIrRxd事件。与它机IrPrint()函数配合,可实现红外数据通信 + 函数参数: void char *RxdPt:指定接收数据包存放区(首地址) + unsigned char RxdNmax:指定每个数据包接收最大字节数。当收到的数据大于Nmax后,将被丢弃。 + 函数返回值:无 + + (5) unsigned char GetIrRxNum(void):获取收到的红外接收数据包实际字节数。与SetIrRxd()配合,可实现红外数据包接收。(它机应使用IrPrint()函数发送数据包) + 返回取值 <= Ir接收缓冲区最大字节数(RxdNmax定义)。如果实际红外数据包字节数大于RxdNmax,收到的多余字节数将不被存储(也不进行计数) + 函数参数: 无 + 函数返回值:红外接收数据包大小(字节数)。 + 当收到一个数据包的numEventIrRxd事件产生后,可用该函数获取红外接收数据包的大小(字节数)。其它时间访问,其值不确定 + + (6) char GetIrStatus(void): 获取Ir状态 + 函数返回值:enumIrFree:红外空闲 + enumIrBusy:红外正忙(正在发送数据包,或正在接收数据包) + + (7) 红外接收事件enumEventIrRxd:红外Ir上收到一个符合格式的数据包(红外格式见IrPrint()函数说明)。 + 如果接收数据包实际字节数大于Ir接收缓冲区最大字节数(RxdNmax定义),也在收到数据包结束符后产生enumEventIrRxd事件 + +补充说明: + (1) 串口1、串口2波特率可独立设置,互不影响. + (2) 串口1、串口2、红外通信可同时工作,互不影响 + (3) 串口1、串口2用法基本上完全一致,红外通信用法也基本相同。不同地方是: + a,串口1固定在USB接口上,可用于与计算机通信;而串口2可初始化在EXT扩展、或485接口上(在485接口上时仅单工工作); + b,红外通信速率固定不可变(大约相当于500~800 bps),通信时没有包头匹配功能。红外模块除通信功能外,还提供用于电器红外遥控的应用函数; + c,红外通信模块仅为单工工作。不发送时自动进入接收状态;有数据发送时自动进入发送状态,但正在接收数据包过程中不会进入发送状态。 + +编写:徐成(电话18008400450) 2021年8月24日设计,2021年11月5日更新 +*/ + +#ifndef _IR_H_ +#define _IR_H_ + +extern void IrInit(unsigned char Protocol); //IR模块初始化。参数:定义红外IR基本周期 +enum IrProtocalName {NEC_R05d=43}; //定义红外IR协议基本周期 = 43*1000/76 = 566 (uS) + +extern char IrTxdSet(unsigned char *pt,unsigned char num); //以自由编码方式控制IR发送:可用于编写任意编码协议的红外发送,如各种电器红外遥控器等 +extern char IrPrint(void *pt, unsigned char num); //以NEC的PWM编码方式发送数据,可用于符合该函数发送格式的部分电器遥控器;与SetIrRxd()配合,可进行红外双机通信;等 +extern void SetIrRxd(void *RxdPt,unsigned char RxdNmax); //设置红外接收数据包存放位置、每个数据包最大字节数。收到一个数据包(至少1字节数据)时将产生numEventIrRxd事件。与它机IrPrint()函数配合,可实现红外数据通信 +extern unsigned char GetIrRxNum(void); //当收到一个数据包的numEventIrRxd事件产生后,可用该函数获取红外接收数据包的大小(字节数)。其它时间访问,其值不确定 +extern char GetIrStatus(void); //获取Ir状态,enumIrFree:红外接口空闲, enumIrBusy,红外接口正忙 + +enum IrActName {enumIrFree=0 //红外发送空闲 + ,enumIrBusy // 忙 + ,enumIrTxOK // 发送成功 + ,enumIrTxFailure}; // 发送失败(正忙) +#endif \ No newline at end of file diff --git a/key/inc/Key.H b/key/inc/Key.H new file mode 100644 index 0000000..4902f4a --- /dev/null +++ b/key/inc/Key.H @@ -0,0 +1,34 @@ +/**********************************key V2.0 璇存槑 ************************************************************************ +Key妯″潡鐢ㄤ簬鑾峰彇鈥淪TC-B瀛︿範鏉库濅笂涓変釜鎸夐敭鐨勭姸鎬併傛彁渚涙寜閿ā鍧楀姞杞藉拰涓涓簲鐢ㄥ嚱鏁,涓涓滄寜閿簨浠讹細enumEventKey锛 + (1) KeyInit()锛氭寜閿ā鍧楀姞杞藉嚱鏁帮紱 + (2) char GetKeyAct(char Key)锛氳幏鍙栨寜閿姸鎬併 + 鍑芥暟鍙傛暟锛欿ey锛屾寚瀹氳鑾峰彇鐘舵佺殑鎸夐敭銆侹ey鍙栧硷細 + enumKey1 + enumKey2 + enumKey3 +锛堝綋鍙傛暟鍙栧艰秴鍑烘湁鏁堣寖鍥达紝鍑芥暟灏嗚繑鍥瀎ail锛 + 鍑芥暟杩斿洖鍊硷細 + enumKeyNull锛堟棤鎸夐敭鍔ㄤ綔锛 + enumKeyPress锛堟寜涓嬶級 + enumKeyRelease锛堟姮璧凤級 + enumKeyFail锛堝け璐ワ級 + 杩斿洖鍊兼槸缁忚繃澶氭妫娴嬫寜閿疄鏃剁姸鎬佸拰缁熻妫娴嬬粨鏋滃悗锛堣蒋浠舵秷鎶栵級鐨勬湁鏁堜簨浠躲 + 姣忎釜鎸夐敭鏌ヨ涓娆″悗,浜嬩欢鍊煎彉鎴恊numKeyNull銆備簨浠跺间粎鏌ヨ涓娆℃湁鏁堛 + (3) 鎸夐敭浜嬩欢锛歟numEventKey + 褰撲笁涓寜閿紙enumKey1,enumKey2,enumKey3锛変腑浠绘剰涓涓寜閿湁鈥濇寜涓嬧滄垨鈥濇姮璧封滃姩浣滄椂锛屽皢浜х敓涓涓濇寜閿簨浠垛滐紝鍝嶅簲鎸夐敭浜嬩欢鐨勭敤鎴峰鐞嗗嚱鏁扮敱鐢ㄦ埛缂栧啓,骞舵湁sys涓彁渚涚殑SetEventCallBack鍑芥暟璁剧疆. + +琛ュ厖璇存槑锛氬鏋滃惎鐢ㄤ簡ADC妯″潡锛屾寜閿3锛圞ey3锛変换浣曟搷浣滃湪鏈ā鍧椾笉鍙娴嬪埌鍜屾湁浠讳綍淇℃伅鍙嶅簲锛岃繖鏃舵寜閿3锛圞ey3锛変换浣曟搷浣滃皢鍦ˋDC妯″潡涓娴嬪拰鍙嶅簲銆備娇鐢ㄦ柟娉曠浉鍚岋紝鍏蜂綋瑙丄DC妯″潡璇存槑銆 + +缂栧啓锛氬緪鎴愶紙鐢佃瘽18008400450锛 2021骞3鏈5鏃ヨ璁★紝2021骞8鏈26鏃ユ洿鏂 +*/ + +#ifndef _key_H_ +#define _key_H_ + +extern void KeyInit(); +extern unsigned char GetKeyAct(char Key) ; //鑾峰彇鎸夐敭enumKey1,enumKey2,enumKey3浜嬩欢 + //杩斿洖鍊硷細enumKeyNull鈥斺旀棤锛宔numKeyPress鈥斺斾笅闄嶆部锛宔numKeyRelease鈥斺斾笂鍗囨部锛宔numKeyFail鈥斺旈敊璇 +enum KeyName {enumKey1,enumKey2,enumKey3}; //鎸夐敭鍚 +enum KeyActName {enumKeyNull,enumKeyPress,enumKeyRelease,enumKeyFail}; //鎸夐敭鍔ㄤ綔鍚 + +#endif \ No newline at end of file diff --git a/key/inc/M24C02.h b/key/inc/M24C02.h new file mode 100644 index 0000000..fc135cd --- /dev/null +++ b/key/inc/M24C02.h @@ -0,0 +1,32 @@ +/**********************************M24C02 V1.0 说明 ************************************************************************ +M24C02模块用于控制“STC-B学习板”上IIC接口的非易失存储器(NVM)M24C02芯片操作。 +M24C02提供2K bits(256 Bytes)非易失存储器(NVM)功能(非易失存储器单元地址为:00~0xff)。 +M24C0402模块共提供2个应用函数(本模块不需要初始化) + + (1) unsigned char M24C02_Read(unsigned char NVM_addr): 读取M24C02一个指定地址内容 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值00~0xff(共256个单元) + 函数返回值:返回M24C02中对应单元的存储数值(1Byte) + + (2) void M24C02_Write(unsigned char NVM_addr, unsigned char NVM_data):向M24C02一个指定地址写入新值 + 函数参数: + NVM_addr:指定非易失存储单元地址,有效值:00~0xff(共256个单元) + NVM_data:待写入M24C02单元的新值(1Byte) + +补充说明: + M24C02为非易失性存储器,其主要特点是:存储的内容在断电后能继续保存,一般用于保存断电需保留的工作系统参数; + 但读、写M24C02内部每一个字节均需要花费一定时间(每次读写操作大约数十uS,写周期为5~10mS),且有”写“寿命限制(每一单元大约”写“寿命为10万次量级寿命); + 与DS1302内部NVM区别:容量大(M24C02提供256字节,M24CXX系列最大可提供64K字节),但有“写”寿命限制(一般为数十万次“写”寿命“,且写周期长(5~10mS) + 因此,两次写操作之间需间隔5~10mS以上; + 仅在需要时使用以上读或写函数读写需要的特定字节内容,应避免对其进行无效、大量、重复操作! + +编写:徐成(电话18008400450) 2021年8月8日设计 +*/ + +#ifndef _M24C02_H_ +#define _M24C02_H_ + +extern unsigned char M24C02_Read(unsigned char NVM_addr); //读NVM(读M24C02中的非易失存储单元内容) +extern void M24C02_Write(unsigned char NVM_addr, unsigned char NVM_data); //写NVM(写M24C02中的非易失存储单元) + +#endif \ No newline at end of file diff --git a/key/inc/STC15F2K60S2.H b/key/inc/STC15F2K60S2.H new file mode 100644 index 0000000..96d807b --- /dev/null +++ b/key/inc/STC15F2K60S2.H @@ -0,0 +1,237 @@ +#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的捕捉/比较寄存器高字节 + +///////////////////////////////////////////////// + +#endif + diff --git a/key/inc/StepMotor.h b/key/inc/StepMotor.h new file mode 100644 index 0000000..6bbd1e8 --- /dev/null +++ b/key/inc/StepMotor.h @@ -0,0 +1,50 @@ +/**********************************StepMotor 说明 ************************************************************************ +StepMotor用于STC-B板控制步进电机。共提供1个驱动函数、3个应用函数: + (1) StepMotorInit():步进电机模块驱动函数 + (2) SetStepMotor(char StepMotor,unsigned char speed ,int steps ) 指定步进电机、按指定转动速度、转动指定步 + 函数参数:StepMotor 指定步进电机,取值(enum StepMotorName中定义) + enumStepMotor1: SM 接口上的步进电机 + enumStepMotor2: 此时,用L0~L3四个LED模拟一个4相步进电机 + enumStepMotor3: 此时,用L4~L7四个LED模拟一个4相步进电机 + speed 步进电机转动速度(0~255),单位:步/S。 (实际每步时间=int(1000mS/speed) mS),与设置速度可能存在一定误差 + steps 步进电机转动步数(-32768~32767),负值表示反转 + 函数返回:enumSetStepMotorOK: 调用成功(enum StepMotorActName中定义) + enumSetStepMotorFail:调用失败(电机名不在指定范围,或speed=0,或调用时正在转动) + (3)EmStop(char StepMotor) 紧急停止指定步进电机转动 + 函数参数:StepMotor 指定步进电机。函数参数不对将返回0值。 + 函数返回:剩余未转完的步数 + (4)GetStepMotorStatus(char StepMotor) 获取指定步进电机状态 + 函数参数:StepMotor 指定步进电机 + 函数返回:enumStepMotorFree:自由(enum StepMotorActName中定义) + enumStepMotorBusy,忙(正在转动) + enumSetStepMotorFail:调用失败(步进电机名不在指定范围) + +编写:徐成(电话18008400450) 2021年4月16日设计,2021年4月18日更新 +*/ + +#ifndef _StepMotor_H_ +#define _StepMotor_H_ + +extern void StepMotorInit(); // 步进电机模块初始化 +extern char SetStepMotor(char StepMotor,unsigned char speed ,int steps ); // 指定步进电机、按指定转动速度、转动指定步 + // 函数参数:StepMotor 指定步进电机,取值(enum StepMotorName中定义) + // enumStepMotor1: SM 接口上的步进电机 + // enumStepMotor2: 此时,用L0~L3四个LED模拟一个4相步进电机 + // enumStepMotor3: 此时,用L4~L7四个LED模拟一个4相步进电机 + // speed 步进电机转动速度(0~255),单位:步/S (实际每步时间=int(1000mS/speed) mS),与设置速度可能存在一定误差 + // steps 步进电机转动步数(-32768~32767),负值表示反转 + // 函数返回: + // enumSetStepMotorOK:调用成功 + // enumSetStepMotorFail:调用失败(电机名不在指定范围,或speed=0,或调用时正在转动) +extern int EmStop(char StepMotor); // 紧急停止指定步进电机转动 + // 函数参数:StepMotor 指定步进电机(函数参数不对将返回0值) + // 函数返回:剩余未转完的步数 +extern unsigned char GetStepMotorStatus(char StepMotor); // 获取指定步进电机状态 + // 函数参数:StepMotor 指定步进电机 + // 函数返回:enumStepMotorFree:自由 + // enumStepMotorBusy,忙(正在转动) + // enumSetStepMotorFail:调用失败(步进电机名不在指定范围) +enum StepMotorName {enumStepMotor1=0,enumStepMotor2,enumStepMotor3}; +enum StepMotorActName {enumStepMotorFree,enumStepMotorBusy,enumSetStepMotorOK,enumSetStepMotorFail}; + +#endif \ No newline at end of file diff --git a/key/inc/Vib.h b/key/inc/Vib.h new file mode 100644 index 0000000..ff8a281 --- /dev/null +++ b/key/inc/Vib.h @@ -0,0 +1,21 @@ +/**********************************振动传感器SV V2.0 说明 ************************************************************************ +SV用于获取"STC-B学习板"上Vib传感器状态.提供一个模块加载函数和一个应用函数,一个Vib事件enumEventVib: + (1) VibInit():振动传感器Vib模块初始化函数; + (2) char GetVibAct():获取Vib事件。 + 函数返回值:返回当前Vib传感器事件,返回值:enumVibNull——无,enumVibQuake——发生过振动 + 查询一次后,事件值变成 enumVibNull (仅查询一次有效) + (3) Vib传感器事件enumEventVib: + 当Vib检测到有”振动“事件时,将产生一个”振动事件“,响应事件的用户处理函数由用户编写, + 并有sys中提供的SetEventCallBack()函数设置. + +编写:徐成(电话18008400450) 2021年3月5日设计,2021年3月26日更新 +*/ + +#ifndef _Vib_H_ +#define _Vib_H_ + +extern void VibInit(); +extern unsigned char GetVibAct(void) reentrant; //获取Vib事件 +enum VibActName {enumVibNull,enumVibQuake}; //返回值:enuVibNull——无,enuVibQuake——发生过振动 + +#endif \ No newline at end of file diff --git a/key/inc/adc.h b/key/inc/adc.h new file mode 100644 index 0000000..eaf1a2c --- /dev/null +++ b/key/inc/adc.h @@ -0,0 +1,79 @@ +/**********************************ADC V3.5a 说明 ************************************************************************ +ADC模块用于“STC-B学习板”上与ADC相关电路:温度Rt、光照Rop、导航按键Nav、扩展接口EXT上的ADC转换。提供ADC模块初始化函数、2个应用函数,2个事件: + (1) AdcInit(char ADCsel):ADC模块初始化函数; + 函数参数: ADCsel选择扩展接口EXT是否用作ADC功能,取值: + ADCincEXT : 含对扩展接口EXT设置ADC功能(EXT上P1.0、P1.1不可作数字IO功能使用) + ADCexpEXT : 不含对扩展接口EXT设置ADC功能(EXT上P1.0、P1.1可作数字IO功能使用) + (2) struct_ADC GetADC():获取ADC值。 + 函数参数:无 + 函数返回值:返回数据结构 struct_ADC。 + 数据结构定义: + typedef struct //ADC转换结果 + { unsigned int EXT_P10; // 扩展接口EXT上P1.0脚ADC(10bit) + unsigned int EXT_P11; // 扩展接口EXT上P1.1脚ADC(10bit) + unsigned int Rt; // 热敏电阻上ADC(10bit) + unsigned int Rop; // 光敏电阻上ADC(10bit) + unsigned int Nav; // 导航按键上ADC(10bit) + } struct_ADC; + +说明1:每个数字表示 VCC/1024(单位:V),其中VCC为电路板供电电压(USB接口一般为5V左右) +说明2:对于导航按键,下面GetAdcNavAct函数输出消抖后导航按键事件和状态,更方便使用; + + (3) char GetAdcNavAct(char Nav_button):获取导航按键(包含K3)状态 + 函数参数:Nav_button:指定要获取状态的导航按键。取值: + enumAdcNavKey3(K3键), + enumAdcNavKeyRight(右按), + enumAdcNavKeyDown(下按), + enumAdcNavKeyCenter(中心按) + enumAdcNavKeyLeft(左按), + enumAdcNavKeyUp(上按). +(当参数取值不在有效范围,函数将返回enumKeyFail) + 函数返回值:返回当前按键事件,返回值:(同Key模块GetAdcKeyAct()返回值) + enumKeyNull(无按键动作), + enumKeyPress(按下), + enumKeyRelease(抬起), + enumKeyFail(失败) + 返回值是经过多次检测按键实时状态和统计检测结果后(软件消抖)的有效事件。 + 每个按键查询一次后,事件值变成 enumKeyNull (仅查询一次有效) + (4) 导航按键事件“:enumEventNav + 当导航按键5个方向或按键K3有任意”按下“或”抬起“动作时,将产生一个”导航按键事件“enumEventNav。响应导航按键事件的用户回调函数由用户编写,并由sys提供的SetEventCallBack()函数设置响应函数. + (5) 扩展接口EXT上P1.0、P1.1两个端口有新的AD值事件“:enumEventXADC + 当ADC模块对P1.0、P1.1进行ADC转换,获得了它们新的ADC结果时,将产生enumEventXADC事件,通知用户进行处理。响应enumEventXADC事件的用户回调函数由用户编写,并有sys提供的SetEventCallBack()函数设置响应函数. + ADC模块对P1.0、P1.1进行ADC转换速度为3mS,也即每3mS或每秒钟333次转换. + (6) 补充说明: + a:对EXT上P1.0、P1.0的转换速度为3mS,也即每秒钟提供333次转换结果,提供了有新转换结果事件:enumEventXADC,方便用户处理 +b:对于Rt、Rop,转换速度为9mS,也即每秒钟提供111次转换结果。没有提供相应“事件”,用户随时用函数GetAdcResult()查询和使用 + c:对导航按键进行了软件消抖处理,最快可支持导航按键每秒12次操作速度,提供了导航按键发生了操作事件:enumEventNav + d:由于导航按键与K3键共用了单片机同一个端口(P1.7),启用ADC模块后,P1.7口IO功能失效,只能用GetAdcNavAct(char Nav_button)函数获取K3按键的事件或状态。 + e: STC-B板上Rt型号为:10K/3950 NTC热敏电阻,光敏电阻Rop型号为:GL5516. 它们的ADC值与温度、光照强度关系请参阅它们的数据手册与STC-B电路图进行换算。 + + +编写:徐成(电话18008400450) 2021年3月25日设计,2021年8月30日修改 +*/ + +#ifndef _adc_H_ +#define _adc_H_ + +#define ADCincEXT 0x9B +#define ADCexpEXT 0x98 + +typedef struct //ADC转换结果 + { unsigned int EXT_P10; // 扩展接口EXT上P1.0脚ADC + unsigned int EXT_P11; // 扩展接口EXT上P1.1脚ADC + unsigned int Rt; // 热敏电阻上ADC + unsigned int Rop; // 光敏电阻上ADC + unsigned int Nav; // 导航按键上ADC + } struct_ADC; + +extern void AdcInit(char ADCsel); + +extern struct_ADC GetADC(); +extern unsigned char GetAdcNavAct(char Nav_button); //获取导航按键5个方向(右、下、中心、左、上)操作,以及按键K3操作的事件 + //返回值:enuKeyNull(无按键动作),enuKeyPress(按下),enuKeyRelease(抬起),enuKeyFail(失败) +enum KN_name {enumAdcNavKey3=0, //导航按键:按键K3 + enumAdcNavKeyRight, //导航按键:右 + enumAdcNavKeyDown, //导航按键:下 + enumAdcNavKeyCenter, //导航按键:中心 + enumAdcNavKeyLeft, //导航按键:左 + enumAdcNavKeyUp}; //导航按键:上 +#endif \ No newline at end of file diff --git a/key/inc/displayer.h b/key/inc/displayer.h new file mode 100644 index 0000000..7888dcc --- /dev/null +++ b/key/inc/displayer.h @@ -0,0 +1,26 @@ +/**********************************display V2.0 璇存槑 ************************************************************************ +displayer鐢ㄤ簬鎺у埗鈥淪TC-B瀛︿範鏉库濅笂8涓7娈垫暟鐮佺锛圫eg7锛夊拰8涓寚绀虹伅锛圠ed锛夊伐浣.鎻愪緵鏄剧ず妯″潡鍔犺浇鍜屼笁涓簲鐢ㄥ嚱鏁帮細 + + (1) displayerInit()锛氭樉绀烘ā鍧楀姞杞藉嚱鏁帮紱 + + (2) SetDisplayerArea(char Begin_of_scan,char Ending_of_Scan)锛氳缃甃ED鍚敤鍖哄煙銆8涓暟鐮佺浠庡乏鑷冲彸缂栧彿鍒嗗埆涓0鈥斺7锛屽嚱鏁板弬鏁 + Begin_of_scan璁惧畾鍚敤鏁扮爜绠¤捣濮嬬紪鍙凤紝Ending_of_Scan涓虹粨鏉熺紪鍙枫傝瀹氳寖鍥村唴鐨勬暟鐮佺鎵嶅伐浣滃拰鏄剧ず銆 + 娉細姝e父鎯呭喌涓嬶紝涓や釜鍙傛暟鍙栧艰寖鍥翠负0鈥斺7锛屼笖Ending_of_Scan>Begin_of_scan銆備絾鍒╃敤鍔ㄦ佹壂鎻忓拰浜虹溂瑙嗚鏁堟灉锛屽彲璁剧疆瓒呭嚭 + 璇ヨ寖鍥寸殑鍙傛暟锛屼互瀹炵幇鐗规畩鏄剧ず鏁堟灉锛氬杞欢璋冩暣鏄剧ず浜害锛屾垨闈炵伅浜害鏄剧ず锛岀瓑锛 + + (3) Seg7Print(char d0,char d1,char d2,char d3,char d4,char d5,char d6,char d7)锛氬皢8涓弬鏁板煎垎鍒瘧鐮佹樉绀哄埌瀵瑰簲鐨勬暟鐮佺涓娿 + 鏄剧ず璇戠爜琛(code char decode_table[])鍦╩ain.c涓,鐢ㄦ埛鍙互淇敼鍜屽鍑. + + (4) LedPrint(char led_val)锛氭帶鍒8涓寚绀虹伅寮鍏炽傚弬鏁發ight_val鐨8涓猙it浣嶅搴8涓寚绀虹伅鐨勫紑鍏筹紝鈥1鈥濃斺旀寚绀虹伅鈥滀寒鈥 + +缂栧啓锛氬緪鎴愶紙鐢佃瘽18008400450锛 2021骞2鏈26鏃ヨ璁★紝2021骞3鏈15鏃ユ洿鏂 +*/ + +#ifndef _displayer_H_ +#define _displayer_H_ +extern void DisplayerInit(); //鍔犺浇鏄剧ず妯″潡宸ヤ綔 +extern void SetDisplayerArea(char Begin_of_scan,char Ending_of_Scan); //璁剧疆鏈夋晥鏄剧ず鍖哄煙 +extern void Seg7Print(char d0,char d1,char d2,char d3,char d4,char d5,char d6,char d7); //鍦ㄦ暟鐮佺涓婅緭鍑 +extern void LedPrint(char led_val); +#endif + diff --git a/key/inc/hall.H b/key/inc/hall.H new file mode 100644 index 0000000..bfcc3b1 --- /dev/null +++ b/key/inc/hall.H @@ -0,0 +1,24 @@ +/**********************************hall V2.0 说明 ************************************************************************ +Hall模块用于获取“STC-B学习板”上hall传感器状态。hall模块共提供1个加载函数、1个应用函数,一个Hall事件:enumEventHall + (1)HallInit():hall模块初始化函数 + (2)unsigned char GetHallAct(void):获取hall事件。 + 函数返回值: + enumHallNull(无变化) + enumHallGetClose(磁场接近) + enumHallGetAway(磁场离开) + 查询一次后,事件值变成enumEventHall (仅查询一次有效) + (3)hall传感器事件: + 当Hall检测到有"磁场接近"或"磁场离开"事件时,将产生一个Hall传感器事件(enumEventHall).响应事件的用户处理函数由用户编写, 并有sys中提供的SetEventCallBack()函数设置事件响应函数. + + +编写:徐成(电话18008400450) 2021年3月15日设计 2021年3月26日修改 +*/ + +#ifndef _hall_H_ +#define _hall_H_ + +extern void HallInit(void); //加载hall模块 +extern unsigned char GetHallAct(void); //获取hall事件 +enum HallActName {enumHallNull,enumHallGetClose,enumHallGetAway}; //返回值:enumHallNull——无,enumHallGetClose——下降沿(磁场接近),enumHallGetAway——上升沿(磁场离开) + +#endif \ No newline at end of file diff --git a/key/inc/music.h b/key/inc/music.h new file mode 100644 index 0000000..0c219a9 --- /dev/null +++ b/key/inc/music.h @@ -0,0 +1,100 @@ +/********************************** music V2.0 说明 ************************************************************************ +Music模块在Beep和Displayer模块基础上再次封装,用于控制“STC-B学习板”上播放音乐。加载该模块,将同时加载Beep模块、displayer模块。music模块共提供1个music驱动函数、4个应用函数: + (1)MusicPlayerInit():驱动music模块; + (2)char PlayTone(unsigned char tone, unsigned char beatsPM ,unsigned char scale, unsigned char beats):播放音乐音阶,实现用指定音调、指定节拍率、发指定音阶、发音节拍数。 +函数参数: + tone:指定音调,有效值:0xFA、0xFB、0xFC、0xFD、0xFE、0xFF、0xF9分别对应音乐A、B、C、D、E、F、G调 + beatsPM:节拍率,即每分钟节拍数,值范围10~255拍/分钟 + scale:音乐简谱音高,1字节。 +0x00——休止符 +高4位:1——低8度音 2——中8度音 3——高8度音 +低3位:1-7对应简谱音。其它值无效。 +如:0x13表示低音3(mi) + beats:音长(节拍数),单位1/16拍。 +如:16(0x10)对应1拍,32(0x20)对应2拍,8(0x08)对应半拍...... 。 +函数返回值:enumBeepOK:调用成功 + enumBeepBusy:忙(上一音未按设定发完,或因蜂鸣器正在发音) + enumBeepFail:调用失败(音调参数tone不对,或音高编码scale不对) + (见Beep.h中定义BeepActName) + (3)SetMusic(unsigned char beatsPM, unsigned char tone, unsigned char *pt, unsigned int datasize, unsigned char display):设定或改变要播放音乐和播放参数。 +函数参数: + beatsPM:节拍率,即每分钟节拍数,值范围10~255拍/分钟,如果参数值为enumModeInvalid将不改变原beatsPM; + tone:指定音调, 有效值:0xFA、0xFB、0xFC、0xFD、0xFE、0xFF、0xF9分别对应音乐A、B、C、D、E、F、G调,参数值为enumModeInvalid或其它值将不改变原tone + *pt :指向要播放的音乐编码的首地址 。*pt 和 datasize 只有有一个参数 = enumModeInvalid,将不改变 *pt 和 datasize + datasize:要播放的音乐编码的长度(字节数) 。*pt 和 datasize 只有有一个参数 = enumModeInvalid,将不改变 *pt 和 datasize + display:Seg7和Led是否用来显示播放音乐信息,取值: + enumMscNull —— 不用 + enumMscDrvSeg7 —— 用7段数码管Seg7(显示信息) + enumMscDrvLed —— 用Led指示灯(打拍) enumMscDrvSeg7andLed —— 用Seg7 和 Led + 参数值为enumModeInvalid或其它值将不改变原display +音乐编码规则: +1,常规音乐简谱发音编码(成对出现,不可分开,中间不能插入其它编码和控制字) + 基本格式:音高(1字节),节拍数(1字节),音高,节拍,...... + 其中“音高”部分: +0x11 — 0x17 :对应低音 do、re、mi、fa、so、la、si、 0x21 — 0x27 :对应中音 do、re、mi、fa、so、la、si + 0x31 — 0x37 :对应高音 do、re、mi、fa、so、la、si + 其中“节拍数”部分: +0x01-0xFF:单位1/16拍。也即十六进制中,高4位表示整拍数,低4位表示分拍数(1/16) + 如:发音2拍: 0x20 + 发音半拍: 0x08 + 发音1拍半:0x18 + 2,音乐编码中可以插入以下控制字,用于设定音乐播放参数等(前6个也可以通过函数,用程序设定和实现): + enumMscNull : 不用 + enumMscDrvSeg7 : 用7段数码管Seg7(显示信息) + enumMscDrvLed : 用Led指示灯(打拍) + enumMscDrvSeg7andLed : 用Seg7 和 Led + enumMscSetBeatsPM : 设置节拍率, 后面再跟 节拍率(1字节) + enumMscSetTone : 设置音调, 后面再跟 音调(1字节) +0xFA 或 0xFB 或 0xFC 或 0xFD 或 0xFE 或 0xFF 或 0xF9 +分别对应音乐:A调 或B调……… + enumMscRepeatBegin : 设置音乐播放重复开始处。重复一次(暂不支持多次),暂不能嵌套(嵌套无效或可能导致不可预期结果) + enumMscRepeatEnd : 设置音乐播放重复结束处 + + (4)SetPlayerMode(unsigned char play_ctrl) :音乐播放控制函数。 + 函数参数: + play_ctrl:enumModePlay : ”播放“ + enumModePause : ”暂停“ + enumModeStop :”停止/结束“ + (其它参数无效) +所有操作在当前”音“播放完成后生效; + (5)char GetPlayerMode(void): 获取当前播放状态 + 函数返回值:(play_ctrl值) + enumModePlay : 播放状态 + enumModePause : 暂停状态 + enumModeStop : 停止/结束 +(其它功能应用型函数可根据需要设置和增加) + + +编写:徐成(电话18008400450) 2021年3月5日设计,2021年9月5日更新 +*/ + +#ifndef _music_H_ +#define _music_H_ + +extern void MusicPlayerInit(); +extern char PlayTone(unsigned char tone, unsigned char beatsPM ,unsigned char scale, unsigned char beats); + // tone: 音调。F9,FA,FB,FC,FD,FE,FF分别对应G\A\B\C\D\E\F调,其它值无效 + // beatsPM:节凑,单位:每分钟节拍数 + // scale: 音高。0x00——休止符,高4位:1——低8度音 2——中8度音 3——高8度音,低3位:1-7简谱音。其它无效 + // beats: 音长(节拍数),单位1/16拍。16(0x10)对应1拍,32(0x20)对应2拍,8(0x08)对应半拍...... +extern void SetMusic(unsigned char beatsPM, unsigned char tone, unsigned char *pt, unsigned int datasize, unsigned char display); + //可设置或改变:全部、或部分播放参数(节拍率、音调、显示方式、音乐原数据) + //其中节拍率、音调、显示方式 也可以在音乐编码中设置 +extern void SetPlayerMode(unsigned char play_ctrl); + //操作播放:enumModePlay 或 enumModePause 或 enumModeStop,分别设置音乐”播放“、”暂停“、”停止/结束“,所有操作在当前”音“播放完成后生效; +extern char GetPlayerMode(void); //获取当前播放状态 + +enum PlayerMode {enumModeInvalid=0, //播放模式非法 + enumModePlay, //播放 + enumModePause, //暂停(可恢复续放) + enumModeStop}; //停止(结束) +enum MusicKeyword {enumMscNull=0xF0, //播放音乐时,不用7段数码管、LED指示灯(显示音乐播放相关信息) + enumMscDrvSeg7, //播放音乐时, 用7段数码管 + enumMscDrvLed, //播放音乐时, 用 LED指示灯 + enumMscDrvSeg7andLed, //播放音乐时, 用7段数码管、LED指示灯 + enumMscSetBeatsPM, //音乐编码中关键字: 设置 音乐节拍 + enumMscSetTone, //音乐编码中关键字: 设置 音调 + enumMscRepeatBegin, //音乐编码中关键字: 设置 重复开始 + enumMscRepeatEnd}; //音乐编码中关键字: 设置 重复结束 + +#endif \ No newline at end of file diff --git a/key/inc/sys.H b/key/inc/sys.H new file mode 100644 index 0000000..c03d3d8 --- /dev/null +++ b/key/inc/sys.H @@ -0,0 +1,63 @@ +/******************************* sys Ver3.6 说明 ************************************************ + (1) sys.c构成STC程序基本架构。提供: + a, 系统初始化MySTC_Init(),系统调度函数MySTC_OS(),加载用户回调函数SetEventCallBack() + b, 若干可设置和触发回调函数的事件; + enumEventSys1mS : 1mS定时到 + enumEventSys10mS : 10mS定时到 + enumEventSys100mS : 100mS定时到 + enumEventSys1S : 1S定时到 + enumEventKey : 按键事件 + enumEventNav : 导航按键事件“ + enumEventHall : hall传感器事件 + enumEventVib : 振动传感器事件 + enumEventXADC : 扩展接口上新的AD值事件 + enumEventUart1Rxd : 串口1上收到一个符合格式定义的数据包事件。串口1:USB上与PC机通信 + enumEventUart2Rxd : 串口2上收到一个符合格式定义的数据包事件。串口2:485上UART、EXT上UART、或485上ModBus协议(2022年5月2日新增) + enumEventIrRxd : 红外收到一个数据包事件 + c, 获取系统运行性能评价参数 + + (2) MySTC_Init():sys初始化函数,必须执行一次。 + (3) MySTC_OS(): sys调度函数,应在while(1)循环中。 + (4) SetEventCallBack(char event, void *(user_callback)):加载"事件"用户回调函数. + (5) SysPerF GetSysPerformance(void) :获取系统运行性能评估参数 + 函数参数:无 + 函数返回值:结构 struct SysPerF。定义如下: + typedef struct //系统性能评估参数,每秒更新一次 + { unsigned long MainLoops; //SysPerformance.MainLoops 每秒主循环次数(应大于1000以上) + unsigned char PollingMisses; //SysPerformance.PollingMisses 每秒轮询丢失次数(理想值为0。如果有非0情况,说明用户程序或算法存在问题) + } SysPerF; + + (6) 补充说明: + sys.c 基本调度时间为1mS,非抢占式,要求用户程序片段,其单次循环执行时间累加起来应小于1mS。 + +编写:徐成(电话18008400450) 2021年2月26日设计,2022年5月2日更新 +*/ + +#ifndef _sys_h_ +#define _sys_h_ + +typedef struct //系统性能评估参数,每秒更新一次 + { unsigned long MainLoops; //SysPerformance.MainLoops 每秒主循环次数(应大于1000以上) + unsigned char PollingMisses; //SysPerformance.PollingMisses 每秒轮询丢失次数(理想值为0。如果有非0情况,说明用户程序或算法存在问题) + } struct_SysPerF; + +extern void MySTC_Init(); //sys初始化函数 +extern void MySTC_OS(); //sys调度函数,应在while(1)循环中 +extern void SetEventCallBack(char event, void *(user_callback)); //加载"事件"用户回调函数. +extern struct_SysPerF GetSysPerformance(void); + +enum event{enumEventSys1mS, //系统1mS事件 + enumEventSys10mS, //系统10mS事件 + enumEventSys100mS, //系统100mS事件 + enumEventSys1S, //系统1S事件 + enumEventKey, //按键事件 + enumEventHall, //hall传感器事件 + enumEventVib, //振动传感器事件 + enumEventNav, //导航按键事件“ + enumEventXADC, //扩展接口上新的AD值事件 + enumEventUart1Rxd, //串口1上收到一个符合格式定义的事件 + enumEventUart2Rxd, //串口2上收到一个符合格式定义("数据包格式"、或"ModBus协议+数据包格式")的事件。 (2022年5月2日新增) + enumEventIrRxd //红外Ir上收到一个数据包 + }; + +#endif \ No newline at end of file diff --git a/key/inc/uart1.h b/key/inc/uart1.h new file mode 100644 index 0000000..ef39ba0 --- /dev/null +++ b/key/inc/uart1.h @@ -0,0 +1,58 @@ +/**********************************Uart1串行通信模块 V2.0 说明 ************************************************************************ +Uart1模块提供Uart1模块初始化函数、3个应用函数,1个事件(enumEventRxd): +(1) Uart1Init(unsigned long band):Uart1模块初始化函数。 + 函数参数:unsigned long band定义串口1的通信波特率(单位:bps)(8个数据位、1个停止位,无奇偶校验位) + 函数返回值:无 + +(2) void SetUart1Rxd(char *RxdPt, unsigned int Nmax, char *matchhead, unsigned int matchheadsize); + 设置串口1接收参数:数据包存放位置、大小,包头匹配字符、匹配字符个数。收到符合条件的数据包时将产生enumEventRxd事件。 + 函数参数: char *RxdPt:指定接收数据包存放区(首地址) + unsigned int Nmax:接收数据包大小(字节数),最大65535。当收到的数据大于Nmax后,将被丢弃 (2022年5月2日更改) + char *matchhead: 需要匹配的数据包头(首地址) + unsigned int matchheadsize:需要匹配的字节数 + 补充说明: + Nmax=1:为单字节接收,即收到一个字节就产生enumUart1EventRxd事件(如果定义了匹配,还需满足匹配条件); + 0 < matchheadsize < Nmax:要求接收数据中连续matchheadsize个字节与*matchhead处数据完全匹配,才在收到Nmax数据时产生enumEventRxd事件; + matchheadsize = Nmax:设定接收数据包完全匹配 + matchheadsize=0 或 matchheadsize > Nmax:将不做匹配,接收到任意Nmax数据时产生enumEventRxd事件; + 在enumEventRxd事件发出后,用户回调函数返回才接收下一个数据包 (2022年5月2日更改) + 函数返回值:无 + + (3) char Uart1Print(void *pt, unsigned int num):发送数据包,非阻塞函数(即函数不等到所设定任务全部完成才返回),该函数从被调用到返回大约1uS左右时间。 + 函数参数: void *pt :指定发送数据包位置 + unsigned int num:发送数据包大小; + 函数返回值:enumTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumTxFailure:调用失败(主要原因是:串口正忙(上一数据包未发完) + 补充说明:串口上发送1个字节数据大约需要时间0.1mS~10mS(视所设定的波特率),对计算机来说,如果发送多个字节是一个很要时间才能完成的事。类似于 + 前面用蜂鸣器演奏音乐,对这类事件与程序"异步"的问题,编程时不仅要注意程序逻辑性、还有注意程序时效性。(这个问题其实总是要注意、必须要注意的) + + (4) char GetUart1TxStatus(void): 获取Uart1发送状态 + 函数返回值:enumUart1TxFree:串口1发送空闲 + enumUart1TxBusy,串口1发送正忙 + + (5) Uart1接收事件:enumEventUart1Rxd。表示收到了一个符合指定要求(数据包头匹配、数据包大小一致)的数据包。 + 补充说明:串口(1和2)上收到的两个数据包之时间间隔要求不小于1mS(原因:系统内部调度方法限制) + +补充说明: + (1) 串口1、串口2波特率可独立设置,互不影响. + (2) 串口1、串口2、红外通信可同时工作,互不影响 + (3) 串口1、串口2用法基本上完全一致,红外通信用法也基本相同。不同地方是: + a,串口1固定在USB接口上,可用于与计算机通信;而串口2可初始化在EXT扩展、或485接口上(在485接口上时仅单工工作); + b,红外通信速率固定不可变(大约相当于500~800 bps),通信时没有包头匹配功能。红外模块除通信功能外,还提供用于电器红外遥控的应用函数; + c,红外通信模块仅为单工工作。不发送时自动进入接收状态;有数据发送时自动进入发送状态,但正在接收数据包过程中不会进入发送状态。 + + +编写:徐成(电话18008400450) 2021年3月28日设计 2021年11月8日更新 +*/ + + +#ifndef _uart1_H_ +#define _uart1_H_ + +extern void Uart1Init(unsigned long band); //串口初始化,参数:波特率 +extern void SetUart1Rxd(void *RxdPt, unsigned int Nmax, void *matchhead, unsigned int matchheadsize); //设置接收条件:数据包存放位置、大小,包头匹配字符、匹配字符个数。符合条件的包将产生enumEventRxd事件 +extern char Uart1Print(void *pt, unsigned int num); //发送数据包。非阻塞函数。数据包位置、大小。返回值enumTxOK调用成功,enumTxFailure失败(串口忙,上一数据包未发完) +extern char GetUart1TxStatus(void); //获取串口1发送状态,enumUart1TxFree:串口1发送空闲, enumUart1TxBusy,串口1发送正忙 +enum Uart1ActName {enumUart1TxFree=0,enumUart1TxBusy,enumUart1TxOK,enumUart1TxFailure}; + +#endif \ No newline at end of file diff --git a/key/inc/uart2.h b/key/inc/uart2.h new file mode 100644 index 0000000..0d68121 --- /dev/null +++ b/key/inc/uart2.h @@ -0,0 +1,65 @@ +/********************************** Uart2串行通信模块 V2.0 说明 *************************************************************** +Uart2模块提供Uart2模块初始化函数、3个应用函数,1个事件(enumUart2EventRxd): +(1) Uart2Init(unsigned long band,unsigned char Uart2mode):Uart2模块初始化函数。 + 函数参数:unsigned long band:定义串口2的通信波特率(单位:bps)(固定8个数据位、1个停止位,无奇偶校验位) + unsigned char Uart2mode:定义串口2位置 + 取值:Uart2UsedforEXT —— 串口2在EXT扩展插座上(TTL标准串口) + Uart2Usedfor485 —— 串口2用于485通信(半双工。发送数据包时不能接收数据) + Uart2Usedfor485ModBus —— 串口2用于485上,ModBus协议收发 (2022年5月2日新增) +(2) void SetUart2Rxd(char *RxdPt, unsigned int Nmax, char *matchhead, unsigned int matchheadsize); + 设置串口2接收参数:数据包存放位置、大小,包头匹配字符、匹配字符个数。收到符合条件的数据包时将产生enumEventRxd事件。 + 函数参数: char *RxdPt:指定接收数据包存放区(首地址) + unsigned int Nmax:接收数据包大小(字节数),最大65535。当收到的数据大于Nmax后,将被丢弃 (2022年5月2日更改) + char *matchhead: 需要匹配的数据包头(首地址) + unsigned int matchheadsize:需要匹配的字节数 + 补充说明: + Nmax=1:为单字节接收,即收到一个字节就产生enumEventUart2Rxd事件(如果定义了匹配,还需满足匹配条件); + 0 < matchheadsize < Nmax:要求接收数据中连续matchheadsize个字节与*matchhead处数据完全匹配,才在收到Nmax数据时产生enumEventRxd事件; + matchheadsize = Nmax:设定接收数据包完全匹配 + matchheadsize=0 或 matchheadsize > Nmax:将不做匹配,接收到任意Nmax数据时产生enumEventRxd事件; + 在enumEventRxd事件发出后,用户回调函数返回才接收下一个数据包 (2022年5月2日更改) +(3) char Uart2Print(void *pt, unsigned int num):发送数据包,非阻塞函数(即函数不等到所设定任务全部完成才返回),该函数从被调用到返回大约1uS左右时间。 + 函数参数: void *pt :指定发送数据包位置 + unsigned int num:发送数据包大小; + 函数返回值:enumTxOK:调用成功,即所设定的发送数据包请求已被系统sys正确接受,sys将尽硬件资源最大可能及时发送数据。 + enumTxFailure:调用失败(主要原因是:串口正忙(上一数据包未发完) + 补充说明:串口上发送1个字节数据大约需要时间0.1mS~10mS(视所设定的波特率),对计算机来说,如果发送多个字节是一个很要时间才能完成的事。 + 类似于前面用蜂鸣器演奏音乐,对这类事件与程序"异步"的问题,编程时不仅要注意程序逻辑性、还有注意程序时效性。(这个问题其实总是要注意、必须要注意的) +(4) char GetUart2TxStatus(void): 获取Uart2发送状态 + 函数返回值:enumUart2TxFree:串口2发送空闲 + enumUart2TxBusy,串口2发送正忙 +(5) Uart2接收事件:enumUart2EventRxd。表示收到了一个符合指定要求(数据包头匹配、数据包大小一致)的数据包。 + 当串口2工作于: Uart2UsedforEXT 或 Uart2Usedfor485 方式时, + Uart2接收事件为:同串口1性质一致,即:数据包头匹配、数据包大小一致 + 当串口2工作于: Uart2Usedfor485ModBus 方式时, (2022年5月2日新增) + Uart2接收事件为:收到一个ModBus数据帧(数据包内字节间间隔<4字节收发时间),且帧内包头内容与设定内容匹配 + 但:1,数据帧内未进行CRC校验。建议用户在回调函数中,为了验证数据包正确性,应对数据包进行CRC校验 + 2,未返回ModBus数据帧有效字节数。用户可从收到的指令类型(第2字节)及对应帧内数据(一般第5、6字节)判断帧字节数 + 补充说明:串口(1和2)上收到的两个数据包之时间间隔要求不小于1mS(原因:系统内部调度方法限制) + +补充说明: + (1) 串口1、串口2波特率可独立设置,互不影响. + (2) 串口1、串口2、红外通信可同时工作,互不影响 + (3) 串口1、串口2(除开ModBus)用法基本上完全一致,红外通信用法也基本相同。不同地方是: + a,串口1固定在USB接口上,可用于与计算机通信;而串口2可初始化在EXT扩展、或485接口上(在485接口上时仅单工工作); + b,红外通信速率固定不可变(大约相当于500~800 bps),通信时没有包头匹配功能。红外模块除通信功能外,还提供用于电器红外遥控的应用函数; + c,红外通信模块仅为单工工作。不发送时自动进入接收状态;有数据发送时自动进入发送状态,但正在接收数据包过程中不会进入发送状态。 + (4)2022年5月2日新增串口2在485接口上支持ModBus协议数据帧监测功能,使"STC-B学习板"方便实现ModBus协议的节点等功能 (2022年5月2日新增) + +编写:徐成(电话18008400450) 2021年3月28日设计 2022年5月2日更新 +*/ + + +#ifndef _uart2_H_ +#define _uart2_H_ + +extern void Uart2Init(unsigned long band,unsigned char Uart2mode); //串口2初始化,参数:波特率、串口2位置 +enum Uart2PortName {Uart2UsedforEXT,Uart2Usedfor485,Uart2Usedfor485ModBus}; // Uart2UsedforEXT —— 串口2在EXT扩展插座上(TTL标准串口) + // Uart2Usedfor485 —— 串口2用于485通信(半双工。发送数据包时不能接收数据) + // Uart2Usedfor485ModBus —— 串口2用于485上,ModBus协议收发 +extern void SetUart2Rxd(void *RxdPt, unsigned int Nmax, void *matchhead, unsigned int matchheadsize); //设置接收条件:数据包存放位置、大小,包头匹配字符、匹配字符个数。符合条件的包将产生enumUart2EventRxd事件 +extern char Uart2Print(void *pt, unsigned int num); //发送数据包。非阻塞函数。数据包位置、大小。返回值enumUart2TxOK调用成功,enumUart2TxFailure失败(串口忙,上一数据包未发完) +extern char GetUart2TxStatus(void); //获取串口2发送状态,enumUart2TxFree:串口2发送空闲, enumUart2TxBusy,串口2发送正忙 +enum Uart2ActName {enumUart2TxFree=0,enumUart2TxBusy,enumUart2TxOK,enumUart2TxFailure}; + +#endif \ No newline at end of file diff --git a/key/key.uvopt b/key/key.uvopt new file mode 100644 index 0000000..85f6bba --- /dev/null +++ b/key/key.uvopt @@ -0,0 +1,197 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + Target 1 + 0x0 + MCS-51 + + 35000000 + + 1 + 1 + 1 + 0 + 0 + + + 0 + 65535 + 0 + 0 + 0 + + + 120 + 65 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + -1 + + + + + + + + + + + + + + + 0 + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Source Group 1 + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\source\main.c + main.c + 0 + 0 + + + 1 + 2 + 4 + 0 + 0 + 0 + .\source\STCBSP_V3.6.LIB + STCBSP_V3.6.LIB + 0 + 0 + + + +
diff --git a/key/key.uvproj b/key/key.uvproj new file mode 100644 index 0000000..e7d8e5e --- /dev/null +++ b/key/key.uvproj @@ -0,0 +1,395 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + Target 1 + 0x0 + MCS-51 + 0 + + + STC15F2K60S2 Series + STC + IRAM(0-0xFF) XRAM(0-0x6FF) IROM(0-0xEFF8) CLOCK(35000000) MODP2 + + "LIB\STARTUP.A51" ("Standard 8051 Startup Code") + + 62472 + STC15F2K60S2.H + + + + + + + + + + + 0 + 0 + + + + STC\ + STC\ + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + key + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 0 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + 65535 + + + S8051.DLL + + DP51.DLL + -pDP8051 + S8051.DLL + + TP51.DLL + -p51 + + + + 0 + 0 + 0 + 0 + 16 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + + 0 + -1 + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + 0 + 0 + -1 + + 0 + + + + + + + 0 + + + + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0x0 + 0xffff + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0xeff9 + + + 0 + 0x0 + 0x100 + + + 0 + 0x0 + 0x700 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + + + 0 + 0 + 1 + 0 + 1 + 3 + 8 + 2 + 1 + 1 + 0 + 0 + + + + + .\inc + + + + 0 + 1 + 0 + 0 + + + + + + + + + 0 + 0 + 1 + 0 + 2 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source Group 1 + + + main.c + 1 + .\source\main.c + + + STCBSP_V3.6.LIB + 4 + .\source\STCBSP_V3.6.LIB + + + + + + + +
diff --git a/key/source/STCBSP_V3.6.LIB b/key/source/STCBSP_V3.6.LIB new file mode 100644 index 0000000000000000000000000000000000000000..bf42f13d33a4d56bc1231fd14c66ad66708b8fe2 GIT binary patch literal 61916 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 literal 0 HcmV?d00001 diff --git a/key/source/main.c b/key/source/main.c new file mode 100644 index 0000000..f33f65f --- /dev/null +++ b/key/source/main.c @@ -0,0 +1,81 @@ +// This project is used for demonstrating digital tubes of BSP library. +#include "STC15F2K60S2.H" +#include "displayer.h" +#include "key.H" +#include "sys.H" + +code unsigned long SysClock = 11059200; //蹇呴』銆傚畾涔夌郴缁熷伐浣滄椂閽熼鐜(Hz)锛岀敤鎴峰繀椤讳慨鏀规垚涓庡疄闄呭伐浣滈鐜囷紙涓嬭浇鏃堕夋嫨鐨勶級涓鑷 +#ifdef _displayer_H_ //鏄剧ず妯″潡閫夌敤鏃跺繀椤汇傦紙鏁扮爜绠℃樉绀鸿瘧鐮佽〃锛岀敤鎴跺彲淇敼銆佸鍔犵瓑锛 +code char decode_table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x00, 0x08, 0x40, 0x01, 0x41, 0x48, + /* 搴忓彿: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + /* 鏄剧ず: 0 1 2 3 4 5 6 7 8 9 (鏃) 涓- 涓- 涓- 涓婁腑- 涓笅- */ + 0x3f | 0x80, 0x06 | 0x80, 0x5b | 0x80, 0x4f | 0x80, 0x66 | 0x80, 0x6d | 0x80, 0x7d | 0x80, 0x07 | 0x80, 0x7f | 0x80, 0x6f | 0x80}; +/* 甯﹀皬鏁扮偣 0 1 2 3 4 5 6 7 8 9 */ +#endif + +char changeBit(char x, char n, char y) +{ + char temp = x; + temp &= ~(1 << n); + temp |= (y << n); + return temp; +} + +void display_key() +{ + static char status[8]={10,10,10,10,10,10,10,10}; + static char led = 0x0; + char key1 = GetKeyAct(enumKey1), key2 = GetKeyAct(enumKey2), key3 = GetKeyAct(enumKey3); + switch (key1) + { + case enumKeyPress: + status[5] = 1; + led=changeBit(led, 0, 1); + break; + case enumKeyRelease: + status[5] = 10; + led=changeBit(led, 0, 0); + break; + } + switch (key2) + { + case enumKeyPress: + status[6] = 2; + led=changeBit(led, 1, 1); + break; + case enumKeyRelease: + status[6] = 10; + led=changeBit(led, 1, 0); + break; + } + switch (key3) + { + case enumKeyPress: + status[7] = 3; + led=changeBit(led, 2, 1); + break; + case enumKeyRelease: + status[7] = 10; + led=changeBit(led, 2, 0); + break; + } + status[0]=led/10; + status[1]=led%10; + Seg7Print(status[0], status[1], status[2], status[3], status[4], status[5], status[6], status[7]); + LedPrint(led); +} + +void main() +{ + DisplayerInit(); + KeyInit(); + SetDisplayerArea(0, 7); + SetEventCallBack(enumEventKey, display_key); + MySTC_Init(); + LedPrint(0xff); + Seg7Print(10, 10, 10, 10, 10, 10, 10, 10); + while (1) + { + MySTC_OS(); + } +}