標題:
基于stm8L051F3單片機的無線遙控器程序設(shè)計
[打印本頁]
作者:
gandonjun
時間:
2019-12-30 13:59
標題:
基于stm8L051F3單片機的無線遙控器程序設(shè)計
使用stm8L051F3芯片,RF433頻率的無線遙控器代碼,支持3種按鍵模式
51hei.png
(13.46 KB, 下載次數(shù): 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--檢測到連續(xù)震動 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); //選擇內(nèi)部低速時鐘作為時鐘源
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1); //設(shè)置系統(tǒng)時鐘分頻32K
while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_LSI);//等待時鐘穩(wěn)定
CLK_HSICmd(DISABLE);
}
void Hsi_Clk_Init(void)
{
CLK_SYSCLKSourceSwitchCmd(ENABLE); //使能時鐘切換
CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI); //選擇內(nèi)部高速時鐘作為時鐘源
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_16); //設(shè)置系統(tǒng)時鐘分頻1M
while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSI);//等待時鐘穩(wěn)定
}
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狀態(tài),6050處于1HZ檢測狀態(tài)*/
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狀態(tài),6050處于40HZ檢測狀態(tài)*/
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調(diào)用一次
1s內(nèi)有2次以上震動就算檢測到震動信號,否則算為靜止時間,連續(xù)靜止5s以上重新進入低功耗模式
連續(xù)檢測到5次以上震動信號就算檢測到甩干信號
*******************************************/
void ShakeMonitor(void)
{
if(ShakeTime_1S >= 2)//1s內(nèi)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內(nèi)5s,4min內(nèi)60s)進入低功耗
{
ShakeFlag = 0;
ShakeTime_1S = 0;
ShakeTime = 0;
ShakeTestTime = 0;
}
}
/*******************************************
100ms調(diào)用一次
未檢測到甩干信號時檢測甩干信號
檢測到甩干信號后定時喚醒檢測開門狀態(tài)
*******************************************/
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; //關(guān)閉中斷
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) //要檢測連續(xù)震動信號
{
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)//檢測到連續(xù)震動之后需要檢測開門信號
{
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;/*十進制負數(shù)*/
}
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 )//發(fā)送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 ) //發(fā)送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, 下載次數(shù): 43)
2019-12-30 15:56 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1