使用stm8L051F3芯片,RF433頻率的無線遙控器代碼,支持3種按鍵模式
51hei.png (13.46 KB, 下載次數: 48)
下載附件
2019-12-30 15:54 上傳
單片機源程序如下:
- #include "All_Includes.h"
- #define ACCEL_OPEN 180
- #define ACCEL_SHAKE 60
- #define ANGLE_OPEN 900 //55°* 16.4 = 900
- #define OPEN_TEST_TIME_GATE 25 //3s
- #define SHAKE_TEST_TIME_GATE (4*60) //4min
- #define SHAKE_TIME_GATE 60 //60s
- #define ID_ADDR 0x4926
- #define CODE_MATCH 0X79
- #define CODE_DOWN 0X33
- #define CODE_UP 0X11
- #define CODE_STOP 0X55
- #define CODE_DRY 0X75
- #define CODE_LED 0X0F
- #define CODE_XD 0X73
- #define CODE_HEAT 0X76
- #define CODE_FLZ 0X44
- uint8_t ShakeFlag = 0;
- uint8_t ShakeFirstFlag = 0;
- uint8_t DryFlag = 0;//0--未檢測到任何信號 1--檢測到連續震動 2--檢測到加速度 3--檢測到開門信號
- uint8_t ShakeTime_1S = 0;
- uint16_t TimeCount = 0;
- uint16_t TestCount = 0;
- uint16_t TestFlag = 76;
- uint8_t TestHALF = 0;
- uint8_t HALF_H_FLAG = 1;
- uint8_t GO_FLAG = 0;
- uint8_t TestGo = 0;
- uint8_t ShakeTime = 0;
- uint16_t ShakeTestTime = 0;
- uint8_t OpenTestTime = 0;
- uint8_t Uid[4] = {0};
- uint8_t KeyFlag = 0;
- uint8_t UpFlag = 1;
- uint8_t DnFlag = 1;
- uint8_t TimeFlag = 0;
- void Lsi_Clk_Init(void)
- {
- CLK_SYSCLKSourceSwitchCmd(ENABLE); //使能時鐘切換
- CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_LSI); //選擇內部低速時鐘作為時鐘源
- CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1); //設置系統時鐘分頻32K
- while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_LSI);//等待時鐘穩定
- CLK_HSICmd(DISABLE);
- }
- void Hsi_Clk_Init(void)
- {
- CLK_SYSCLKSourceSwitchCmd(ENABLE); //使能時鐘切換
- CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI); //選擇內部高速時鐘作為時鐘源
- CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_16); //設置系統時鐘分頻1M
- while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSI);//等待時鐘穩定
- }
- void Rtc_Init(void)
- {
- CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);//RTC時鐘門控使能
- CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);
- RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
- RTC_SetWakeUpCounter(200); //80ms
- RTC_WakeUpCmd(ENABLE);
-
- PWR_FastWakeUpCmd(ENABLE); //快速喚醒使能
- PWR_UltraLowPowerCmd(ENABLE);//超低功耗
- RTC_ITConfig(RTC_IT_WUT, ENABLE);
- }
-
- void Init_All(void)
- {
- Hsi_Clk_Init(); //初始化時鐘
- Time4_Init();
- Gpio_Init();
- //MPU6050_Init();
- }
- /*STM8L處于HALT狀態,6050處于1HZ檢測狀態*/
- void Enter_Halt(void)
- {
- //MPU6050_Init_1HZ();
- //Gpio_Init_LowPower();
- Lsi_Clk_Init();
- PWR_UltraLowPowerCmd(ENABLE);//超低功耗
- //MPU6050INT_Port->CR2 |= MPU6050INT_PINS; //開中斷
- enableInterrupts();
- halt();
- }
- /*STM8L處于AWU狀態,6050處于40HZ檢測狀態*/
- void Enter_AWU(void)
- {
- MPU6050_Init_40HZ();
- Gpio_Init_LowPower();
- Lsi_Clk_Init();
- Rtc_Init();
- PWR_UltraLowPowerCmd(ENABLE);//超低功耗
- halt();
- }
- int16_t fabs(int16_t x)
- {
- if(x > 0)
- {
- return x;
- }
- else
- {
- return -x;
- }
- }
- uint16_t fabs_2(int16_t x,int16_t y)
- {
- if(x > y)
- {
- return (uint16_t)((int32_t)x-(int32_t)y);
- }
- else
- {
- return (uint16_t)((int32_t)y-(int32_t)x);
- }
- }
- void GetStm8Id(uint8_t* uid)
- {
- uid[0] = *(uint8_t*)(ID_ADDR+4);
- uid[1] = *(uint8_t*)(ID_ADDR+6);
- uid[2] = *(uint8_t*)(ID_ADDR+8);
- uid[3] = *(uint8_t*)(ID_ADDR+9);
- //uid[0] = 0x76;
- //uid[1] = 0x44;
- //uid[2] = 0x77;
- //uid[3] = 0x61;//6,9
- }
- void KeyDeal(uint8_t code , uint8_t key_pins )
- {
- disableInterrupts();
- //KeyFlag = 0;
- TimeCount = 0;
- if(0 == (KEY_PORT_B->IDR & key_pins))//按鍵為0表示有按鍵按下
- {
- Delay100uS(100);
- if(0 == (KEY_PORT_B->IDR & key_pins))//延時10ms消抖
- {
- SysLED_High;
- Send_RF433_Data_3Time(code);
- Delay100uS(100);
- SysLED_Low;
- }
- }
- enableInterrupts();
- }
- /*******************************************
- 1s調用一次
- 1s內有2次以上震動就算檢測到震動信號,否則算為靜止時間,連續靜止5s以上重新進入低功耗模式
- 連續檢測到5次以上震動信號就算檢測到甩干信號
- *******************************************/
- void ShakeMonitor(void)
- {
- if(ShakeTime_1S >= 2)//1s內2次
- {
- ShakeTime_1S = 0;
- ShakeTime++;
- if(ShakeTime >= SHAKE_TIME_GATE)
- {
- DryFlag = 1;
- ShakeTime = 0;
- return;
- }
- }
- ShakeTestTime ++;
- if((ShakeTestTime >= 40 && ShakeTime <= 5)
- || ShakeTestTime >= SHAKE_TEST_TIME_GATE)//(40s內5s,4min內60s)進入低功耗
- {
- ShakeFlag = 0;
- ShakeTime_1S = 0;
- ShakeTime = 0;
- ShakeTestTime = 0;
- }
- }
- /*******************************************
- 100ms調用一次
- 未檢測到甩干信號時檢測甩干信號
- 檢測到甩干信號后定時喚醒檢測開門狀態
- *******************************************/
- void ShakeProcess(void)
- {
- int16_t acce_x_aver = 0;
- int16_t acce_y_aver = 0;
- int16_t acce_z_aver = 0;
- uint16_t acce_x_change = 0;
- uint16_t acce_y_change = 0;
- uint16_t acce_z_change = 0;
- static int16_t acce_x_before = 0;
- static int16_t acce_y_before = 0;
- static int16_t acce_z_before = 0;
-
- int16_t gyro_x_aver = 0;
- int16_t gyro_y_aver = 0;
- int16_t gyro_z_aver = 0;
- static int32_t Angle_x = 0;
- static int32_t Angle_y = 0;
- static int32_t Angle_z = 0;
-
- MPU6050INT_Port->CR2 &= ~MPU6050INT_PINS; //關閉中斷
- I2C_IOInit();
- MPU6050ReadAcc(&acce_x_aver,&acce_y_aver,&acce_z_aver);
-
- if(1 == ShakeFirstFlag)
- {
- DryFlag = 0;
- ShakeTestTime = 0;
- ShakeTime_1S = 0;
- ShakeTime = 0;
- OpenTestTime = 0;
- ShakeFirstFlag = 0;
- acce_x_before = acce_x_aver;
- acce_y_before = acce_y_aver;
- acce_z_before = acce_z_aver;
- }
- acce_x_change = fabs_2(acce_x_aver,acce_x_before);
- acce_y_change = fabs_2(acce_y_aver,acce_y_before);
- acce_z_change = fabs_2(acce_z_aver,acce_z_before);
-
- acce_x_before = acce_x_aver;
- acce_y_before = acce_y_aver;
- acce_z_before = acce_z_aver;
- if(0 == DryFlag) //要檢測連續震動信號
- {
- if(ACCEL_SHAKE < acce_x_change || ACCEL_SHAKE < acce_y_change || ACCEL_SHAKE < acce_z_change)//震動
- {
- ShakeTime_1S++;
- }
- TimeCount++;
- if(TimeCount >= 10)
- {
- TimeCount = 0;
- ShakeMonitor();
- }
- }
- else if(1 == DryFlag)//檢測到連續震動之后需要檢測開門信號
- {
- if(ACCEL_OPEN < acce_x_change || ACCEL_OPEN < acce_y_change || ACCEL_OPEN < acce_z_change)//開門
- {
- DryFlag = 2;
- Angle_x = 0;
- Angle_y = 0;
- Angle_z = 0;
- }
- }
- else if(2 == DryFlag)//檢測到瞬間加速度值大于開門加速度
- {
- MPU6050_Init_Active();
-
- MPU6050ReadGyro(&gyro_x_aver,&gyro_y_aver,&gyro_z_aver);
- Angle_x = Angle_x + gyro_x_aver/6; //150ms
- Angle_y = Angle_y + gyro_y_aver/6;
- Angle_z = Angle_z + gyro_z_aver/6;
- if(ANGLE_OPEN < fabs(Angle_x) || ANGLE_OPEN < fabs(Angle_y) || ANGLE_OPEN < fabs(Angle_z))
- {
- DryFlag = 0;
- ShakeFirstFlag = 0;
- ShakeFlag = 0;
- disableInterrupts();
- Send_RF433_Data_3Time(CODE_DOWN);
- enableInterrupts();
- return;
- }
- OpenTestTime++;
- if(OpenTestTime >= OPEN_TEST_TIME_GATE)//超過一定時間檢測到角度變化值小則重新檢測加速度
- {
- OpenTestTime = 0;
- DryFlag = 1;
- }
- }
- }
- uint8_t itoa(int32_t num,uint8_t *str,int8_t radix)
- {
- uint8_t index[]= "0123456789ABCDEF";
- uint32_t unum;
- int8_t i=0,j,k;
- if(num < 0)
- {
- unum=(uint32_t)(-num);
- str[i++] = '-';
- }
- else
- {
- unum = (uint32_t)num;
- }
-
- do
- {
- str[i++] = index[unum%radix];
- unum /= radix;
- }while(unum);
- str[i]='\0';
-
- /*逆序*/
- if(str[0]=='-')
- {
- k=1;/*十進制負數*/
- }
- else
- {
- k=0;
- }
-
- int8_t temp;
- for(j=k;j<=(i-1)/2;j++)
- {
- temp = str[j];
- str[j] = str[i-1+k-j];
- str[i-1+k-j] = temp;
- }
- return i;
- }
- void main(void)
- {
- disableInterrupts();
- Init_All();
- SysLED_High;
- //Delay100uS(10000);
- SysLED_Low;
- GetStm8Id(Uid);
- //Enter_Halt();
-
- enableInterrupts();
- //Enter_Halt();
- Send_RF433_Data_3Time(CODE_MATCH);
-
- while(1)
- {
- //Hsi_Clk_Init();
- //RTC_ITConfig(RTC_IT_WUT, DISABLE);
-
- switch(KeyFlag)
- {
- case 1 : //上升
- Delay100uS( TimeCount );
- if(0 == (KEY_PORT_B->IDR & (KEY_PINS_UP | KEY_PINS_DN )))
- {
-
- KeyDeal( CODE_MATCH , (KEY_PINS_UP | KEY_PINS_DN) );
- TimeCount = 0;
- }
- else if ( KeyFlag )
- {
- KeyDeal( CODE_UP, KEY_PINS_UP );
- TimeFlag ++;
- }
-
- if ( KEY_PORT_B->IDR & KEY_PINS_UP )
- {
- Send_RF433_Data( 0X1E );
- KeyFlag = 0;
- }
-
- if ( TimeFlag >= 60 )//發送60次報文,時間約10s,
- {
- KeyFlag = 0;
- TimeFlag = 0;
- }
- break;
- case 2: //下降
- Delay100uS( TimeCount );
- if(0 == (KEY_PORT_B->IDR & (KEY_PINS_UP | KEY_PINS_DN )))
- {
- KeyDeal( CODE_MATCH , (KEY_PINS_UP | KEY_PINS_DN) );
- TimeCount = 0;
- }
- else if ( KeyFlag )
- {
- KeyDeal( CODE_DOWN, KEY_PINS_DN );
- TimeFlag ++;
- }
-
- if ( KEY_PORT_B->IDR & KEY_PINS_DN )
- {
- Send_RF433_Data( 0X3E );
- KeyFlag = 0;
- }
-
- if ( TimeFlag >= 60 ) //發送60次后停止
- {
- KeyFlag = 0;
- TimeFlag = 0;
- }
- break;
- case 3: //風干
- KeyDeal( CODE_DRY , KEY_PINS_DRY );
- KeyFlag = 0;
- break;
- case 4: //照明
- KeyDeal( CODE_LED , KEY_PINS_LED );
- //Send_RF433_Data_3Time(0x79);
- KeyFlag = 0;
- break;
- case 5: //消毒
- KeyDeal( CODE_XD , KEY_PINS_XD );
- KeyFlag = 0;
- break;
- case 6: //烘干
- KeyDeal( CODE_HEAT , KEY_PINS_HEAT );
- KeyFlag = 0;
- break;
- case 7: //負離子
- KeyDeal( CODE_FLZ , KEY_PINS_FLZ );
- KeyFlag = 0;
- break;
- default:
- //Enter_Halt(); //沒有按鍵的情況下,進入低功耗
- break;
- }
- }
- }
復制代碼
所有資料51hei提供下載:
YK001 V1.0.7z
(635.9 KB, 下載次數: 43)
2019-12-30 15:56 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|