編輯:關於Android編程
為手機設計的一種背夾,具有OTG功能、hub和充電功能功能。具體如下:
1、只插入手機時,手機處於host狀態,充電寶給手機充電,同時手機可以訪問充電寶上的SD卡
2、插入電腦後,電腦處於host狀態,手機和sd都是slave狀態
3、充電寶上有4個led,顯示電量
4、手機通過PD與充電寶進行通信與交互
硬件芯片:STM32F030C8T6
開發環境:windows xp/win7
開發工具:IAR+STM32CUBEMX+ST_LINKER
主要包括了充電、放電、主從切換以及PD通信等主要的4個模塊。下面從每個模塊說起
這裡充電采用的IC是BQ25895,帶BC1.2協議的芯片,充電部分主要模仿MTK平台上的switch charging,具體driver code 如下:
#include "stm32f0xx_hal.h" #include "switch_charging.h" extern int8_t UI_Percentage; uint8_t charging_state=CHR_PRE; extern uint8_t charger_type; int16_t temp_input_cc_value; int16_t temp_cc_value; static void select_charging_current() { switch (charger_type) { case STANDARD_HOST: //sdp usb host for max 500ma temp_input_cc_value=500; temp_cc_value=500; break; case CHARGING_HOST: //cdp for max 1.5a temp_input_cc_value=1500; temp_cc_value=1500; break; case STANDARD_CHARGER: //dcp for max3.25a temp_input_cc_value=3000; temp_cc_value=3000; break; case UNKNOWN_CHARGER: //500ma temp_input_cc_value=500; temp_cc_value=500; break; case NON_STANDARD_CHARGER: //appale charger 1a temp_input_cc_value=1000; temp_cc_value=1000; break; case NO_CHARGER: break; } } void pchr_turn_on_charging() { /***1:gpio enable***/ HAL_GPIO_WritePin(GPIOA, GPIO_CHG_EN_Pin, GPIO_PIN_RESET); /***gpio enable***/ /***2:bq24595 reg init for charging***/ /***bq24595 reg init for charging***/ /***3:select charging current***/ select_charging_current(); bq2589x_set_input_current_limit(temp_input_cc_value); bq2589x_set_chargecurrent(temp_cc_value); /***select charging current***/ /***4:set cc_cv voltage***/ /***set cc_cv voltage***/ /***5:enable charging***/ bq2589x_enable_charge(); /****enable charging***/ } static uint8_t charging_full_check() { uint8_t state; state=bq2589x_is_charge_done(); return state; } void Pre_Charge_Mode() { pchr_turn_on_charging(); if(UI_Percentage==100) charging_state=CHR_FULL; else charging_state=CHR_CC; } void Constant_Charge_Mode() { pchr_turn_on_charging(); if(charging_full_check()==TRUE) charging_state=CHR_FULL; } void Battery_Full() { if(charging_full_check()==FALSE) charging_state=CHR_CC; } void mt_battery_charging_algorithm(void)//just like the mtk switch charging. { switch (charging_state) { case CHR_PRE: Pre_Charge_Mode(); break; case CHR_CC: Constant_Charge_Mode(); break; case CHR_FULL: Battery_Full(); break; default: break; } }
放電模塊模仿的是展訊平台的,由於系統不帶有硬件庫侖計,只能采用通過讀取電池的電壓來換算成電池電量。 這裡需要注意以下幾點:
(1)、電池電量的變化不能出現跳變,充電時逐漸+1,放電時逐漸-1,
(2)、充電時電量只能增加,放電時只能減少
#include "stm32f0xx_hal.h" #include "battery_common.h" int8_t UI_Percentage; uint8_t chr_det=FALSE; uint8_t charger_type; uint8_t usb_typec_plug_in; uint8_t battery_run_timer=FALSE; uint8_t phone_is_online = FALSE; uint8_t pc_is_online =FALSE; uint8_t charger_is_online = FALSE; extern uint8_t charging_state; extern uint8_t sleep_mode; uint8_t need_init; /* usb mode select */ void Usb_Sel_Host(enum host_is host_type) { if(host_type==PC) { HAL_GPIO_WritePin(GPIOA, USB_SEL_Pin, GPIO_PIN_SET); } else if(host_type==PHONE) { HAL_GPIO_WritePin(GPIOA, USB_SEL_Pin, GPIO_PIN_RESET); } else if(host_type==NONE) { } } void check_host_is() { if(pc_is_online==TRUE && phone_is_online==TRUE) { Usb_Sel_Host(PC); } else if(pc_is_online==TRUE && phone_is_online==FALSE) { Usb_Sel_Host(PC); } else if(pc_is_online==FALSE && phone_is_online==TRUE) { Usb_Sel_Host(PHONE); } else if(pc_is_online==FALSE && phone_is_online==FALSE) { Usb_Sel_Host(NONE); } } /* interrupt for EINT_CHR_STAT callback */ void check_chrdet_type() { uint8_t temp_charger_type; temp_charger_type=bq2589x_read_vbus_type(); if(temp_charger_type==0) charger_type=NO_CHARGER; else if(temp_charger_type==1) charger_type=STANDARD_HOST; else if(temp_charger_type==2) charger_type=CHARGING_HOST; else if(temp_charger_type==3) charger_type=STANDARD_CHARGER; else if(temp_charger_type==5) charger_type=UNKNOWN_CHARGER; else if(temp_charger_type==6) charger_type=NON_STANDARD_CHARGER; if(temp_charger_type!=0 || temp_charger_type!=7)//0:no charger,7:OTG { charger_is_online= TRUE; chr_det = TRUE; } else{ charger_is_online= FALSE; chr_det = FALSE; } } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin==EINT_CHG_STAT_Pin) { check_chrdet_type(); if(charger_type==STANDARD_HOST || charger_type==CHARGING_HOST) pc_is_online = TRUE; else pc_is_online = FALSE; } else if(GPIO_Pin==CC_INT_Pin) { if(usb_typec_plug_in==TRUE) { phone_is_online = TRUE; }else if(usb_typec_plug_in==FALSE) { phone_is_online = FALSE; } } else if(GPIO_Pin==POWER_ON_N_Pin) { if(sleep_mode==0) enter_stopmode(); } check_host_is(); if(sleep_mode==1) { need_init=1; sleep_mode =0; } } static void sync_UI_percentage() { uint8_t percentage_temp; uint8_t timer=0; percentage_temp = get_battery_percentage(); if(chr_det==TRUE) { if(UI_Percentage100) UI_Percentage=100; }else if(chr_det==FALSE) { if(UI_Percentage>percentage_temp) timer++; else timer=0; if(timer==5) UI_Percentage--; if(UI_Percentage<0) UI_Percentage=0; } } /*** O ON X OFF * BLINK discharing: 0%~25% O X X X 25%~50% O O X X 50%~75% O O O X 75%~100% O O O O charging: 0%~25% O * X X 25%~50% O O * X 50%~75% O O O * 75%~100% O O O O ***/ static void percentage_display() { sync_UI_percentage(); if(chr_det==TRUE)//for charging { if(UI_Percentage>=75) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_ON); Led_Sink_Set(LED_SINK_3,LED_ON); Led_Sink_Set(LED_SINK_4,LED_ON); } else if(UI_Percentage>=50) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_ON); Led_Sink_Set(LED_SINK_3,LED_ON); Led_Sink_Blink(LED_SINK_4,LED_BLINK_TIME_1000); } else if(UI_Percentage>=25) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_ON); Led_Sink_Blink(LED_SINK_3,LED_BLINK_TIME_1000); Led_Sink_Set(LED_SINK_4,LED_OFF); }else if(UI_Percentage>0) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Blink(LED_SINK_2,LED_BLINK_TIME_1000); Led_Sink_Set(LED_SINK_3,LED_OFF); Led_Sink_Set(LED_SINK_4,LED_OFF); } }else if(chr_det==FALSE)//for dis_charging { if(UI_Percentage>=75) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_ON); Led_Sink_Set(LED_SINK_3,LED_ON); Led_Sink_Set(LED_SINK_4,LED_ON); } else if(UI_Percentage>=50) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_ON); Led_Sink_Set(LED_SINK_3,LED_ON); Led_Sink_Set(LED_SINK_4,LED_OFF); } else if(UI_Percentage>=25) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_ON); Led_Sink_Set(LED_SINK_3,LED_OFF); Led_Sink_Set(LED_SINK_4,LED_OFF); }else if(UI_Percentage>0) { Led_Sink_Set(LED_SINK_1,LED_ON); Led_Sink_Set(LED_SINK_2,LED_OFF); Led_Sink_Set(LED_SINK_3,LED_OFF); Led_Sink_Set(LED_SINK_4,LED_OFF); } } } uint8_t sleep_timer=0; void check_need_sleep() { if(phone_is_online==FALSE && pc_is_online==FALSE && charger_is_online ==FALSE) sleep_timer++; else sleep_timer =0; if(sleep_timer==6)//about 60 seconds. { enter_stopmode();//go to sleep mode sleep_timer = 0; } } void battery_thread() { uart_printf("battery_thread:battery_run_timer=%d\n",battery_run_timer); if(battery_run_timer==TRUE) { percentage_display(); if(chr_det==TRUE) { mt_battery_charging_algorithm(); }else{ charging_state = CHR_PRE; } check_need_sleep(); } } /* get battery voltage adc value */ void init_battery() { /***[1] init ui_percentage***/ percentage_display(); /***[2] check pc or phone is online or outline***/ }
#include "stm32f0xx_hal.h" #include "led.h" //#include "stm32f0xx_it.h" static uint16_t blink_led_type=1; extern TIM_HandleTypeDef htim6; extern TIM_HandleTypeDef htim14; extern uint8_t battery_run_timer; /* interrupt for timer6 callback*/ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance==htim6.Instance) { if((blink_led_type==LED_SINK_1_Pin) || (blink_led_type==LED_SINK_2_Pin)) HAL_GPIO_TogglePin(GPIOF, blink_led_type); else if((blink_led_type==LED_SINK_3_Pin) || (blink_led_type==LED_SINK_4_Pin)) HAL_GPIO_TogglePin(GPIOA, blink_led_type); } if(htim->Instance==htim14.Instance) { battery_run_timer = TRUE; } } /* led set */ void Led_Sink_Set(enum tct_led_sink_type led_type,enum tct_led_state led_state) { switch (led_type) { case LED_SINK_1: if(led_state==LED_ON) HAL_GPIO_WritePin(GPIOF, LED_SINK_1_Pin, GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOF, LED_SINK_1_Pin, GPIO_PIN_RESET); break; case LED_SINK_2: if(led_state==LED_ON) HAL_GPIO_WritePin(GPIOF, LED_SINK_2_Pin, GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOF, LED_SINK_2_Pin, GPIO_PIN_RESET); break; case LED_SINK_3: if(led_state==LED_ON) HAL_GPIO_WritePin(GPIOA, LED_SINK_3_Pin, GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOA, LED_SINK_3_Pin, GPIO_PIN_RESET); break; case LED_SINK_4: if(led_state==LED_ON) HAL_GPIO_WritePin(GPIOA, LED_SINK_4_Pin, GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOA, LED_SINK_4_Pin, GPIO_PIN_RESET); break; default: break; } } /* led blink */ void Led_Sink_Blink(enum tct_led_sink_type led_type,enum tct_led_blink_time led_blink_time) { if(led_blink_time==LED_BLINK_TIME_0) HAL_TIM_Base_Stop_IT(&htim6);//stop timer6 else{ htim6.Init.Prescaler = 0;//prescaler clock htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = led_blink_time;//blink period HAL_TIM_Base_Start_IT(&htim6);//start timer6 } switch (led_type) { case LED_SINK_1: blink_led_type=LED_SINK_1_Pin; break; case LED_SINK_2: blink_led_type=LED_SINK_2_Pin; break; case LED_SINK_3: blink_led_type=LED_SINK_3_Pin; break; case LED_SINK_4: blink_led_type=LED_SINK_4_Pin; break; default: break; } } /* led init */
#include#include #include "stm32f0xx_hal.h" #include "print.h" extern UART_HandleTypeDef huart1; void uart_printf(char *fmt, ...) { char uart1_pString[101]; va_list uart1_ap; va_start(uart1_ap, fmt); vsnprintf(uart1_pString, 100, fmt, uart1_ap); va_end(uart1_ap); HAL_UART_Transmit_IT(&huart1, (uint8_t *)uart1_pString, sizeof(uart1_pString)); }
#include "stm32f0xx_hal.h" #include "sleep.h" uint8_t sleep_mode; void enter_stopmode() { sleep_mode =1; HAL_GPIO_WritePin(GPIOA, VDD33_HUB_EN_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOA, VDD33_EN_Pin, GPIO_PIN_RESET); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); }
由於項目暫停,PD狀態機的移植代碼還沒提供,因此沒有繼續開發下去,板子也沒到,因此也沒有在真實的板子上運行過,還有待驗證。
如今的人們幾乎每天都會用手機拍攝無數張照片,但是照片一多管理就是一件麻煩事。一般來說,用戶管理照片不是系統的圖庫就是快圖應用,後者雖然浏覽速度快但管理功能卻
由於努比亞 Z5S(NX503A)對底包的要求較高,安卓4.2的升級到4.4的需要升級4.4的底包再進行刷機,反之亦然刷機精靈降級教程步驟如下 1、首先下
環境主機:WIN 7開發環境:Android Studio2.2.2步驟安裝NDK打開Tools->Android->SDK Manager->SDK
Android PreferenceActivity與PreferenceFragment前言轉來轉去又回到了Android,閒話少說,這裡是參考Androi