内部资源的处理
GPIO的处理
//输出
#define LED(a) (a?HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET):HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET))
#define BEEP(a) (a?HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET):HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET))
#define RELAY(a) (a?HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_SET):HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_RESET))
//输入
#define IR_IN HAL_GPIO_ReadPin(IR_IN_GPIO_Port,IR_IN_Pin)
#define FRI HAL_GPIO_ReadPin(FRI_GPIO_Port,FRI_Pin)
定时器的使用
uint16_t time_1ms,time_500ms; //计时变量1ms,500ms
HAL_TIM_Base_Start_IT(&htim1); //定时器中断开始初始化
//定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim1.Instance) //定时器1触发中断
{
time_1ms++;
if(time_1ms>= 500)
{
time_1ms= 0;
time_500ms = 1;
}
}
}
串口的数据获取与发送
//串口的数据获取
uint8_t USART1_TX_BUF[200];
#define u1_printf(...) HAL_UART_Transmit(&huart1,USART1_TX_BUF,sprintf((char *)USART1_TX_BUF,__VA_ARGS__),0xffff)
uint8_t USART2_TX_BUF[200];
#define u2_printf(...) HAL_UART_Transmit(&huart2,USART2_TX_BUF,sprintf((char *)USART2_TX_BUF,__VA_ARGS__),0xffff)
uint8_t USART3_TX_BUF[200];
#define u3_printf(...) HAL_UART_Transmit(&huart3,USART3_TX_BUF,sprintf((char *)USART3_TX_BUF,__VA_ARGS__),0xffff)
//串口2的数据获取
uint8_t uart2_value; //串口传的单个数据
//串口的储存数组,串口的接收时间,串口存值的数量
uint8_t uart2_buf[36],uart2_time,uart2_num;
uint8_t uart2_rx_flag;//串口的获取值的标志位
//定时器中串口处理过程
if(uart2_num != 0) //串口接收到数据传来
{
uart2_time++; //计时开始
if(uart2_time >= 10)//一帧数据接受完成
{
//将标志位清零
uart2_time = 0;
uart2_num = 0;
//接收标志位置1
uart2_rx_flag = 1;
}
}
//串口回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == huart2.Instance)//串口2触发中断
{
//获取串口2的数据,uart2_value
HAL_UART_Receive_IT(&huart2, &uart2_value, 1);
//将数据存储到uart2_buf中
uart2_buf[uart2_num++] = uart2_value;
uart2_time = 0;
}
}
adc的数据获取
uint16_t adc_value,light_value;
//单通道数据获取
HAL_ADC_Start(&hadc1);
if(HAL_ADC_PollForConversion(&hadc1, 999) == HAL_OK)
adc_value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
light_value = (adc_value/4096.0)*100; //获取值
//多通道数据获取
uint8_t adc_ch; //adc的个数
uint32_t adc_buf[3];//adc数值的存储数组
/*******************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
* 函数功能: 一次完整的ADC数据传输
* 输入参数: 无
* 返 回 值: adc的数值存储区域adc_buf[]
* 说 明:adc_buf uint32_t;
*****************************/
uint16_t dong_get_adc(){
//开启ADC1
HAL_ADC_Start(&hadc1);
//等待ADC转换完成,超时为100ms
HAL_ADC_PollForConversion(&hadc1,100);
//判断ADC是否转换成功
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){
//读取值
return HAL_ADC_GetValue(&hadc1);
}
return 0;
}
//将获取的值存储到adc_buf中
for(adc_ch=0;adc_ch<3;adc_ch++){
//分别存放通道1、2、3的ADC值
adc_buf[adc_ch]=dong_get_adc();
}
//浊度传感器
deep=adc_buf[1]/4095.00*5; //获取电压值
deep = deep-0.0192*(temp/10.0 - 25.0); //进行温度补偿
deep = -865.68*deep+3680; //计算浊度值
//PM2.5传感器
#define P_LED(a) (a?HAL_GPIO_WritePin(P_LED_GPIO_Port, P_LED_Pin, GPIO_PIN_SET):HAL_GPIO_WritePin(P_LED_GPIO_Port, P_LED_Pin, GPIO_PIN_RESET))
P_LED(0); //打开灯光
delay_us(280); //延时280us
//ADC检测
delay_us(40); //延时40us
P_LED(1); //关灯
PM2_5 = ((adc_buf[0]*3.3/4096.0)*1000)/12;
外部中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == PUSH_Pin)
{
push_value++;
}
}
外设驱动
氧气检测
uint16_t O2_value; //氧气变量
if(uart1_rx_flag == 1)
{
uart1_rx_flag = 0;
O2_value = uart1_buf[4]*256 + uart1_buf[5]; //读取氧气值
}
//氧气初始化配置
u1_printf("%c%c%c%c%c%c%c%c%c",0xFF,0x01,0x03,0x01,0x00,0x00,0x00,0x00,0x04);
舵机控制
//pwm控制
uint16_t SG90_angle=500; //舵机角度控制变量(500-2500 0-180°)
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3); //定时器3pwm初始化
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_3,SG90_angle); //舵机的角度控制
Zigbee 的配置与数据收发(亿百特)
//主机
//配置zigbee
ev_type:
00 协调器
01 路由器
02 终端(默认)
u2_printf("%c%c%c%c%c", 0xFD, 0x02, 0x01, 0x00, 0xFF); //设置zigbee为协调器
/*******从机*****/
//ZIGBEE的发送包头,以广播形式发送
uint8_t Zigbee_Head[4] = {0xFC,0X00,0X01,0X02};
//Zigbee的发送数据
uint8_t Zigbee_Data[20];
//发送的位数
uint8_t Zigbee_num;
//Zigbee发送的数据长度
uint8_t Data_Leng = 6;
/*******************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
* 函数功能: Zigbee发送包头,广播形式发送
* 输入参数: 发送数据的长度
* 返 回 值: 无
* 说 明:无
**************/
void Zigbee_Send_Head(uint8_t Data_Len)
{
uint8_t i;
//改变Zigbee_Head数组中[1]的数,确认发送长度
Zigbee_Head[1] = Data_Len += 2;
//for循环依次发出
for(i=0;i<4;i++)
u2_printf("%c", Zigbee_Head[i]); //串口2发送字符
}
//发送字符放入待发送数组中
Zigbee_Data[0]=0xA1;
Zigbee_Data[1]=NUM/100%10;
Zigbee_Data[2]=NUM/10%10;
Zigbee_Data[3]=NUM/1%10;
Zigbee_Data[4]=NUM/10%10;
Zigbee_Data[5]=NUM/1%10;
//发送报头数据
Zigbee_Send_Head(Data_Leng);
//循环发送数组的数据
for(Zigbee_num=0; Zigbee_num<Data_Leng; Zigbee_num++)
u2_printf("%c", Zigbee_Data[Zigbee_num]);//以字符发送
ADX345-角度传感器
Init_ADXL345(); //ADXL345初始化
uint16_t BuShu; //步数变量
uint8_t BuShu_flag; //步数标志位
ReadData_XYZ(); //读取角度值
/* 步数计算 一般500ms检测一次*/
if(temp_Y>300 && BuShu_flag==0)
BuShu_flag = 1;
if(temp_Y<-300 && BuShu_flag==1)
{
BuShu_flag = 0;
BuShu++;
}
28BYJ-48-步进电机
uint8_t Motor_Status; //步进电机状态变量
uint16_t Motor_Num; //步进电机计数变量
uint16_t Motor_Time; //步进电机计时变量
uint8_t const Motor_Buf[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09};//步进电机步数数组
//1ms定时器中
if(Motor_Status & 0x80) //步进电机转动
{
if(Motor_Status & 0x01)
Motor_Num++;
else
Motor_Num--;
if(Motor_Num >= 256*8)
{
Motor_Status &= ~0x80;
Motor_Time = 0;
if(Motor_Status&0x01) //开门后,延时关门
Motor_Status |= 0x40;
}
//第一种写法
GPIOB->ODR &= 0xff0f; //引脚状态
GPIOB->ODR |= Motor_Buf[Motor_Num%8] << 4;
//第二种写法
GPIOB->ODR &= 0xffc7;
GPIOA->ODR &= 0x7fff;
if(Motor_Buf[Motor_Num%8] & 0x01)
GPIOB->ODR |= 1<<5;
if(Motor_Buf[Motor_Num%8] & 0x02)
GPIOB->ODR |= 1<<4;
if(Motor_Buf[Motor_Num%8] & 0x04)
GPIOB->ODR |= 1<<3;
if(Motor_Buf[Motor_Num%8] & 0x08)
GPIOA->ODR |= 1<<15;
}
if((Motor_Status & 0x01) == 0x00 ) //若门为关闭状态,步进电机开门
{
Motor_Status |= 0x81;
}
if(Motor_Status & 0x40 )
{
Motor_Status &= ~0x41;
Motor_Status |= 0x80;
}
if(Motor_Status & 0x80) //步进电机转动
{
if(Motor_Status & 0x01)
Motor_Num++;
else
{
if(IR)
{
Motor_Status |= 0x01;
Motor_Status |= 0x40;
}
Motor_Num--;
}
if(Motor_Num >= 256*8)
{
Motor_Status &= ~0x80;
Motor_Time = 0;
if(Motor_Status&0x01) //开门后,延时关门
Motor_Status |= 0x40;
}
GPIOB->ODR &= 0xff0f;
GPIOB->ODR |= Motor_Buf[Motor_Num%8] << 4;
}
if((Motor_Status & 0x40))//延时关门(红外触发后通过该程序延时关门)
{
Motor_Time++;
if(Motor_Time >= 3000)
{
Motor_Time = 0;
Motor_Status |= 0x80;
Motor_Status &= ~0x41;
}
}
GSM-SIM900A(SIM800C)
uint8_t GSM_Send_bz; //发送标志位
uint16_t GSM_time; //每隔500ms发送一条
uint8_t Phone_Number[11]="18016242114";//接收手机号
uint8_t Message[50]; //发送数据存储
uint8_t GSM_flag; //发送标志
void GSM_Send(uint8_t *Message)
{
if(GSM_Send_bz==1)
{
if(GSM_flag==0)
{
GSM_flag=1;
u3_printf("AT+CMGF=1\r\n"); //设置短息格式为文本模式
}
}
else if(GSM_Send_bz==2)
{
if(GSM_flag==0)
{
GSM_flag=1;
u3_printf("AT+CSMP=17,167,2,25\r\n"); //设置短消息文本模式
}
}
else if(GSM_Send_bz == 3)
{
if(GSM_flag==0)
{
GSM_flag=1;
u3_printf("AT+CSCS=\"UCS2\"\r\n"); //选择TE字符集
}
}
else if(GSM_Send_bz == 4)
{
if(GSM_flag==0)
{
GSM_flag=1;
u3_printf("AT+CMGS=\"003%c003%c003%c003%c003%c003%c003%c003%c003%c003%c003%c\"\r\n", \
Phone_Number[0],Phone_Number[1],Phone_Number[2],\
Phone_Number[3],Phone_Number[4],Phone_Number[5],\
Phone_Number[6],Phone_Number[7],Phone_Number[8],\
Phone_Number[9],Phone_Number[10]);//此处修改为对方的电话号
}
}
else if(GSM_Send_bz == 5)
{
if(GSM_flag==0)
{
GSM_flag=1;
u3_printf("%s",Message); //发送文本
u3_printf("%c",0x1A); //结束符
}
}
}
GSM_Send(Message);
//1ms定时器中
if(GSM_Send_bz > 0) {GSM_time++;}
if(GSM_time >= 500)
{
/* GSM向手机发送报警 */
GSM_flag=0;
GSM_time=0;
GSM_Send_bz++;
if(GSM_Send_bz >= 6) //中文
GSM_Send_bz = 0;
}
sprintf((char *)Message,"%s","4E2D56FD60A8597D");
GSM_Send_bz=1;
GPS
char *Start,*End;
char latitude_buf[20];
char longitude_buf[20];
/****
*******GPS
*****/
void GPS_function(void)
{
char i;
memset(latitude_buf,'-',7);
memset(longitude_buf,'-',7);
Start = strstr((char *)uart2_buf, "GLL");
if(Start != NULL)
{
Start = strstr(Start, ",") + 1; //获取纬度数据首地址
if(*(Start) != ',') //判断是否获取到经纬度数据
{
Start++; //纬度数据首地址
End = strstr(Start, ","); //获取纬度数据尾地址
for(i=0; i<End - Start; i++)
{
latitude_buf[i+1] = *(Start + i-1); //将纬度数据存放在数组中
if(*(Start + i-1) == '.')
{
latitude_buf[i+1] = latitude_buf[i];
latitude_buf[i] = latitude_buf[i-1];
latitude_buf[i-1] = '.';
}
}
Start = strstr(Start, ",") + 1; //获取南纬或北纬数据
if(*Start=='N' || *Start=='S')
latitude_buf[0] = *Start; //将数据存放在纬度数组
Start = strstr(Start, ",") + 1; //获取经度数据首地址
End = strstr(Start, ","); //获取经度数据尾地址
for(i=0; i<End - Start; i++)
{
longitude_buf[i+1] = *(Start + i); //将经度数据存放在数组中
if(*(Start + i) == '.')
{
longitude_buf[i+1] = longitude_buf[i];
longitude_buf[i] = longitude_buf[i-1];
longitude_buf[i-1] = '.';
}
}
Start = strstr(Start, ",") + 1; //获取东经或西经数据
if(*Start=='E' || *Start=='W')
longitude_buf[0] = *Start; //将数据存放在经度数组中
latitude_buf[7] = '\0'; //只让经度和纬度显示十个字符
longitude_buf[7] = '\0';
// lat = atof((char *)latitude_buf+1); //字符串转换为浮点型变量
// lon = atof((char *)longitude_buf+1); //字符串转换为浮点型变量
}
}
}
心率
uint16_t timeCount; //发送间隔变量
uint8_t sec_5; //5S标志位
uint32_t ADC_ConvertedValue,xinlv;
uint16_t BPM_BUF[100]; //心率特征点缓存数组
uint16_t IBI, BPM; //两次脉搏间隔时间以及心率
uint16_t BPM_New, BPM_Old, BPM_Cha;
uint16_t IBI_Time; //两次脉搏间隔时间计时
uint8_t IBI_Flag;
uint16_t BPM_Max, BPM_Min, BPM_Mid; //最大最小值以及中间值
uint16_t filter; //有效阈值
uint8_t flag_50ms,IBI_Finish,BPM_Num,BPM_Err;
int FindArrayMax( uint16_t *a, int n ) //求最大值
{
int i, max;
max = a[0];
for(i=0; i<n; i++ )
{
if(a[i]>max)
max = a[i];
}
return max;
}
int FindArrayMin( uint16_t *a, int n ) //求最小值
{
int i, min;
min = a[0];
for(i=0; i<n; i++ )
{
if(a[i]<min)
min = a[i];
}
return min;
}
void Get_BPM_function()
{
if(flag_50ms)
{
HAL_ADC_Start(&hadc1);
if(HAL_ADC_PollForConversion(&hadc1, 999) == HAL_OK)
ADC_ConvertedValue = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
flag_50ms =0;
BPM_Max = FindArrayMax(BPM_BUF, 100);
BPM_Min = FindArrayMin(BPM_BUF, 100);
BPM_Mid = (BPM_Max + BPM_Min)/2;
filter = (BPM_Max + BPM_Mid)/2;
if(IBI_Finish == 1)
{
IBI_Finish = 0;
BPM_Old = BPM_New;
BPM_New = 60000 / IBI;
if(BPM_New < 200) //心率大于200算错误信号
{
if(BPM_New >= BPM_Old)
BPM_Cha = BPM_New - BPM_Old;
else
BPM_Cha = BPM_Old - BPM_New;
if(BPM_Cha < 5) //连续3次误差在5之内才进行输出
{
BPM_Err = 0;
BPM_Num++;
if(BPM_Num >= 2)
{
BPM_Num = 0;
BPM = BPM_New;
}
}
else{ //中途错误一次,重新计算
BPM_Num = 0;
BPM_Err++;
if(BPM_Err >= 5)
BPM = 0;
}
}
else{
BPM_Num = 0;
BPM_Err++;
if(BPM_Err >= 5)
BPM = 0;
}
}
}
}
//1ms定时器中
if(timeCount%30==0)
{
flag_50ms=1;
BPM_BUF[i++] = ADC_ConvertedValue; //以15ms的周期将350个特征点存入心率数组,用于心率计算
if(i >= 100)
i = 0;
}
if((BPM_Max-BPM_Min) > 100) //提高误差
{
if(IBI_Flag==1 && ADC_ConvertedValue>=filter) //大于有效阈值的时间记录一次时间
{
IBI_Flag = 0;
IBI = IBI_Time;
IBI_Time = 0;
IBI_Finish = 1;
}
else if(IBI_Flag==0 && ADC_ConvertedValue<filter)
IBI_Flag = 1;
IBI_Time++;
}
else{
IBI = 0;
IBI_Time = 0;
BPM = 0;
}
timeCount++;
if(timeCount >= 5000) //产生5S周期信号
{
timeCount = 0;
sec_5 = 1;
}
WIFI -腾讯云
//1、放在main函数while(1);
ESP8266_App();
//2、放在1ms定时器中
time_flag_1ms++;
if(time_flag_1ms>3000) //定时三秒,每三秒上传一次数据
{
time_flag_1ms=0;
sec_3 = 1;
}
//3、串口中断回调函数
if(huart->Instance == huart2.Instance)//串口2触发
{
HAL_UART_Receive_IT(&huart2, &uart2_value, 1);
if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //防止串口被刷爆
esp8266_buf[esp8266_cnt++] = uart2_value;
}
//4、配网标志位等于1
SmartConfig=1;
WIFI-ONENET
//网络设备驱动
#include "esp8266.h"
//网络设备
#include "onenet.h"
uint8_t time_1ms,time_500ms;
uint8_t uart1_value; //串口1数据接收变量
uint8_t uart2_value; //串口2数据接收变量
uint16_t timeCount; //发送间隔变量
uint8_t sec_5; //5S标志位
uint8_t flag_wifi; //WIFI状态变量
unsigned char *dataPtr = NULL;//接收指针
HAL_TIM_Base_Start_IT(&htim1);
HAL_UART_Receive_IT(&huart1, &uart1_value, 1);
HAL_UART_Receive_IT(&huart2, &uart2_value, 1);
if(sec_5 == 1)
{
sec_5 = 0;
if(ESP8266_Status()==0)
{
if(flag_wifi == 0)
{
flag_wifi = 1;
ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT");
OneNet_DevLink();
}
UsartPrintf("OneNet_SendData\r\n");
OneNet_SendData(); //发送数据
ESP8266_Clear();
}
else{
if(flag_wifi == 1)
flag_wifi = 0;
}
}
dataPtr = ESP8266_GetIPD(0);
if(dataPtr != NULL)
OneNet_RevPro(dataPtr);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim1.Instance) //定时器1触发中断
{
time_1ms++;
if(time_1ms>= 500)
{
time_1ms= 0;
time_500ms = 1;
}
timeCount++;
if(timeCount >= 5000) //产生5S周期信号
{
timeCount = 0;
sec_5 = 1;
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == huart1.Instance)//串口1触发
{
HAL_UART_Receive_IT(&huart1, &uart1_value, 1);
}
else if(huart->Instance == huart2.Instance)//串口2触发
{
HAL_UART_Receive_IT(&huart2, &uart2_value, 1);
if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //防止串口被刷爆
esp8266_buf[esp8266_cnt++] = uart2_value;
}
}
DS1302-时钟模块
/****
*******按键设置函数
*****/
void Key_function(void)
{
key_num = Chiclet_Keyboard_Scan(); //按键扫描
if(key_num != 0) //有按键按下
{
switch(key_num)
{
case 1: //按键1
flag_display == 7 ? flag_display = 0 : flag_display++; //一共7个模式
OLED_Clear2(); //清屏
break;
case 2: //按键2
switch(flag_display)
{
case 0: //模式0
break;
case 1: //设置界面为1时,修改年 +1
TIME[6]++;
if(TIME[6]%0x10 > 9)
{
TIME[6] = TIME[6] + 0x06;
}
Ds1302Init();
break;
case 2: //设置界面为2时,修改月 +1
TIME[4]++;
if(TIME[4]%0x10 > 9)
{
TIME[4] = TIME[4] + 0x06;
}
if(TIME[4] > 0x12)
{
TIME[4] = 0x01;
}
Ds1302Init();
break;
case 3: //设置界面为3时,修改日 +1
TIME[3]++;
if(TIME[3]%0x10 > 9)
{
TIME[3] = TIME[3] + 0x06;
}
if(TIME[3] > 0x31)
{
TIME[3] = 0x01;
}
Ds1302Init();
break;
case 4: //设置界面为4时,修改时 +1
TIME[2]++;
if(TIME[2]%0x10 > 9)
{
TIME[2] = TIME[2] + 0x06;
}
if(TIME[2] > 0x23)
{
TIME[2] = 0x00;
}
Ds1302Init();
break;
case 5: //设置界面为5时,修改分 +1
TIME[1]++;
if(TIME[1]%0x10 > 9)
{
TIME[1] = TIME[1] + 0x06;
}
if(TIME[1] > 0x59)
{
TIME[1] = 0x00;
}
Ds1302Init();
break;
case 6: //设置界面为6时,修改秒 +1
TIME[0]++;
if(TIME[0]%0x10 > 9)
{
TIME[0] = TIME[0] + 0x06;
}
if(TIME[0] > 0x59)
{
TIME[0] = 0x00;
}
Ds1302Init();
break;
case 7: //设置界面为7时,修改星期 +1
TIME[5]++;
if(TIME[5] > 0x07)
{
TIME[5] = 0x01;
}
Ds1302Init();
break;
default:;break;
}
break;
case 3: //按键3
switch(flag_display)
{
case 0: //模式0关闭窗帘
break;
case 1: //设置界面为1时,修改年 -1
TIME[6]--;
if(TIME[6]%0x10 == 0x0f)
{
TIME[6] = TIME[6] - 0x06;
}
Ds1302Init();
break;
case 2: //设置界面为2时,修改月 -1
TIME[4]--;
if(TIME[4]%0x10 == 0x0f)
{
TIME[4] = TIME[4] - 0x06;
}
if(TIME[4] < 0x01)
{
TIME[4] = 0x12;
}
Ds1302Init();
break;
case 3: //设置界面为3时,修改日 -1
TIME[3]--;
if(TIME[3]%0x10 == 0x0f)
{
TIME[3] = TIME[3] - 0x06;
}
if(TIME[3] < 0x01)
{
TIME[3] = 0x31;
}
Ds1302Init();
break;
case 4: //设置界面为4时,修改时 -1
TIME[2]--;
if(TIME[2]%0x10 == 0x0f)
{
TIME[2] = TIME[2] - 0x06;
}
if(TIME[2] > 0x23)
{
TIME[2] = 0x23;
}
Ds1302Init();
break;
case 5: //设置界面为5时,修改分 -1
TIME[1]--;
if(TIME[1]%0x10 == 0x0f)
{
TIME[1] = TIME[1] - 0x06;
}
if(TIME[1] > 0x59)
{
TIME[1] = 0x59;
}
Ds1302Init();
break;
case 6: //设置界面为6时,修改秒 -1
TIME[0]--;
if(TIME[0]%0x10 == 0x0f)
{
TIME[0] = TIME[0] - 0x06;
}
if(TIME[0] > 0x59)
{
TIME[0] = 0x59;
}
Ds1302Init();
break;
case 7: //设置界面为7时,修改星期 -1
TIME[5]--;
if(TIME[5] < 0x01)
{
TIME[5] = 0x07;
}
Ds1302Init();
break;
default:;break;
}
break;
default:;break;
}
}
}
/****
*******显示函数
*****/
void Display_function(void)
{
OLED_Show_Time((uint8_t *)TIME);
switch(flag_display) //根据不同的显示标志位,显示不同的界面
{
case 0: //界面0
Oled_ShowCHinese(1,4,(uint8_t *)"温度");
Oled_ShowString(32,4,(uint8_t *)":");
OLED_Show_Temp(40,4,temp);
Oled_ShowCHinese(1,6,(uint8_t *)"湿度");
Oled_ShowString(32,6,(uint8_t *)":");
OLED_Show_Humi(40,6,humi);
break;
case 1: //界面1
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" nian");
break;
case 2: //界面2
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" yue ");
break;
case 3: //界面3
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" ri ");
break;
case 4: //界面4
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" shi ");
break;
case 5: //界面5
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" fen ");
break;
case 6: //界面6
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" miao");
break;
case 7: //界面7
Oled_ShowString(32,4,(uint8_t *)"Set Time");
Oled_ShowString(96,4,(uint8_t *)"...");
Oled_ShowCHinese(1,6,(uint8_t *)"设置");
Oled_ShowString(32,6,(uint8_t *)":");
Oled_ShowString(40,6,(uint8_t *)" zhou");
break;
default:;break;
}
}
RC522-RFID
/* RFID相关变量 */
uint8_t Temp[4],UID[4];
uint8_t const DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //校验密码
uint8_t RC522_Buf[16]; //RC522接收数据存储数组
uint8_t User_Name[6]; //用户数组
uint8_t User_Num;
uint8_t Card_flag; //卡标志位
uint16_t RC522_time;
uint8_t flag_err_card;
uint8_t cnt=1;
uint16_t flag_card;
if(PcdRequest(0x52,Temp)==MI_OK) //寻卡,成功后Temp数组为卡类型
{
if(PcdAnticoll(UID)==MI_OK) //防冲突,UID数组数据为卡序列号
{
if(PcdSelect(UID) == MI_OK)//选择该序列号卡
{
if(PcdAuthState(0x60, 2, (unsigned char *)DefaultKey,UID) == MI_OK)//校验卡密码
{
if(PcdRead(2, RC522_Buf) == MI_OK) //读取块2中当前数据
{
if(flag_card==1)
{
if(RC522_Buf[8] == 1)
{
if(flag_led==0)
{
flag_led=2;
BEEP(1);
HAL_Delay(150);
BEEP(0);
flag_display=0;
flag_card=0;
}
}
else
{
//未授权卡
if(flag_err_card==0)
{
if(flag_led==0)
{
flag_led=1;
BEEP(1);
HAL_Delay(1000);
BEEP(0);
}
}
}
}
//添加或者注销卡
else
{
if(flag_card == 3) //添加卡
{
RC522_Buf[8] = 1;
memcpy(RC522_Buf + 9, &cnt, 6);
User_Num = 0;
PcdWrite(2, RC522_Buf);
OLED_Clear();
Oled_ShowCHinese(32,3,"已增加");
BEEP(1);
HAL_Delay(1000);
BEEP(0);
flag_card=0;
flag_display=0;
OLED_Clear();
}
else if(flag_card == 4) //注销卡
{
memset(RC522_Buf + 8, 0, 7);
PcdWrite(2, RC522_Buf);
OLED_Clear();
Oled_ShowCHinese(32,3,"已删除");
BEEP(1);
HAL_Delay(1000);
BEEP(0);
flag_card=0;
flag_display=0;
OLED_Clear();
}
}
}
}
}
}
}
/* RFID相关初始化 */
RC522_GPIO_Init();
PcdReset();
PcdAntennaOff();
HAL_Delay(5);
PcdAntennaOn();
M500PcdConfigISOType('A');
红外遥控
uint8_t IR_Buf[4]; //红外信号存储数组
/*
45 46 47
44 40 43
07 15 09
16 19 0D
0C 18 5E
08 1C 5A
42 52 4A
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//外部中断回调函数
{
uint8_t j,k;
if(GPIO_Pin == IR_IN_Pin)//判断是否是红外引脚触发中断
{
if(IR_IN == 0) //确认是否真的接收到正确的信号
{
while(IR_IN == 0); //等待9ms低电平
if(IR_IN == 1) //如果正确等到9ms低电平
{
TIM2->CNT=0;
HAL_TIM_Base_Start(&htim2);
while(IR_IN == 1) //等待4.5ms的起始高电平过去
{
if(TIM2->CNT >= 5000) return ;
}
HAL_TIM_Base_Stop(&htim2);
for(j=0;j<4;j++) //共有4组数据
{
for(k=0;k<8;k++) //接收一组数据
{
while(IR_IN == 0); //等待信号前面的560us低电平过去
TIM2->CNT=0;
HAL_TIM_Base_Start(&htim2);
while(IR_IN == 1) //计算高电平的时间长度
{
if(TIM2->CNT >= 2000) return ;
}
HAL_TIM_Base_Stop(&htim2);
IR_Buf[j] >>= 1;
if(TIM2->CNT >= 800) IR_Buf[j] |= 0x80; //如果高电平出现大于800us,那么是1
}
}
}
if(IR_Buf[2] == 0x0C)
{
}
else if(IR_Buf[2] == 0x18)
{
}
}
}
}
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。