編輯:關於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) 升級/降級底包教程
由於努比亞 Z5S(NX503A)對底包的要求較高,安卓4.2的升級到4.4的需要升級4.4的底包再進行刷機,反之亦然刷機精靈降級教程步驟如下 1、首先下
Android Studio2.2.2 配置NDK
環境主機:WIN 7開發環境:Android Studio2.2.2步驟安裝NDK打開Tools->Android->SDK Manager->SDK
Android PreferenceActivity與PreferenceFragment詳解及簡單實例
Android PreferenceActivity與PreferenceFragment前言轉來轉去又回到了Android,閒話少說,這裡是參考Androi