STM32杂交版(HAL库、音乐盒、闹钟、点阵屏、温湿度)
一、设计描述
本设计精心构建了一个以STM32MP157A高性能单片机为核心控制单元的综合性嵌入式系统。该系统巧妙融合了蜂鸣器、数码管显示器、点阵屏、温湿度传感器、LED指示灯以及按键等多种外设模块,形成了一个功能丰富、操作便捷的杂交版智能设备。通过串口通信,用户可以灵活地切换系统的工作模式,轻松实现闹钟、音乐盒播放及温湿度监测与调控等基本功能。
核心硬件
- 主控单元:采用STM32MP157A单片机,凭借其强大的处理能力和丰富的外设接口,为系统提供了坚实的硬件基础。
软件平台
- 开发工具:利用STM32CUBEIDE这一直观易用的集成开发环境,极大地提升了软件编程与调试的效率,确保了系统软件的稳定可靠。
系统功能亮点
-
模式灵活切换:通过串口通信,用户可以轻松地在闹钟、音乐盒播放及温湿度监测三种模式之间自由切换,满足不同场景下的使用需求。
-
动态信息显示:点阵屏作为系统的信息展示窗口,能够根据当前的工作模式显示相应的汉字(如“钟”代表闹钟模式,“音”代表音乐盒模式,“传”可视为温湿度监测的简化标识),为用户提供了直观的操作反馈。
-
按键交互体验:设计中充分考虑了用户的交互体验,通过按键即可在各模式下执行对应的功能操作,如音乐盒的速度与音量调节、歌曲切换、暂停/播放控制,以及闹钟的时间调整、设置多个闹钟、关闭闹钟等。
-
温湿度智能调控:系统内置温湿度传感器,能够实时监测环境状况,并通过串口接收用户指令调节温湿度的上下限阈值。一旦环境参数超出设定范围,LED指示灯将亮起作为边界提示,帮助用户及时采取措施。
二、基本配置信息
音乐盒在之前做过所以配置不做改变:STM32音乐盒
三、STM32CUBEIDE配置
1、定时器--100ms
2、PWM配置(蜂鸣器 -- PB6)
3. 串口配置
注意针脚
4. IIC配置(温湿度,数码管,点阵屏)
5. GPIO配置(LED和按键)
6. NVIC
四、程序编写
(1)音乐盒代码
音乐盒在之前已经写过,所以这里不再重复之前的操作,我们将串口和模式转换加进去。
STM32音乐盒
串口音乐控制函数
//串口音乐控制函数
void music_kz(){if(EN_music == 1)//启动play_music(list,Low_volume);else__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量if(strcmp("music volume increase",(char *)uart4_data)==0){uart4_data[0] = '0';Low_volume = Low_volume + Low_volume_cnt;if(Low_volume >= 10)Low_volume = 10;}if(strcmp("music volume reduction",(char *)uart4_data)==0){Low_volume = Low_volume - Low_volume_cnt;if(Low_volume <= 0)Low_volume = 0;}if(strcmp("music speed increase",(char *)uart4_data)==0){uart4_data[0] = '0';music_speed_i++;music_speed_i = music_speed_kz(music_speed_i);}if(strcmp("music speed reduction",(char *)uart4_data)==0){uart4_data[0] = '0';music_speed_i--;music_speed_i = music_speed_kz(music_speed_i);}if(strcmp("music next song",(char *)uart4_data)==0){uart4_data[0] = '0';list++;if(list > list_max){list = list_max;}}if(strcmp("music previous song",(char *)uart4_data)==0){list--;uart4_data[0] = '0';if(list < 0){list = 0;}}if(strcmp("music start",(char *)uart4_data)==0){EN_music = 1;}if(strcmp("music stop",(char *)uart4_data)==0){EN_music = 0;}}
按键模式控制
用mode变量代表模式,后面三个按键同理。
void EXTI0_IRQHandler(void)
{/* USER CODE BEGIN EXTI0_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == 0 && mode == 0)//确保数据稳定{//每次按下解决 音量�??????? Low_volume_cntLow_volume = Low_volume + Low_volume_cnt;if(Low_volume >= 10)Low_volume = 0;}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0)==GPIO_PIN_RESET && mode == 1) {shi_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;if(shi_clock>=24){shi_clock=0;}miao_shi_clock=miao_clock/10;miao_ge_clock=miao_clock%10;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;buf[0]=smg_number[shi_shi_clock];buf[1]=smg_number[shi_ge_clock];buf[3]=smg_number[fen_shi_clock];buf[4]=smg_number[fen_ge_clock];buf[6]=smg_number[miao_shi_clock];buf[7]=smg_number[miao_ge_clock];}/* USER CODE END EXTI0_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);/* USER CODE BEGIN EXTI0_IRQn 1 *//* USER CODE END EXTI0_IRQn 1 */
}
(2)模式切换
mode变量切换
void uart_mode(){if(strcmp("mode = music",(char *)uart4_data)==0){mode = 0;}if(strcmp("mode = clock",(char *)uart4_data)==0){mode = 1;}if(strcmp("mode = sensor",(char *)uart4_data)==0){mode = 2;}
}
点阵屏字库
uint8_t DZP_data[6][34]={{0xAA,0x55,0xFD,0xFF,0xFE,0xFF,0xC0,0x07,0xFF,0xFF,0xF7,0xDF,0xFB,0xBF,0x00,0x01,0xFF,0xFF,0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF},//音{0xAA,0x55,0xEF,0xDF,0xEF,0xDF,0xC3,0xDF,0xDF,0xDF,0xBE,0x03,0x42,0xDB,0xEE,0xDB,0xEE,0xDB,0x02,0xDB,0xEE,0x03,0xEE,0xDB,0xEF,0xDF,0xEB,0xDF,0xE7,0xDF,0xEF,0xDF,0xFF,0xDF},//钟//1//{0xAA,0x55,0xF7,0xBF,0xF7,0xBF,0xF7,0xBF,0xEC,0x07,0xEF,0xBF,0xCF,0x7F,0xC8,0x01,0xAF,0x7F,0x6E,0xFF,0xEC,0x07,0xEF,0xF7,0xEE,0xEF,0xEF,0x5F,0xEF,0xBF,0xEF,0xDF,0xEF,0xDF}//传//2//};
点阵屏显示
if(mode_n != mode){mode_n = mode;for(int i = 0; i<34;i++){//printf("afgsbgafdffag");HAL_I2C_Master_Transmit(&hi2c1, 0xA0 , (uint8_t*)&DZP_data[mode][i], 1, 300);HAL_Delay(2);}}
(3)闹钟代码编写
1. 基础变量
main.c
//数码管闹钟基础变量
extern int buf[8];
extern int shi_shi;
extern int shi_ge ;
extern int fen_shi;
extern int fen_ge ;
extern int miao_shi ;
extern int miao_ge ;extern int miao ;
extern int shi ;
extern int fen;
//闹钟保存数组
extern int alarm_clock_array[20][4];
extern int alarm_clock_array_cnt;
stm32mp1xx_it.c 基础变量
//数码管闹钟基础设置
int smg_number[10] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xE0,0xFE,0xF6};
int buf[8] = {0};//闹钟保存数组
int alarm_clock_array[20][4] = {0};
int alarm_clock_array_cnt = 0;
//实时时钟信息
int shi_shi = 0;
int shi_ge = 0;
int fen_shi = 0;
int fen_ge = 0;
int miao_shi = 0;
int miao_ge = 0;
int miao = 0;
int shi = 0;
int fen = 0;int EN_clock = 0;//闹钟设置使能
extern int en_clock;//用于控制闹钟响铃//闹钟设置信息
int shi_shi_clock = 0;
int shi_ge_clock = 0;
int fen_shi_clock = 0;
int fen_ge_clock = 0;
int miao_shi_clock = 0;
int miao_ge_clock = 0;
int miao_clock = 0, shi_clock = 0, fen_clock = 0;
2. TIM2定时器
void TIM2_IRQHandler(void)
{/* USER CODE BEGIN TIM2_IRQn 0 */if(EN_music == 1)time_100ms_cnt++;elsetime_100ms_cnt = time_100ms_cnt; //其余状�?�不计数if(time_100ms_cnt >= Beat_speed_n * Beat_num){ //这个音节结束time_100ms_cnt = 0;flag = 1; //发�?�音节结束信�???????}//数码�????static int smg_time_100ms = 0;smg_time_100ms++;if(smg_time_100ms>=10){miao++;smg_time_100ms = 0;}if (miao>=60){miao=0;fen++;if(fen>=60){fen=0;shi++;if(shi>=24){shi=0;}}}if(miao >= 60){miao = miao-60;fen++;}if(fen>=60){fen = fen-60;shi ++;}if(shi>= 24){shi = shi -24;}miao_shi=miao/10;miao_ge=miao%10;fen_shi=fen/10;fen_ge=fen%10;shi_shi=shi/10;shi_ge=shi%10;if(EN_clock == 0){buf[0]=smg_number[shi_shi];buf[1]=smg_number[shi_ge];buf[3]=smg_number[fen_shi];buf[4]=smg_number[fen_ge];buf[6]=smg_number[miao_shi];buf[7]=smg_number[miao_ge];HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_RESET);//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);//HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET);//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);//HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_SET);}/* USER CODE END TIM2_IRQn 0 */HAL_TIM_IRQHandler(&htim2);/* USER CODE BEGIN TIM2_IRQn 1 *//* USER CODE END TIM2_IRQn 1 */
}
3. 按键控制设置闹钟和保存闹钟
void EXTI9_IRQHandler(void)
{/* USER CODE BEGIN EXTI9_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 0){//确保数据稳定EN_music = !EN_music;}if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 1 ){//确保数据稳定if(EN_clock == 1){//闹钟设置成功alarm_clock_array[alarm_clock_array_cnt][0] = shi_clock;alarm_clock_array[alarm_clock_array_cnt][1] = fen_clock;alarm_clock_array[alarm_clock_array_cnt][2] = miao_clock;alarm_clock_array[alarm_clock_array_cnt][3] = 3; //默认播放第三首音�????alarm_clock_array_cnt++;if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;EN_clock = 0;}else if(EN_clock == 0){//设置闹钟shi_shi_clock = shi_shi;shi_ge_clock = shi_ge;fen_shi_clock = fen_shi;fen_ge_clock = fen_ge;miao_shi_clock = 0;miao_ge_clock = 0;miao_clock = 0;shi_clock = shi;fen_clock = fen;EN_clock = 1;}}/* USER CODE END EXTI9_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);/* USER CODE BEGIN EXTI9_IRQn 1 *//* USER CODE END EXTI9_IRQn 1 */
}
4. 时分按键+
void EXTI0_IRQHandler(void)
{/* USER CODE BEGIN EXTI0_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == 0 && mode == 0)//确保数据稳定{//每次按下解决 音量�??????? Low_volume_cntLow_volume = Low_volume + Low_volume_cnt;if(Low_volume >= 10)Low_volume = 0;}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0)==GPIO_PIN_RESET && mode == 1) {shi_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;if(shi_clock>=24){shi_clock=0;}miao_shi_clock=miao_clock/10;miao_ge_clock=miao_clock%10;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;buf[0]=smg_number[shi_shi_clock];buf[1]=smg_number[shi_ge_clock];buf[3]=smg_number[fen_shi_clock];buf[4]=smg_number[fen_ge_clock];buf[6]=smg_number[miao_shi_clock];buf[7]=smg_number[miao_ge_clock];}/* USER CODE END EXTI0_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);/* USER CODE BEGIN EXTI0_IRQn 1 *//* USER CODE END EXTI0_IRQn 1 */
}/*** @brief This function handles EXTI line1 interrupt.*/
void EXTI1_IRQHandler(void)
{/* USER CODE BEGIN EXTI1_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_1) == 0 && mode == 0)//确保数据稳定{music_speed_i++;music_speed_i = music_speed_kz(music_speed_i);}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_1)==GPIO_PIN_RESET && mode == 1) {fen_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;if(fen_clock>=60){fen_clock=0;shi_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;if(shi_clock>=24){shi_clock=0;}}miao_shi_clock=miao_clock/10;miao_ge_clock=miao_clock%10;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;buf[0]=smg_number[shi_shi_clock];buf[1]=smg_number[shi_ge_clock];buf[3]=smg_number[fen_shi_clock];buf[4]=smg_number[fen_ge_clock];buf[6]=smg_number[miao_shi_clock];buf[7]=smg_number[miao_ge_clock];}/* USER CODE END EXTI1_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);/* USER CODE BEGIN EXTI1_IRQn 1 *//* USER CODE END EXTI1_IRQn 1 */
}/*** @brief This function handles EXTI line2 interrupt.*/
void EXTI2_IRQHandler(void)
{/* USER CODE BEGIN EXTI2_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_2) == 0 && mode == 0)//确保数据稳定{list++;if(list > list_max){list = 0;}}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_2)==GPIO_PIN_RESET && mode == 1) {//在此处关闭闹�????en_clock = 0;}/* USER CODE END EXTI2_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);/* USER CODE BEGIN EXTI2_IRQn 1 *//* USER CODE END EXTI2_IRQn 1 */
}
5. 时钟相加函数(将后三的时分秒加入左三的对应时分秒)
//通过输入不同的n,返回shi fen miao
int clock_compute(int time_shi,int time_fen,int time_miao,int add_shi,int add_fen,int add_miao,int n){time_miao = time_miao + add_miao;time_fen = time_fen + time_miao/60;time_miao = time_miao % 60;time_fen = time_fen + add_fen;time_shi = time_shi + time_fen / 60;time_fen = time_fen%60;time_shi = time_shi + add_shi;time_shi = time_shi%24;if(n == 0) return time_shi;if(n == 1) return time_fen;if(n == 2) return time_miao;return -1;
}
6. 提取对应字符串后两位数字
// 函数定义:从字符串中提取两位数字
int extract_two_digits(const char *str, const char *prefix, int *value) {char *pos = strstr(str, prefix); // 查找前缀的位�?????if (pos == NULL) return 0; // 如果没找到前�?????,返�?????0表示失败// 跳过前缀的长度,找到数字�?????始的位置pos += strlen(prefix);// �?????查接下来的两个字符是否是数字if (pos[0] >= '0' && pos[0] <= '9' && pos[1] >= '0' && pos[1] <= '9') {// 转换字符为数�?????*value = (pos[0] - '0') * 10 + (pos[1] - '0');return 1; // 成功提取,返�?????1}return 0; // 提取失败,返�?????0
}
7. 串口设置目前时钟,定时闹钟,延时闹钟
//判断是否到底闹钟
int en_clock = 0;//用于控制闹钟响铃
int en_clock_cnt = 0;
int clock_end[3] = {0};//记录闹钟无人时关闭的时间
//串口设置闹钟
void uart_clock(){int ci = 0;int ci_n = 0;//ci = number_char_come(uart4_data,(uint8_t *)"clock shi = ",2);ci = extract_two_digits((char *)uart4_data, (char *)"clock shi = ", &ci_n);if(ci == 1){uart4_data[0] = '1';shi = ci_n;}//ci = number_char_come(uart4_data,(uint8_t *)"clock fen = ",2);ci = extract_two_digits((char *)uart4_data, (char *)"clock fen = ", &ci_n);if(ci == 1){uart4_data[0] = '1';fen = ci_n;}//ci = number_char_come(uart4_data,(uint8_t *)"clock miao = ",2);ci = extract_two_digits((char *)uart4_data, (char *)"clock miao = ", &ci_n);if(ci == 1){uart4_data[0] = '1';miao = ci_n;}//设置�?????个多少时间后的闹�?????//ci = number_char_come(uart4_data,(uint8_t *)"clock delay shi = ",2);ci = extract_two_digits((char *)uart4_data, "clock delay shi = ", &ci_n);if(ci == 1){uart4_data[0] = '1';alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,ci_n,0,0,0);alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,ci_n,0,0,1);alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,ci_n,0,0,2);alarm_clock_array_cnt++;}//ci = number_char_come(uart4_data,(uint8_t *)"clock delay fen = ",2);ci = extract_two_digits((char *)uart4_data, "clock delay fen = ", &ci_n);if(ci == 1){uart4_data[0] = '1';alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,ci_n,0,0);alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,ci_n,0,1);alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,ci_n,0,2);alarm_clock_array_cnt++;}ci = extract_two_digits((char *)uart4_data, "clock delay miao = ", &ci_n);if(ci == 1){uart4_data[0] = '1';alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,0,ci_n,0);alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,0,ci_n,1);alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,0,ci_n,2);alarm_clock_array_cnt++;}// time shi = 12;fen = 10;miao = 12;music = 1;ci = 0;ci = ci + extract_two_digits((char *)uart4_data, "time shi = ", &alarm_clock_array[alarm_clock_array_cnt][0]);ci = ci + extract_two_digits((char *)uart4_data, ";fen = ", &alarm_clock_array[alarm_clock_array_cnt][1]);ci = ci + extract_two_digits((char *)uart4_data, ";miao = ", &alarm_clock_array[alarm_clock_array_cnt][2]);//ci = ci + extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][2]);if(ci == 3){//完美对应uart4_data[0] = '1';ci = extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][3]);if(ci > list_max && ci<0) //如果大于音乐总数alarm_clock_array[alarm_clock_array_cnt][3] = 3;//默认�?????3alarm_clock_array_cnt++;}if(strcmp("clock delay list",(char *)uart4_data)==0){uart4_data[0] = '0';for(int i = 0; i< alarm_clock_array_cnt;i++){if(alarm_clock_array[i][0] != -1 && alarm_clock_array[i][1] != -1 && alarm_clock_array[i][2] != -1)printf("%d : time -> %d/%d/%d \r\n",i, alarm_clock_array[i][0],alarm_clock_array[i][1],alarm_clock_array[i][2]);}}//读取关闭第几位闹�?????//ci = number_char_come(uart4_data,(uint8_t *)"clock stop list = ",2);ci = extract_two_digits((char *)uart4_data, "clock stop list = ", &ci_n);if(ci == 1){alarm_clock_array[ci_n][0] = -1;alarm_clock_array[ci_n][1] = -1;alarm_clock_array[ci_n][2] = -1;}//关闭闹钟if(strcmp("clock stop stop",(char *)uart4_data)==0){en_clock = 0;}if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;
}
8. 闹钟实现和停止(数码管显示)
void alarm_clock(){//时钟显示(数码管)static int pos = 0;HAL_I2C_Mem_Write(&hi2c1,0x70,0X10+pos, 1, (uint8_t*)&buf[pos],1,100);HAL_Delay(1);pos++;if(pos == 3 && pos == 6) pos++;if(pos == 8) pos = 0;uart_clock();//调用串口控制for(int j=0;j<alarm_clock_array_cnt && en_clock == 0;j++){//int cnt_clock = 0;if(alarm_clock_array[j][0] == shi && alarm_clock_array[j][1] == fen && alarm_clock_array[j][2] == miao) {en_clock_cnt = j;en_clock = 1;clock_end[0] = clock_compute(shi,fen,miao,0,0,30,0);clock_end[1] = clock_compute(shi,fen,miao,0,0,30,1);clock_end[2] = clock_compute(shi,fen,miao,0,0,30,2);break;}}//当闹钟响�?????30Sif(shi == clock_end[0] && fen == clock_end[1] && miao == clock_end[2]){en_clock = 0;//关闭闹钟//EN_music = 1;}if(en_clock == 1 ){motor(10);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);}}
(4)温湿度代码编写
1. 温湿度基础变量
uint8_t add1=0xFE,add2=0xE5,add3=0xE3;
//0xFE复位 0xE5启动湿度转换 0xE3启动温度转换
uint16_t RH_Code,RH_Code_low=0,RH_Code_high=0;
uint16_t Temp_Code,Temp_Code_low=0,Temp_Code_high=0;int humidity_min = 50;//能仍受最低干燥程度
int temperature_max = 50;//能仍受的最高温度
int en_t = 0; //温度使能
int en_r = 0; //湿度使能
2. 温湿度计算
//计算出温湿度
void Temperature_humidity(){//湿度HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add2, 1,100);//写命�??????? ox40里面写命�??????? 0xe5 启动湿度转换HAL_I2C_Master_Receive(&hi2c1, 0x81, &RH_Code, 1, 100);//读命�??????? �???????0x40读取出湿度的数据 存入变量RH_CODEHAL_Delay(30);//进行高低字节转换RH_Code_low=(RH_Code & 0xff);RH_Code_high=(RH_Code >> 8)& 0xff;RH_Code=(RH_Code_low << 8)+RH_Code_high;//温度HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add3, 1,100);HAL_I2C_Master_Receive(&hi2c1, 0x81, &Temp_Code, 1, 100);//读命�??????? �???????0x40读取出温度的数据 存入变量Temp_CODEHAL_Delay(30);//进行高低字节转换Temp_Code_low=(Temp_Code & 0xff);Temp_Code_high=(Temp_Code >> 8)& 0xff;Temp_Code=(Temp_Code_low << 8)+Temp_Code_high;Temp_Code=17572*Temp_Code/65535-4685;//扩大�???????百�??RH_Code=125*RH_Code/65536-6;//计算出湿度�??//printf("Temp_Code = \r%d.%d RH_Code = %d%%\n",Temp_Code/100,Temp_Code%100,RH_Code%100);//串口输出温湿�???????HAL_Delay(2);
}
3. 温湿度串口控制
void uart_sensor(){int tr=0;int tr_i = 0;tr = extract_two_digits((char *)uart4_data, "sensor humidity_min = ", &tr_i);if(tr != 0){humidity_min = tr_i;}tr = extract_two_digits((char *)uart4_data, "sensor temperature_max = ", &tr_i);if(tr != 0){temperature_max = tr_i;}if(strcmp("sensor temperature start",(char *)uart4_data)==0){en_t = 1;}if(strcmp("sensor humidity start",(char *)uart4_data)==0){en_r = 1;}if(strcmp("sensor temperature stop",(char *)uart4_data)==0){en_t = 0;}if(strcmp("sensor humidity stop",(char *)uart4_data)==0){en_r = 0;}if(strcmp("sensor list",(char *)uart4_data)==0){uart4_data[0] = '0';printf("Temp_Code = \r%d.%d RH_Code = %d%%\r\n",Temp_Code/100,Temp_Code%100,RH_Code%100);printf("sensor en_t : %d\r\n",en_t);printf("sensor en_r : %d\r\n",en_r);printf("sensor temperature_max : %d\r\n",temperature_max);printf("sensor humidity_min : %d\r\n",humidity_min);}if(strcmp("sensor Temp_Code RH_Code",(char *)uart4_data)==0){uart4_data[0] = '0';printf("Temp_Code = \r%d.%d RH_Code = %d%%\n",Temp_Code/100,Temp_Code%100,RH_Code%100);}}
4. 温湿度主函数
void sensor(){static int iii = 0;if(iii == 0){HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add1, 1, 100);HAL_Delay(2);iii++;}Temperature_humidity();uart_sensor();if(RH_Code < humidity_min && en_r == 1){//motor(10);HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_RESET);}if(Temp_Code/100 >= temperature_max && en_t == 1){HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_RESET);}
}
(5)主函数
void end_main(){tone_init(); //初始化音量频�??????list_max = music_init();//更新乐谱HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //启动蜂鸣器定时器HAL_TIM_Base_Start_IT(&htim2); //启动定时�??????2HAL_TIM_Base_Start_IT(&htim3); //启动定时�??????2//1 使能串口空闲中断__HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);//2.使能串口中断接收数据HAL_UART_Receive_IT(&huart4,rx_buf,sizeof(rx_buf));int mode_n = 1;while(1){music_kz();alarm_clock();uart_mode();sensor();if(mode_n != mode){mode_n = mode;for(int i = 0; i<34;i++){//printf("afgsbgafdffag");HAL_I2C_Master_Transmit(&hi2c1, 0xA0 , (uint8_t*)&DZP_data[mode][i], 1, 300);HAL_Delay(2);}}}
}
五、总代码
main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** <h2><center>© Copyright (c) 2024 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */#include <string.h>uint8_t rx_buf[200]={0}; //接收不定长数
uint8_t uart4_data[200] = {0};extern int mode; //模式
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;UART_HandleTypeDef huart4;/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM4_Init(void);
static void MX_UART4_Init(void);
static void MX_TIM3_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *///重写标准输出函数
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 10);return ch;
}// 自定义空闲中断处理函�????????
void uart4_idle_func(void)
{int len = 0;//判定 是否为空闲中�????????if( __HAL_UART_GET_FLAG(&huart4, UART_FLAG_IDLE) == SET ){// 清除空闲中断标志,因为是自己定义的函数 系统不会清标__HAL_UART_CLEAR_IDLEFLAG(&huart4);// 计算接收数据的长len = sizeof(rx_buf) - huart4.RxXferCount;//第二个参数是 还剩下的空间// 打印接收到时数据 数据处理//printf("uart rx len = %d, data: %s\r\n",len, rx_buf);// 使用strcpy复制字符�????????strcpy((char *)uart4_data, (char *)rx_buf);printf("%s instructions success\r\n", uart4_data);// 准备接收下一次数�?????????memset(rx_buf,0,len); // 清理接收容器//重置接收指针 剩余容器大小huart4.pRxBuffPtr = rx_buf;huart4.RxXferCount = sizeof(rx_buf);}
}//控制马达
void motor(int d){HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_6);//HAL_Delay(d);
}// 音乐
// 音乐盒基�??????变量
extern int time_100ms_cnt; //0.1s计数�??????
extern int Beat_speed; //节拍速度,代表半个节拍需要多少个0.1s
extern int Beat_speed_n; //实际执行的节拍数extern int Beat_num; //这个�??????个音�??????要多少个 半拍
extern int flag; //当其等于 1 时,表示�??????个音结束
extern int EN_music ; //使能信号,用于开启整个音乐盒
extern int list ; //音乐列表
extern int list_max ; //音乐总数
extern int Low_volume ; //音量大小
extern int Low_volume_cnt;
extern int music_speed_i; //音乐播放速度模式保存
extern int music_speed_kz(int i);int tone[3][8];
//初始化高中低音频�??????
void tone_init(){tone[1][0] = 0; //不执行音�??????tone[1][1] = 191;tone[1][2] = 170;tone[1][3] = 151;tone[1][4] = 143;tone[1][5] = 127;tone[1][6] = 113;tone[1][7] = 101;// 低音 (Low)for (int i = 0; i < 8; i++) {tone[0][i] = tone[1][i] * 2; // 只是低音 近似的�??}// 高音 (High)for (int i = 0; i < 8; i++) {tone[2][i] = tone[1][i] / 2; // 只是高音 近似的�??}
}#define MAX_unit_num 200 //�????????大乐谱数�????????
//创建结构体保存乐�????????
struct music_unit{char name[50]; //乐谱名称int unit[MAX_unit_num]; //发什么音int unit_HL[MAX_unit_num]; //发高音或者其�????????int time[MAX_unit_num]; //发音时间//int time_4[MAX_unit_num]; //判断是否�????????1/4�????????int num; //记录有多少个
}music[25];//创建乐谱 返回有多少首音乐
int music_init(){int cnt = 0;//第一首音�???????? 生日快乐strcpy(music[0].name, "生日快乐"); // 使用strcpy复制字符�???????? 给音乐命�????????int music0_unit[29] = {0,0, 5,5,6,5,1,7, 5,5,6,5,2,1,5,5,6,3,1,7, 6,4,4,3,1,2,1,0,0}; //基础乐谱int music0_time[29] = {1,1, 1,1,2,2,2,3, 1,1,2,2,2,3,2,2,2,2,2,2, 2,2,2,2,2,2,3,1,1}; //乐谱节拍music[0].num = 29; //乐谱总数int music0_unit_HL[29] = {1,1,0,0,0,0,1,0, 0,0,0,0,1,1,0,0,1,1,1,0, 0,1,1,1,1,1,1,1,1}; //乐谱全为中音//第二首音�???????? �????????闪一闪亮晶晶cnt++;strcpy(music[1].name, "�????????闪一闪亮晶晶"); // 使用strcpy复制字符�???????? 给音乐命�????????int music1_unit[44] = {0,1,1,5,5,6,6,5, 4,4,3,3,2,2,1,5,5,4,4,3,3,2, 5,5,4,4,3,3,2,1,1,5,5,6,6,5, 4,4,3,3,2,2,1,0}; //基础乐谱int music1_time[44] = {2,2,2,2,2,2,2,3, 2,2,2,2,2,2,3,2,2,2,2,2,2,3, 2,2,2,2,2,2,3,2,2,2,2,2,2,3, 2,2,2,2,2,2,3,2}; //乐谱节拍int music1_unit_HL[44] ={1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1}; //乐谱全为中音music[1].num = 44; //乐谱总数//第三首音�???????? 两只老虎cnt++;strcpy(music[2].name, "两只老虎"); // 使用strcpy复制字符�???????? 给音乐命�????????int music2_unit[38] = {0,1,2,3,1, 1,2,3,1, 3,4,5,5, 3,4,5,5,5,6,5,4, 3,1,5,6, 5,4,3,1, 1,5,1,1,1,5,1,1, 0}; //基础乐谱int music2_time[38] = {2,1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,0,0,0,0, 1,1,0,0, 0,0,1,1, 1,1,1,2,1,1,1,2, 2}; //乐谱节拍int music2_unit_HL[38] ={1,1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,1,1,1,0,1,1, 1}; //乐谱�???????? 中音music[2].num = 38; //乐谱总数//第四首音�???????? 青花瓷片�????????cnt++;strcpy(music[3].name, "青花瓷片"); // 使用strcpy复制字符�???????? 给音乐命�????????int music3_unit[100] = {0,0,0,0, 0,5,5,3, 2,3,6,2, 3,5,3,2, 2,5,5,3,2,3,5,2, 3,5,2,1, 1,1,2,3, 5,6,5,4, 5,3,3,2,2,2,1,2, 1,1,2,1, 2,3,5,3, 3,3,5,5, 3,2,3,6,2,3,5,3, 2,2,5,5, 3,2,3,5, 2,3,5,2, 1,1,1,2,3,5,6,5, 4,5,3,3, 2,2,5,3, 2,2,2,1, 1,0,0,0}; //基础乐谱int music3_time[100] = {0,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,2, 0,0,0,0,0,0,1,0, 0,0,0,2, 0,0,0,0, 0,0,0,0, 0,0,0,0,2,0,0,0, 0,0,0,0, 0,1,0,0, 2,0,0,0, 0,0,0,1,0,0,0,0, 2,0,0,0, 0,0,0,1, 0,0,0,0, 2,0,0,0,0,0,0,0, 0,0,0,0, 0,2,0,1, 0,0,0,1, 2,1,1,1}; //乐谱节拍for(int i =0;i<100;i++)music3_time[i] = music3_time[i]+1;int music3_unit_HL[100] ={ 1,1,1,1, 1,1,1,1, 1,1,0,1, 1,1,1,1, 1,1,1,1,1,1,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,0,1,1,1,1, 1,1,1,1, 1,1,1,0, 1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1, 1,1,0,1, 1,1,1,1, 1,1,1,1}; //乐谱�???????? 中音music[3].num = 100; //乐谱总数for (int i = 0; i < MAX_unit_num; i++) {//将乐谱保存进结构�????????if(i<music[0].num){//确保数据正确music[0].unit[i] =music0_unit[i];music[0].unit_HL[i] =music0_unit_HL[i];music[0].time[i] =music0_time[i];}//将乐谱保存进结构�????????if(i<music[1].num){//确保数据正确music[1].unit[i] =music1_unit[i];music[1].unit_HL[i] =music1_unit_HL[i];music[1].time[i] =music1_time[i];}//将乐谱保存进结构�????????if(i<music[2].num){//确保数据正确music[2].unit[i] =music2_unit[i];music[2].unit_HL[i] =music2_unit_HL[i];music[2].time[i] =music2_time[i];}//将乐谱保存进结构�????????if(i<music[3].num){//确保数据正确music[3].unit[i] =music3_unit[i];music[3].unit_HL[i] =music3_unit_HL[i];music[3].time[i] =music3_time[i];}}return cnt;
}//播放�???? N首音�???? 音量�???? X 0 - 100
void play_music(int n, int x){static int ni = 0; //用于判断 是否换了音乐static int cnt = 0; //记录播放到哪�????�???? 音节if(ni != n ){//如果音乐换了ni = n;cnt = 0;__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量HAL_Delay(1000);//}//int value = tone[music[n].unit_HL[cnt]][music[n].unit[cnt]]; //获取频率if(flag == 1){ //接受到一个音节结�????flag = 0; //复位Beat_num = music[n].time[cnt]; //这个音需要多少个半拍//LED_BEEP(music[n].unit[cnt]); //LED随音节变动�?�变�????if(music[n].time[cnt] == 0){//如果�???? 1/4�????Beat_speed_n = Beat_speed /2;}else{//如果没有1/4�????Beat_speed_n = Beat_speed;}//if(value != 0)//如果有频率�?�执行,没有者只更新 时间�????__HAL_TIM_SET_AUTORELOAD(&htim4,value); //自动加载频率�????cnt ++; //可进行下�????次音�????if(cnt >= music[n].num){ //如果�????个音节播放完�????cnt = 0;//重新播放//__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量//HAL_Delay(500);//}}//__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,x * (value/100));//设置音量__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,(value/10)*x);//设置音量
}//串口音乐控制函数
void music_kz(){if(EN_music == 1)//启动play_music(list,Low_volume);else__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量if(strcmp("music volume increase",(char *)uart4_data)==0){uart4_data[0] = '0';Low_volume = Low_volume + Low_volume_cnt;if(Low_volume >= 10)Low_volume = 10;}if(strcmp("music volume reduction",(char *)uart4_data)==0){Low_volume = Low_volume - Low_volume_cnt;if(Low_volume <= 0)Low_volume = 0;}if(strcmp("music speed increase",(char *)uart4_data)==0){uart4_data[0] = '0';music_speed_i++;music_speed_i = music_speed_kz(music_speed_i);}if(strcmp("music speed reduction",(char *)uart4_data)==0){uart4_data[0] = '0';music_speed_i--;music_speed_i = music_speed_kz(music_speed_i);}if(strcmp("music next song",(char *)uart4_data)==0){uart4_data[0] = '0';list++;if(list > list_max){list = list_max;}}if(strcmp("music previous song",(char *)uart4_data)==0){list--;uart4_data[0] = '0';if(list < 0){list = 0;}}if(strcmp("music start",(char *)uart4_data)==0){EN_music = 1;}if(strcmp("music stop",(char *)uart4_data)==0){EN_music = 0;}}//数码管闹�?????
extern int buf[8];
extern int shi_shi;
extern int shi_ge ;
extern int fen_shi;
extern int fen_ge ;
extern int miao_shi ;
extern int miao_ge ;extern int miao ;
extern int shi ;
extern int fen;
//闹钟保存数组
extern int alarm_clock_array[20][4];
extern int alarm_clock_array_cnt;//通过输入不同的n,返回shi fen miao
int clock_compute(int time_shi,int time_fen,int time_miao,int add_shi,int add_fen,int add_miao,int n){time_miao = time_miao + add_miao;time_fen = time_fen + time_miao/60;time_miao = time_miao % 60;time_fen = time_fen + add_fen;time_shi = time_shi + time_fen / 60;time_fen = time_fen%60;time_shi = time_shi + add_shi;time_shi = time_shi%24;if(n == 0) return time_shi;if(n == 1) return time_fen;if(n == 2) return time_miao;return -1;
}//将字符解成数�?????
int char_number(uint8_t c){if(c >= '0' && c <= '9')return c-'0';elsereturn -1;
}// zfc 为当前传入字符串
// zfc_n为比较字符串
// num为如果两字符串最初相等,则取字符串后面多少位的数�?????
int number_char_come(uint8_t zfc[200], uint8_t zfc_n[200], int num){size_t len = strlen((char *)zfc_n);//无符号整数类�?????int cnt = 0;for(int i = 0;i < len;i++){if(zfc[i] != zfc_n[i]) return -1; //不相�?????else cnt++;}if(cnt != len) return -1;//两字符串不等size_t shen_len = strlen((char *)zfc) - len;//剩余字符串长�?????size_t hig_num = 0;//用以保存实际有效位数if(shen_len > num) hig_num = num;else hig_num = shen_len;//int number[200];int number1 = 0;int multiplier = 1; // 用于计算10的幂的变�?????for(int i = len + hig_num - 1; i >= len;i--){//number[i-len] = char_number(zfc[i]);if(char_number(zfc[i])== -1) {printf("\r\r\r number error\r\n");return -1;}multiplier = multiplier*10;number1 = number1 + char_number(zfc[i])*multiplier;}return number1;}// 函数定义:从字符串中提取两位数字
int extract_two_digits(const char *str, const char *prefix, int *value) {char *pos = strstr(str, prefix); // 查找前缀的位�?????if (pos == NULL) return 0; // 如果没找到前�?????,返�?????0表示失败// 跳过前缀的长度,找到数字�?????始的位置pos += strlen(prefix);// �?????查接下来的两个字符是否是数字if (pos[0] >= '0' && pos[0] <= '9' && pos[1] >= '0' && pos[1] <= '9') {// 转换字符为数�?????*value = (pos[0] - '0') * 10 + (pos[1] - '0');return 1; // 成功提取,返�?????1}return 0; // 提取失败,返�?????0
}//判断是否到底闹钟
int en_clock = 0;//用于控制闹钟响铃
int en_clock_cnt = 0;
int clock_end[3] = {0};//记录闹钟无人时关闭的时间
//串口设置闹钟
void uart_clock(){int ci = 0;int ci_n = 0;//ci = number_char_come(uart4_data,(uint8_t *)"clock shi = ",2);ci = extract_two_digits((char *)uart4_data, (char *)"clock shi = ", &ci_n);if(ci == 1){uart4_data[0] = '1';shi = ci_n;}//ci = number_char_come(uart4_data,(uint8_t *)"clock fen = ",2);ci = extract_two_digits((char *)uart4_data, (char *)"clock fen = ", &ci_n);if(ci == 1){uart4_data[0] = '1';fen = ci_n;}//ci = number_char_come(uart4_data,(uint8_t *)"clock miao = ",2);ci = extract_two_digits((char *)uart4_data, (char *)"clock miao = ", &ci_n);if(ci == 1){uart4_data[0] = '1';miao = ci_n;}//设置�?????个多少时间后的闹�?????//ci = number_char_come(uart4_data,(uint8_t *)"clock delay shi = ",2);ci = extract_two_digits((char *)uart4_data, "clock delay shi = ", &ci_n);if(ci == 1){uart4_data[0] = '1';alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,ci_n,0,0,0);alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,ci_n,0,0,1);alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,ci_n,0,0,2);alarm_clock_array_cnt++;}//ci = number_char_come(uart4_data,(uint8_t *)"clock delay fen = ",2);ci = extract_two_digits((char *)uart4_data, "clock delay fen = ", &ci_n);if(ci == 1){uart4_data[0] = '1';alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,ci_n,0,0);alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,ci_n,0,1);alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,ci_n,0,2);alarm_clock_array_cnt++;}ci = extract_two_digits((char *)uart4_data, "clock delay miao = ", &ci_n);if(ci == 1){uart4_data[0] = '1';alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,0,ci_n,0);alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,0,ci_n,1);alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,0,ci_n,2);alarm_clock_array_cnt++;}// time shi = 12;fen = 10;miao = 12;music = 1;ci = 0;ci = ci + extract_two_digits((char *)uart4_data, "time shi = ", &alarm_clock_array[alarm_clock_array_cnt][0]);ci = ci + extract_two_digits((char *)uart4_data, ";fen = ", &alarm_clock_array[alarm_clock_array_cnt][1]);ci = ci + extract_two_digits((char *)uart4_data, ";miao = ", &alarm_clock_array[alarm_clock_array_cnt][2]);//ci = ci + extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][2]);if(ci == 3){//完美对应uart4_data[0] = '1';ci = extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][3]);if(ci > list_max && ci<0) //如果大于音乐总数alarm_clock_array[alarm_clock_array_cnt][3] = 3;//默认�?????3alarm_clock_array_cnt++;}if(strcmp("clock delay list",(char *)uart4_data)==0){uart4_data[0] = '0';for(int i = 0; i< alarm_clock_array_cnt;i++){if(alarm_clock_array[i][0] != -1 && alarm_clock_array[i][1] != -1 && alarm_clock_array[i][2] != -1)printf("%d : time -> %d/%d/%d \r\n",i, alarm_clock_array[i][0],alarm_clock_array[i][1],alarm_clock_array[i][2]);}}//读取关闭第几位闹�?????//ci = number_char_come(uart4_data,(uint8_t *)"clock stop list = ",2);ci = extract_two_digits((char *)uart4_data, "clock stop list = ", &ci_n);if(ci == 1){alarm_clock_array[ci_n][0] = -1;alarm_clock_array[ci_n][1] = -1;alarm_clock_array[ci_n][2] = -1;}//关闭闹钟if(strcmp("clock stop stop",(char *)uart4_data)==0){en_clock = 0;}if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;
}
void smg_xians(){}void alarm_clock(){static int pos = 0;HAL_I2C_Mem_Write(&hi2c1,0x70,0X10+pos, 1, (uint8_t*)&buf[pos],1,100);HAL_Delay(1);pos++;if(pos == 3 && pos == 6) pos++;if(pos == 8) pos = 0;uart_clock();//调用串口控制for(int j=0;j<alarm_clock_array_cnt && en_clock == 0;j++){//int cnt_clock = 0;if(alarm_clock_array[j][0] == shi && alarm_clock_array[j][1] == fen && alarm_clock_array[j][2] == miao) {en_clock_cnt = j;en_clock = 1;clock_end[0] = clock_compute(shi,fen,miao,0,0,30,0);clock_end[1] = clock_compute(shi,fen,miao,0,0,30,1);clock_end[2] = clock_compute(shi,fen,miao,0,0,30,2);break;}}//当闹钟响�?????30Sif(shi == clock_end[0] && fen == clock_end[1] && miao == clock_end[2]){en_clock = 0;//关闭闹钟//EN_music = 1;}if(en_clock == 1 ){motor(10);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);}}uint8_t add1=0xFE,add2=0xE5,add3=0xE3;
//0xFE复位 0xE5启动湿度转换 0xE3启动温度转换
uint16_t RH_Code,RH_Code_low=0,RH_Code_high=0;
uint16_t Temp_Code,Temp_Code_low=0,Temp_Code_high=0;int humidity_min = 50;//能仍受的�?????低干燥程�?????
int temperature_max = 50;//能仍受的�?????高温�?????
int en_t = 0; //温度使能
int en_r = 0; //湿度使能//计算出温湿度
void Temperature_humidity(){//湿度HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add2, 1,100);//写命�??????? ox40里面写命�??????? 0xe5 启动湿度转换HAL_I2C_Master_Receive(&hi2c1, 0x81, &RH_Code, 1, 100);//读命�??????? �???????0x40读取出湿度的数据 存入变量RH_CODEHAL_Delay(30);//进行高低字节转换RH_Code_low=(RH_Code & 0xff);RH_Code_high=(RH_Code >> 8)& 0xff;RH_Code=(RH_Code_low << 8)+RH_Code_high;//温度HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add3, 1,100);HAL_I2C_Master_Receive(&hi2c1, 0x81, &Temp_Code, 1, 100);//读命�??????? �???????0x40读取出温度的数据 存入变量Temp_CODEHAL_Delay(30);//进行高低字节转换Temp_Code_low=(Temp_Code & 0xff);Temp_Code_high=(Temp_Code >> 8)& 0xff;Temp_Code=(Temp_Code_low << 8)+Temp_Code_high;Temp_Code=17572*Temp_Code/65535-4685;//扩大�???????百�??RH_Code=125*RH_Code/65536-6;//计算出湿度�??//printf("Temp_Code = \r%d.%d RH_Code = %d%%\n",Temp_Code/100,Temp_Code%100,RH_Code%100);//串口输出温湿�???????HAL_Delay(2);
}void uart_sensor(){int tr=0;int tr_i = 0;tr = extract_two_digits((char *)uart4_data, "sensor humidity_min = ", &tr_i);if(tr != 0){humidity_min = tr_i;}tr = extract_two_digits((char *)uart4_data, "sensor temperature_max = ", &tr_i);if(tr != 0){temperature_max = tr_i;}if(strcmp("sensor temperature start",(char *)uart4_data)==0){en_t = 1;}if(strcmp("sensor humidity start",(char *)uart4_data)==0){en_r = 1;}if(strcmp("sensor temperature stop",(char *)uart4_data)==0){en_t = 0;}if(strcmp("sensor humidity stop",(char *)uart4_data)==0){en_r = 0;}if(strcmp("sensor list",(char *)uart4_data)==0){uart4_data[0] = '0';printf("Temp_Code = \r%d.%d RH_Code = %d%%\r\n",Temp_Code/100,Temp_Code%100,RH_Code%100);printf("sensor en_t : %d\r\n",en_t);printf("sensor en_r : %d\r\n",en_r);printf("sensor temperature_max : %d\r\n",temperature_max);printf("sensor humidity_min : %d\r\n",humidity_min);}if(strcmp("sensor Temp_Code RH_Code",(char *)uart4_data)==0){uart4_data[0] = '0';printf("Temp_Code = \r%d.%d RH_Code = %d%%\n",Temp_Code/100,Temp_Code%100,RH_Code%100);}}void sensor(){static int iii = 0;if(iii == 0){HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add1, 1, 100);HAL_Delay(2);iii++;}Temperature_humidity();uart_sensor();if(RH_Code < humidity_min && en_r == 1){//motor(10);HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_RESET);}if(Temp_Code/100 >= temperature_max && en_t == 1){HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_RESET);}
}uint8_t DZP_data[6][34]={{0xAA,0x55,0xFD,0xFF,0xFE,0xFF,0xC0,0x07,0xFF,0xFF,0xF7,0xDF,0xFB,0xBF,0x00,0x01,0xFF,0xFF,0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF},//�?//0//{0xAA,0x55,0xEF,0xDF,0xEF,0xDF,0xC3,0xDF,0xDF,0xDF,0xBE,0x03,0x42,0xDB,0xEE,0xDB,0xEE,0xDB,0x02,0xDB,0xEE,0x03,0xEE,0xDB,0xEF,0xDF,0xEB,0xDF,0xE7,0xDF,0xEF,0xDF,0xFF,0xDF},//�?//1//{0xAA,0x55,0xF7,0xBF,0xF7,0xBF,0xF7,0xBF,0xEC,0x07,0xEF,0xBF,0xCF,0x7F,0xC8,0x01,0xAF,0x7F,0x6E,0xFF,0xEC,0x07,0xEF,0xF7,0xEE,0xEF,0xEF,0x5F,0xEF,0xBF,0xEF,0xDF,0xEF,0xDF}//�?//2//};void uart_mode(){if(strcmp("mode = music",(char *)uart4_data)==0){mode = 0;}if(strcmp("mode = clock",(char *)uart4_data)==0){mode = 1;}if(strcmp("mode = sensor",(char *)uart4_data)==0){mode = 2;}
}
void end_main(){tone_init(); //初始化音量频�??????list_max = music_init();//更新乐谱HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //启动蜂鸣器定时器HAL_TIM_Base_Start_IT(&htim2); //启动定时�??????2HAL_TIM_Base_Start_IT(&htim3); //启动定时�??????2//1 使能串口空闲中断__HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);//2.使能串口中断接收数据HAL_UART_Receive_IT(&huart4,rx_buf,sizeof(rx_buf));int mode_n = 1;while(1){music_kz();alarm_clock();uart_mode();sensor();if(mode_n != mode){mode_n = mode;for(int i = 0; i<34;i++){//printf("afgsbgafdffag");HAL_I2C_Master_Transmit(&hi2c1, 0xA0 , (uint8_t*)&DZP_data[mode][i], 1, 300);HAL_Delay(2);}}}
}
/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init */if(IS_ENGINEERING_BOOT_MODE()){/* Configure the system clock */SystemClock_Config();}/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C1_Init();MX_TIM2_Init();MX_TIM4_Init();MX_UART4_Init();MX_TIM3_Init();/* USER CODE BEGIN 2 */end_main();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///printf("afsgbhdn\t\n");//HAL_Delay(500);}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = 16;RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1;RCC_OscInitStruct.LSIState = RCC_LSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE;RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE;RCC_OscInitStruct.PLL4.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** RCC Clock Config*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_ACLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2|RCC_CLOCKTYPE_PCLK3|RCC_CLOCKTYPE_PCLK4|RCC_CLOCKTYPE_PCLK5;RCC_ClkInitStruct.AXISSInit.AXI_Clock = RCC_AXISSOURCE_HSI;RCC_ClkInitStruct.AXISSInit.AXI_Div = RCC_AXI_DIV1;RCC_ClkInitStruct.MCUInit.MCU_Clock = RCC_MCUSSOURCE_HSI;RCC_ClkInitStruct.MCUInit.MCU_Div = RCC_MCU_DIV1;RCC_ClkInitStruct.APB4_Div = RCC_APB4_DIV1;RCC_ClkInitStruct.APB5_Div = RCC_APB5_DIV1;RCC_ClkInitStruct.APB1_Div = RCC_APB1_DIV1;RCC_ClkInitStruct.APB2_Div = RCC_APB2_DIV1;RCC_ClkInitStruct.APB3_Div = RCC_APB3_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK){Error_Handler();}
}/*** @brief I2C1 Initialization Function* @param None* @retval None*/
static void MX_I2C1_Init(void)
{/* USER CODE BEGIN I2C1_Init 0 *//* USER CODE END I2C1_Init 0 *//* USER CODE BEGIN I2C1_Init 1 *//* USER CODE END I2C1_Init 1 */hi2c1.Instance = I2C1;hi2c1.Init.Timing = 0x10707DBC;hi2c1.Init.OwnAddress1 = 0;hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;hi2c1.Init.OwnAddress2 = 0;hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;if (HAL_I2C_Init(&hi2c1) != HAL_OK){Error_Handler();}/** Configure Analogue filter*/if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK){Error_Handler();}/** Configure Digital filter*/if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK){Error_Handler();}/* USER CODE BEGIN I2C1_Init 2 *//* USER CODE END I2C1_Init 2 */}/*** @brief TIM2 Initialization Function* @param None* @retval None*/
static void MX_TIM2_Init(void)
{/* USER CODE BEGIN TIM2_Init 0 *//* USER CODE END TIM2_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};/* USER CODE BEGIN TIM2_Init 1 *//* USER CODE END TIM2_Init 1 */htim2.Instance = TIM2;htim2.Init.Prescaler = 6400-1;htim2.Init.CounterMode = TIM_COUNTERMODE_UP;htim2.Init.Period = 1000-1;htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim2) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM2_Init 2 *//* USER CODE END TIM2_Init 2 */}/*** @brief TIM3 Initialization Function* @param None* @retval None*/
static void MX_TIM3_Init(void)
{/* USER CODE BEGIN TIM3_Init 0 *//* USER CODE END TIM3_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};/* USER CODE BEGIN TIM3_Init 1 *//* USER CODE END TIM3_Init 1 */htim3.Instance = TIM3;htim3.Init.Prescaler = 6399;htim3.Init.CounterMode = TIM_COUNTERMODE_UP;htim3.Init.Period = 10000-1;htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim3) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM3_Init 2 *//* USER CODE END TIM3_Init 2 */}/*** @brief TIM4 Initialization Function* @param None* @retval None*/
static void MX_TIM4_Init(void)
{/* USER CODE BEGIN TIM4_Init 0 *//* USER CODE END TIM4_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfigOC = {0};/* USER CODE BEGIN TIM4_Init 1 *//* USER CODE END TIM4_Init 1 */htim4.Instance = TIM4;htim4.Init.Prescaler = 639;htim4.Init.CounterMode = TIM_COUNTERMODE_UP;htim4.Init.Period = 100-1;htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim4) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_Init(&htim4) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK){Error_Handler();}sConfigOC.OCMode = TIM_OCMODE_PWM1;sConfigOC.Pulse = 0;sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM4_Init 2 *//* USER CODE END TIM4_Init 2 */HAL_TIM_MspPostInit(&htim4);}/*** @brief UART4 Initialization Function* @param None* @retval None*/
static void MX_UART4_Init(void)
{/* USER CODE BEGIN UART4_Init 0 *//* USER CODE END UART4_Init 0 *//* USER CODE BEGIN UART4_Init 1 *//* USER CODE END UART4_Init 1 */huart4.Instance = UART4;huart4.Init.BaudRate = 115200;huart4.Init.WordLength = UART_WORDLENGTH_8B;huart4.Init.StopBits = UART_STOPBITS_1;huart4.Init.Parity = UART_PARITY_NONE;huart4.Init.Mode = UART_MODE_TX_RX;huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart4.Init.OverSampling = UART_OVERSAMPLING_16;huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;if (HAL_UART_Init(&huart4) != HAL_OK){Error_Handler();}if (HAL_UARTEx_SetTxFifoThreshold(&huart4, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK){Error_Handler();}if (HAL_UARTEx_SetRxFifoThreshold(&huart4, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK){Error_Handler();}if (HAL_UARTEx_DisableFifoMode(&huart4) != HAL_OK){Error_Handler();}/* USER CODE BEGIN UART4_Init 2 *//* USER CODE END UART4_Init 2 */}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOF_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOI_CLK_ENABLE();__HAL_RCC_GPIOG_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOE_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1|GPIO_PIN_6, GPIO_PIN_RESET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_RESET);/*Configure GPIO pins : PF1 PF6 */GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_6;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);/*Configure GPIO pin : PC7 */GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pins : PI11 PI10 */GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);/*Configure GPIO pins : PG2 PG0 PG1 */GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);/*Configure GPIO pin : PE9 */GPIO_InitStruct.Pin = GPIO_PIN_9;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI0_IRQn, 3, 0);HAL_NVIC_EnableIRQ(EXTI0_IRQn);HAL_NVIC_SetPriority(EXTI1_IRQn, 3, 0);HAL_NVIC_EnableIRQ(EXTI1_IRQn);HAL_NVIC_SetPriority(EXTI2_IRQn, 3, 0);HAL_NVIC_EnableIRQ(EXTI2_IRQn);HAL_NVIC_SetPriority(EXTI9_IRQn, 2, 0);HAL_NVIC_EnableIRQ(EXTI9_IRQn);}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
stm32mp1xx_it.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file stm32mp1xx_it.c* @brief Interrupt Service Routines.******************************************************************************* @attention** <h2><center>© Copyright (c) 2024 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32mp1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
int mode = 0; //模式
extern void uart4_idle_func(void);
extern void smg_xians();
// 音乐盒基�?????变量
int time_100ms_cnt = 0; //0.1s计数�?????
int Beat_speed = 5; //节拍速度,代表半个节拍需要多少个0.1s
int Beat_speed_n = 0; //实际执行的节拍数int Beat_num = 2; //这个�?????个音�?????要多少个 半拍
int flag = 0; //当其等于 1 时,表示�?????个音结束
int EN_music = 0; //使能信号,用于开启整个音乐盒
int list = 0; //音乐列表
int list_max = 0; //音乐总数
int Low_volume = 5; //音量大小
int Low_volume_cnt = 3; //音量大小增加�?????
int music_speed_i = 0; //音乐播放速度模式保存
// 音乐播放速度控制函数
int music_speed_kz(int i){//倍数计算公式 1 + (1 - (新的节拍速度 / 原来的节拍�?�度))switch(i){case 0:{Beat_speed = 5; //0.5s半个节拍,正�?????+�??????�度break;}case 1:{Beat_speed = 4; //1.2倍数break;}case 2:{Beat_speed = 3; //约等�??????? 1.5倍数break;}case 3:{Beat_speed = 1; //约等�??????? 2 倍数break;}case 4:{Beat_speed = 6; //约等�??????? 0.8 倍数break;}case 5:{Beat_speed = 7; //约等�??????? 0.6 倍数break;}default:{Beat_speed = 5; //0.5s半个节拍,正常�?�度i=0;break;}}return i;
}//数码管闹�????
int smg_number[10] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xE0,0xFE,0xF6};
int buf[8] = {0};//闹钟保存数组
int alarm_clock_array[20][4] = {0};
int alarm_clock_array_cnt = 0;
//实时时钟信息
int shi_shi = 0;
int shi_ge = 0;
int fen_shi = 0;
int fen_ge = 0;
int miao_shi = 0;
int miao_ge = 0;
int miao = 0;
int shi = 0;
int fen = 0;int EN_clock = 0;//闹钟设置使能
extern int en_clock;//用于控制闹钟响铃//闹钟设置信息
int shi_shi_clock = 0;
int shi_ge_clock = 0;
int fen_shi_clock = 0;
int fen_ge_clock = 0;
int miao_shi_clock = 0;
int miao_ge_clock = 0;
int miao_clock = 0, shi_clock = 0, fen_clock = 0;/* USER CODE END TD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
extern UART_HandleTypeDef huart4;
/* USER CODE BEGIN EV *//* USER CODE END EV *//******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/*** @brief This function handles Non maskable interrupt.*/
void NMI_Handler(void)
{/* USER CODE BEGIN NonMaskableInt_IRQn 0 *//* USER CODE END NonMaskableInt_IRQn 0 *//* USER CODE BEGIN NonMaskableInt_IRQn 1 */while (1){}/* USER CODE END NonMaskableInt_IRQn 1 */
}/*** @brief This function handles Hard fault interrupt.*/
void HardFault_Handler(void)
{/* USER CODE BEGIN HardFault_IRQn 0 *//* USER CODE END HardFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_HardFault_IRQn 0 *//* USER CODE END W1_HardFault_IRQn 0 */}
}/*** @brief This function handles Memory management fault.*/
void MemManage_Handler(void)
{/* USER CODE BEGIN MemoryManagement_IRQn 0 *//* USER CODE END MemoryManagement_IRQn 0 */while (1){/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 *//* USER CODE END W1_MemoryManagement_IRQn 0 */}
}/*** @brief This function handles Pre-fetch fault, memory access fault.*/
void BusFault_Handler(void)
{/* USER CODE BEGIN BusFault_IRQn 0 *//* USER CODE END BusFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_BusFault_IRQn 0 *//* USER CODE END W1_BusFault_IRQn 0 */}
}/*** @brief This function handles Undefined instruction or illegal state.*/
void UsageFault_Handler(void)
{/* USER CODE BEGIN UsageFault_IRQn 0 *//* USER CODE END UsageFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_UsageFault_IRQn 0 *//* USER CODE END W1_UsageFault_IRQn 0 */}
}/*** @brief This function handles System service call via SWI instruction.*/
void SVC_Handler(void)
{/* USER CODE BEGIN SVCall_IRQn 0 *//* USER CODE END SVCall_IRQn 0 *//* USER CODE BEGIN SVCall_IRQn 1 *//* USER CODE END SVCall_IRQn 1 */
}/*** @brief This function handles Debug monitor.*/
void DebugMon_Handler(void)
{/* USER CODE BEGIN DebugMonitor_IRQn 0 *//* USER CODE END DebugMonitor_IRQn 0 *//* USER CODE BEGIN DebugMonitor_IRQn 1 *//* USER CODE END DebugMonitor_IRQn 1 */
}/*** @brief This function handles Pendable request for system service.*/
void PendSV_Handler(void)
{/* USER CODE BEGIN PendSV_IRQn 0 *//* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */
}/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 *//* USER CODE END SysTick_IRQn 1 */
}/******************************************************************************/
/* STM32MP1xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32mp1xx.s). */
/******************************************************************************//*** @brief This function handles EXTI line0 interrupt.*/
void EXTI0_IRQHandler(void)
{/* USER CODE BEGIN EXTI0_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == 0 && mode == 0)//确保数据稳定{//每次按下解决 音量�??????? Low_volume_cntLow_volume = Low_volume + Low_volume_cnt;if(Low_volume >= 10)Low_volume = 0;}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0)==GPIO_PIN_RESET && mode == 1) {shi_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;if(shi_clock>=24){shi_clock=0;}miao_shi_clock=miao_clock/10;miao_ge_clock=miao_clock%10;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;buf[0]=smg_number[shi_shi_clock];buf[1]=smg_number[shi_ge_clock];buf[3]=smg_number[fen_shi_clock];buf[4]=smg_number[fen_ge_clock];buf[6]=smg_number[miao_shi_clock];buf[7]=smg_number[miao_ge_clock];}/* USER CODE END EXTI0_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);/* USER CODE BEGIN EXTI0_IRQn 1 *//* USER CODE END EXTI0_IRQn 1 */
}/*** @brief This function handles EXTI line1 interrupt.*/
void EXTI1_IRQHandler(void)
{/* USER CODE BEGIN EXTI1_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_1) == 0 && mode == 0)//确保数据稳定{music_speed_i++;music_speed_i = music_speed_kz(music_speed_i);}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_1)==GPIO_PIN_RESET && mode == 1) {fen_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;if(fen_clock>=60){fen_clock=0;shi_clock++;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;if(shi_clock>=24){shi_clock=0;}}miao_shi_clock=miao_clock/10;miao_ge_clock=miao_clock%10;fen_shi_clock=fen_clock/10;fen_ge_clock=fen_clock%10;shi_shi_clock=shi_clock/10;shi_ge_clock=shi_clock%10;buf[0]=smg_number[shi_shi_clock];buf[1]=smg_number[shi_ge_clock];buf[3]=smg_number[fen_shi_clock];buf[4]=smg_number[fen_ge_clock];buf[6]=smg_number[miao_shi_clock];buf[7]=smg_number[miao_ge_clock];}/* USER CODE END EXTI1_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);/* USER CODE BEGIN EXTI1_IRQn 1 *//* USER CODE END EXTI1_IRQn 1 */
}/*** @brief This function handles EXTI line2 interrupt.*/
void EXTI2_IRQHandler(void)
{/* USER CODE BEGIN EXTI2_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_2) == 0 && mode == 0)//确保数据稳定{list++;if(list > list_max){list = 0;}}if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_2)==GPIO_PIN_RESET && mode == 1) {//在此处关闭闹�????en_clock = 0;}/* USER CODE END EXTI2_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);/* USER CODE BEGIN EXTI2_IRQn 1 *//* USER CODE END EXTI2_IRQn 1 */
}/*** @brief This function handles TIM2 global interrupt.*/
void TIM2_IRQHandler(void)
{/* USER CODE BEGIN TIM2_IRQn 0 */if(EN_music == 1)time_100ms_cnt++;elsetime_100ms_cnt = time_100ms_cnt; //其余状�?�不计数if(time_100ms_cnt >= Beat_speed_n * Beat_num){ //这个音节结束time_100ms_cnt = 0;flag = 1; //发�?�音节结束信�???????}//数码�????static int smg_time_100ms = 0;smg_time_100ms++;if(smg_time_100ms>=10){miao++;smg_time_100ms = 0;}if (miao>=60){miao=0;fen++;if(fen>=60){fen=0;shi++;if(shi>=24){shi=0;}}}if(miao >= 60){miao = miao-60;fen++;}if(fen>=60){fen = fen-60;shi ++;}if(shi>= 24){shi = shi -24;}miao_shi=miao/10;miao_ge=miao%10;fen_shi=fen/10;fen_ge=fen%10;shi_shi=shi/10;shi_ge=shi%10;if(EN_clock == 0){buf[0]=smg_number[shi_shi];buf[1]=smg_number[shi_ge];buf[3]=smg_number[fen_shi];buf[4]=smg_number[fen_ge];buf[6]=smg_number[miao_shi];buf[7]=smg_number[miao_ge];HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_RESET);//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);//HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET);//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);//HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_SET);}/* USER CODE END TIM2_IRQn 0 */HAL_TIM_IRQHandler(&htim2);/* USER CODE BEGIN TIM2_IRQn 1 *//* USER CODE END TIM2_IRQn 1 */
}/*** @brief This function handles TIM3 global interrupt.*/
void TIM3_IRQHandler(void)
{/* USER CODE BEGIN TIM3_IRQn 0 */smg_xians();/* USER CODE END TIM3_IRQn 0 */HAL_TIM_IRQHandler(&htim3);/* USER CODE BEGIN TIM3_IRQn 1 *//* USER CODE END TIM3_IRQn 1 */
}/*** @brief This function handles UART4 global interrupt.*/
void UART4_IRQHandler(void)
{/* USER CODE BEGIN UART4_IRQn 0 */uart4_idle_func();/* USER CODE END UART4_IRQn 0 */HAL_UART_IRQHandler(&huart4);/* USER CODE BEGIN UART4_IRQn 1 *//* USER CODE END UART4_IRQn 1 */
}/*** @brief This function handles EXTI line9 interrupt.*/
void EXTI9_IRQHandler(void)
{/* USER CODE BEGIN EXTI9_IRQn 0 */if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 0){//确保数据稳定EN_music = !EN_music;}if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 1 ){//确保数据稳定if(EN_clock == 1){//闹钟设置成功alarm_clock_array[alarm_clock_array_cnt][0] = shi_clock;alarm_clock_array[alarm_clock_array_cnt][1] = fen_clock;alarm_clock_array[alarm_clock_array_cnt][2] = miao_clock;alarm_clock_array[alarm_clock_array_cnt][3] = 3; //默认播放第三首音�????alarm_clock_array_cnt++;if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;EN_clock = 0;}else if(EN_clock == 0){//设置闹钟shi_shi_clock = shi_shi;shi_ge_clock = shi_ge;fen_shi_clock = fen_shi;fen_ge_clock = fen_ge;miao_shi_clock = 0;miao_ge_clock = 0;miao_clock = 0;shi_clock = shi;fen_clock = fen;EN_clock = 1;}}/* USER CODE END EXTI9_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);/* USER CODE BEGIN EXTI9_IRQn 1 *//* USER CODE END EXTI9_IRQn 1 */
}/*** @brief This function handles RCC wake-up interrupt.*/
void RCC_WAKEUP_IRQHandler(void)
{/* USER CODE BEGIN RCC_WAKEUP_IRQn 0 *//* USER CODE END RCC_WAKEUP_IRQn 0 */HAL_RCC_WAKEUP_IRQHandler();/* USER CODE BEGIN RCC_WAKEUP_IRQn 1 *//* USER CODE END RCC_WAKEUP_IRQn 1 */
}/* USER CODE BEGIN 1 *//* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
串口指令集
mode = music
mode = clock
mode = sensormusic volume increase
music volume reduction
music speed increase
music speed reduction
music next song
music previous song
music start
music stopclock shi =
clock fen =
clock miao =
clock delay shi =
clock delay fen =
clock delay miao = time shi = ;fen = ;miao =
clock delay list
clock stop list =
clock stop stopsensor humidity_min =
sensor temperature_max =
sensor temperature start
sensor humidity start
sensor temperature stop
sensor humidity stop
sensor list
sensor Temp_Code RH_Code
六、部分效果展示
STM32杂交版
七、总结
本设计是一个高度集成的基于STM32MP157A单片机的多功能系统,通过整合蜂鸣器、数码管、点阵屏、温湿度传感器、LED灯、按键等多种模块,实现了丰富的交互与功能。系统利用STM32CUBEIDE作为开发平台,充分发挥了STM32MP157A单片机的高性能与灵活性,展现了其在嵌入式系统设计中的广泛应用潜力。
设计总结:
-
模块化设计:本设计采用了模块化设计思路,将不同功能模块(如闹钟、音乐盒、温湿度监测)独立设计后整合在一起,不仅提高了系统的可维护性和可扩展性,还使得各个模块的功能实现更加清晰明了。
-
灵活的模式切换:通过串口通信实现不同模式(闹钟、音乐盒、温湿度监测)之间的灵活切换,使得用户可以根据需要轻松选择所需功能,提高了系统的用户友好性和实用性。
-
多样化的显示与交互:点阵屏在不同模式下显示不同的汉字(如“钟”、“音”、“传”),直观展示了当前的工作模式,增强了用户体验。同时,按键和串口控制相结合的方式,使得用户可以通过多种途径对系统进行操作,如调节音乐播放速度、音量、切换歌曲,调整闹钟时间、设置多个闹钟等,极大地丰富了系统的交互方式。
-
温湿度监测与调节:系统集成了温湿度传感器,能够实时监测环境温湿度,并通过串口调节温湿度上下限,当温湿度超出设定范围时,通过LED灯进行边界提示,实现了对环境的智能监测与调节。
-
高效的开发平台:采用STM32CUBEIDE作为开发平台,利用其强大的代码编辑、编译、调试功能,以及丰富的库函数和示例项目,极大地提高了开发效率,降低了开发难度。
-
综合应用能力的展现:本设计不仅展示了STM32MP157A单片机在嵌入式系统设计中的强大功能,还体现了设计者在硬件选型、电路设计、软件编程、系统调试等方面的综合应用能力。
综上所述,本设计是一个集多功能性、灵活性、用户友好性于一体的嵌入式系统,充分展示了STM32MP157A单片机在复杂系统设计中的广泛应用前景和潜力。通过本设计的实施,不仅加深了对嵌入式系统设计的理解,还提升了解决实际问题的能力。
参考资料:
1. STM32简易音乐播放器(HAL库)
相关文章:

STM32杂交版(HAL库、音乐盒、闹钟、点阵屏、温湿度)
一、设计描述 本设计精心构建了一个以STM32MP157A高性能单片机为核心控制单元的综合性嵌入式系统。该系统巧妙融合了蜂鸣器、数码管显示器、点阵屏、温湿度传感器、LED指示灯以及按键等多种外设模块,形成了一个功能丰富、操作便捷的杂交版智能设备。通过串口…...

多输入多输出 | Matlab实现Transformer多输入多输出预测
多输入多输出 | Matlab实现Transformer多输入多输出预测 目录 多输入多输出 | Matlab实现Transformer多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现Transformer多输入多输出预测(完整源码和数据) 1.da…...

Linux文件编程(标准C库)
目录 一、标准C库打开/创建文件,读写文件,光标移动 二、标准C库写入结构体到文件 三、其他函数补充 1.fputc函数 2.feof函数和fgetc函数 前面讲到的open函数都是基于linux内核的,也就是说在Windows系统上无法运行,移植性比较…...

生产英特尔CPU处理器繁忙的一天
早晨:准备与检查 7:00 AM - 起床与准备 工厂员工们早早起床,快速洗漱并享用早餐。为了在一天的工作中保持高效,他们会进行一些晨间锻炼,保持头脑清醒和身体活力。 8:00 AM - 到达工厂 员工们到达英特尔的半导体制造工厂&#…...
MVC拦截器、ThreadLocal来进行登录拦截
MVC拦截器、ThreadLocal来进行登录拦截 1. 对登录进行拦截1.1 什么是ThreadLocal1.2 定义UserHolder 类,来封装ThreadLocal方法1.3 拦截器WebMvcConfigurer 的配置1.4 登录的配置,当碰到拦截的方法的时候调用1.5 UserServiceImpl1.6 controllerÿ…...

小程序问题
1.获取节点 wx.createSelectorQuery() wx.createSelectorQuery().in(this) //组件中加in(this),不然获取不到 2.使用实例 wx.createSelectorQuery().in(this).select(#share).fields({node: true,size: true}).exec(async (res) > {const canvas res[0].node;…...
arm 版的 deb、rpm、AppImage 都有什么区别
qq arm 版的 deb、rpm 和 AppImage 格式之间存在几个关键区别。以下是对这些区别的详细解释: 包管理系统与兼容性: deb:是Debian及其衍生发行版(如Ubuntu)中使用的软件包格式。这些系统使用dpkg命令来管理deb包&#…...

docker中mysql设置lower_case_table_names配置的坑
前沿 今天在使用flowable流程框架的时候,遇到一个问题。需要配置MySQL数据库以实现表名大小写不敏感。本以为这是一个简单的任务,却耗费了我两个多小时的时间。 docker容器中修改配置,重启不成功 我们前提是容器中的mysql中已经有很多数据…...

python日志记录工具:loguru日志库使用
文章目录 一、使用loguru1、安装2、简单使用3、详细使用4、工具类(1)logUtil.py(2)测试类(3)效果 参考资料 一、使用loguru 1、安装 pip install loguru2、简单使用 from loguru import logger# 打印到文…...
python入门基础知识·二
""" # Python介绍 # Python注释 # 单行注释: # # 多行注释: r """""" # Python输出和输入 # print: 输出 # input: 输入 ①会让程序暂停,②得到的是字符串内容 int(&…...
深度学习中的正则化技术 - 噪声鲁棒性篇
序言 在深度学习的蓬勃发展中,模型的性能与泛化能力成为了研究者们关注的焦点。然而,实际应用中的数据往往伴随着各种噪声,这些噪声不仅来源于数据采集过程中的硬件限制,还可能由环境干扰、传输错误等因素引入。噪声的存在严重影…...
如何通过 Java 来完成 zip 文件与 rar 文件的解压缩?
目录 一、用到的知识点 二、代码展示(分解版) 三、代码展示(整体版) 一、用到的知识点 1.IO流: Input:输入,通过“输入流”进行文件的读取操作 Output:输出,通过“输出流”进行文件的写入操作 2.文件操作相关: File类ÿ…...

C 语言中的联合(Union)的用途是什么?
🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会! 📙C 语言百万年薪修炼课程 通俗易懂,深入浅出,匠心打磨,死磕细节,6年迭代,看过的人都说好。 文章目…...
汽车电子助力转向系统研究
汽车电子助力转向系统研究 摘要 电子助力转向系统(Electric Power Steering,EPS)是一种利用电动机辅助驾驶员进行车辆转向的系统。相比于传统的液压助力转向系统,EPS具有更高的效率、精确性和可控性。本文将详细探讨EPS的工作原理…...
大数据学习之 scala基础(补充)
scala基础: hello world: 写scala可运行文件的注意事项1、如果一个scala文件要运行,class要改成object2、如果是class,就仅单纯代表一个类,如果是object代表的是单例对象3、scala语法中,一句话结束不需要加分号4、sca…...
正向传播和反向传播
正向传播(Forward Propagation) 正向传播是指将输入数据通过神经网络,计算出预测值的过程。具体步骤如下: 输入层:接受输入数据。隐藏层:每个隐藏层中的神经元接收上一层的输出,进行加权求和&…...
前端文件下载的方式
方式一:a标签直接下载 <a href"链接" >下载</a>一个文件链接(一般是服务器上的某个文件),这个链接一般地址栏输入是预览,不是附件下载 如果想改成附件下载,以下两种方式任选一个均…...

视图库对接系列(GA-T 1400)十六、视图库对接系列(本级)通知(订阅回调)
说明 之前我们实现了订阅接口,其中有一个receiveAddr参数, 这个就是对应的回调的地址。一般情况下对应的是同一个服务。 我们推荐使用http://xxx:xxx/VIID/SubscribeNotifications接口文档 SubscribeNotificationList对象对象如下: 文档中是xml,但实际上目前使用的都是jso…...

Python | Leetcode Python题解之第230题二叉搜索树中第K小的元素
题目: 题解: class AVL:"""平衡二叉搜索树(AVL树):允许重复值"""class Node:"""平衡二叉搜索树结点"""__slots__ ("val", "parent&quo…...

Python酷库之旅-第三方库Pandas(018)
目录 一、用法精讲 44、pandas.crosstab函数 44-1、语法 44-2、参数 44-3、功能 44-4、返回值 44-5、说明 44-6、用法 44-6-1、数据准备 44-6-2、代码示例 44-6-3、结果输出 45、pandas.cut函数 45-1、语法 45-2、参数 45-3、功能 45-4、返回值 45-5、说明 4…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)
小伙伴们,有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL, 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始,OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...
MySQL基本操作(续)
第3章:MySQL基本操作(续) 3.3 表操作 表是关系型数据库中存储数据的基本结构,由行和列组成。在MySQL中,表操作包括创建表、查看表结构、修改表和删除表等。本节将详细介绍这些操作。 3.3.1 创建表 在MySQL中&#…...
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
Nginx 是什么:高性能的HTTP和反向代理Web服务器。怎么用:通过配置文件定义代理规则、负载均衡、静态资源服务等。为什么用:提升Web服务性能、高并发处理、负载均衡和反向代理。优缺点:轻量高效,但动态处理能力较弱&am…...