|
分享一套基于BS818A的八位電容觸摸按鍵方案
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (59.69 KB, 下載次數(shù): 73)
下載附件
2018-7-31 17:18 上傳
成品pcb正面和背面:
0.png (531.02 KB, 下載次數(shù): 73)
下載附件
2018-7-31 17:20 上傳
0.png (553.92 KB, 下載次數(shù): 69)
下載附件
2018-7-31 17:21 上傳
元件清單:
0.png (36.4 KB, 下載次數(shù): 77)
下載附件
2018-7-31 17:20 上傳
STM8L15x-16x-05x-AL31-L_StdPeriph_Lib 原文件夾名稱/庫名稱。
1.觸發(fā)關(guān)閉的動作從中斷it文件中拿出。
某些情況下,可能出現(xiàn)設(shè)定左右中斷后halt過程中。突然進(jìn)入中斷,關(guān)閉中斷,導(dǎo)致再也無法喚醒。
2.代碼里面放一個計數(shù)器,計算喚醒的次數(shù)。
3.ADC 的while(1)等待需要做一個超時限制。
4.整機需要RTC喚醒,或者看門狗么?
5.需要減少喚醒功耗。
6.
///////////////////
1.2016-06-18增加沒有傳感接入情況下的Err顯示。
2.
/////////
1.增加開機后的debug顯示。
2.關(guān)閉初始化后的debug。
3.增加一個次數(shù)的變量。增加一個喚醒次數(shù)的變量。
4.增加檢測detect引腳,觸發(fā)debug輸出的代碼。
5.修改err顯示值的設(shè)定范圍。----------------------------
6.修改電池電壓的獲取時間。----------------------------
7.關(guān)閉屏幕的時候,按照正確的流程來。將多余的電留在屏幕電容里面上,估計可以減少對啟動電流的需求。
8.
///////////////////////////
1.修改detect pin輸出的debug信息。=========
2.增加獨立watchdog。=========
3.顯示時間增加到5秒==========
4.修改option 代碼為 00 00 00 03 00 00 00 00 ,iwatchdog 由硬件啟動,halt后停止,關(guān)閉代碼讀取。===========
5.增加reset次數(shù)記錄和顯示。
PCB空板使用說明
1.焊接電池座時,注意焊盤正負(fù)極。
2.根據(jù)自己的需要,在按鍵上覆蓋按鍵面板材料。
3.J1跳線用于測試整機功耗。
4.J11跳線用于測試芯片的工作模式(串行,并行)
5.J13跳線用于測試芯片的低功耗模式(會影響按鍵掃描速度)
6.整個板子可以根據(jù)需要,從中間切開,分成單獨的芯片模塊和MCU模塊。以便使用其他方案驅(qū)動。
7.J12為STM8L的SWIM接口。
8.在粘接壓克力等面板到PCB上時,建議使用3M的468MP無基材膠。
單片機源程序如下:
- /* Includes ------------------------------------------------------------------*/
- #include "stm8l15x.h"
- #include "main.h"
- /** @addtogroup STM8L15x_StdPeriph_Template
- * @{
- */
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
- void DEBUGBOARD_Init(void);
- void GPIO_LowPower_Config(void);
- void IWDG_Config(void);
- /* Private functions ---------------------------------------------------------*/
- #define NSS_H GPIO_SetBits(GPIOA, GPIO_Pin_2)
- #define NSS_L GPIO_ResetBits(GPIOA, GPIO_Pin_2)
- #define DATA_H GPIO_SetBits(GPIOD, GPIO_Pin_0)
- #define DATA_L GPIO_ResetBits(GPIOD, GPIO_Pin_0)
- #define SCK_H GPIO_SetBits(GPIOA, GPIO_Pin_3)
- #define SCK_L GPIO_ResetBits(GPIOA, GPIO_Pin_3)
- void delay_us(volatile uint32_t times)
- {
- while(times--);
- }
- void GPIO_LowPower_Config(void)
- {
- #if 1////all low out
- GPIO_Init(GPIOA, GPIO_Pin_0, GPIO_Mode_Out_PP_Low_Fast);//SWIM
- GPIO_Init(GPIOA, GPIO_Pin_1, GPIO_Mode_Out_PP_Low_Fast);///NRST
- GPIO_Init(GPIOA, GPIO_Pin_2, GPIO_Mode_In_FL_No_IT);//bin1
- GPIO_Init(GPIOA, GPIO_Pin_3, GPIO_Mode_In_FL_No_IT);//bin0
- GPIO_Init(GPIOB, GPIO_Pin_0, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_2, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_3, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_4, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_Out_PP_High_Fast);///
- GPIO_Init(GPIOC, GPIO_Pin_0, GPIO_Mode_Out_PP_Low_Fast);////SDA
- GPIO_Init(GPIOC, GPIO_Pin_1, GPIO_Mode_Out_PP_Low_Fast);////SCL
- GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_Out_PP_Low_Fast);////
- GPIO_Init(GPIOC, GPIO_Pin_5, GPIO_Mode_In_FL_No_IT);///bin3
- GPIO_Init(GPIOC, GPIO_Pin_6, GPIO_Mode_In_FL_No_IT);///bin2
- GPIO_Init(GPIOD, GPIO_Pin_0, GPIO_Mode_In_FL_No_IT);///debug data
- #endif
- }
- void testpin(uint8_t high_low)
- {
- if(high_low == 1)
- GPIO_SetBits(GPIOC,GPIO_Pin_6);
- else
- GPIO_ResetBits(GPIOC,GPIO_Pin_6);
- }
- void Init(void)
- {
- //IWDG_Config();
- /*High speed internal clock prescaler: 1*/
- CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
- //GPIO_Config();
- GPIO_LowPower_Config();
- //ADC_Periph_Init();///2017-01-04
-
- #if 1//def DEBUG
- ///DEBUGBOARD_Init();///move in GPIO_LowPower_Config();
- #endif
- }
- void Power_Ctrl(uint8_t onoff)
- {
- if(onoff == 1)///////更換了電阻為上拉。(更加省電)2016-05-11/////帶mos 管,1
- {
- GPIO_ResetBits(GPIOB, GPIO_Pin_7);///通電
- }
- else
- {
- GPIO_SetBits(GPIOB, GPIO_Pin_7);///斷電
- }
- }
- void uart_put(uint8_t data)/////new 2016-07-19///////因為中斷問題,80->100
- {
- uint8_t i;
- NSS_L;
- SCK_L;
- if((data&0x80)!=0)/////第一個bit data
- DATA_H;
- else
- DATA_L;
- delay_us(10);
- SCK_H;
- for(i=1;i<8;i++)
- {
- delay_us(10);
- SCK_L;
- NSS_H;/////////////////完成識別后才拉高。
-
- if(((data<<i)&0x80)!=0)
- DATA_H;
- else
- DATA_L;
- delay_us(10);
- SCK_H;
- }
- delay_us(10);//////每個byte的間隙。
- }
- void DEBUGBOARD_Init(void)
- {
- /* Enable AHB clock to the GPIO domain. */
- //LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
- GPIO_Init(GPIOA, GPIO_Pin_2, GPIO_Mode_Out_PP_Low_Fast);//ce
- GPIO_Init(GPIOA, GPIO_Pin_3, GPIO_Mode_Out_PP_Low_Fast);//clk
- GPIO_Init(GPIOD, GPIO_Pin_0, GPIO_Mode_Out_PP_Low_Fast);//data
- }
- void RTC_Config(uint16_t time)//////////////兩個RTC 會沖突。在需要調(diào)用的時候通過改變CLK源實現(xiàn)重啟。2017-01-06
- {
- CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
- #if 0//def USE_LSE
- CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
- #else
- CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);///////內(nèi)置晶振38K////////2375Hz
- #endif
- Calendar_Init();//////LSI 38k set to 1Hz spre
- /* Configures the RTC wakeup timer_step = RTCCLK/16 = LSE/16 = 488.28125 us */
- ///////ck_spre frequency = ck_apre frequency/(PREDIV_S+1)
- ///////ck_apre frequency = fRTCCLK frequency/ (PREDIV_A+1)
- ///////ck_spre frequency = (fRTCCLK frequency/ (PREDIV_A+1))/(PREDIV_S+1)
- ///////RTCCLK frequency = CLK_RTCCLKSource_LSI/CLK_RTCCLKDiv_1
- ///////ck_spre frequency = (38000/(0x7f+1))/(0x00ff+1) == 1s
- RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);////RTC_WakeUpClock_RTCCLK_Div16////---2375/16 = 148.43Hz == 0.0067368s///////////設(shè)置為1秒
-
- //RTC_BypassShadowCmd(DISABLE);/////////////////////move here 2016-05-29
- /* Enable wake up unit Interrupt */
- RTC_ITConfig(RTC_IT_WUT, ENABLE); //開啟中斷
-
- RTC_SetWakeUpCounter(time); //設(shè)置RTC Weakup計算器初值
-
- RTC_WakeUpCmd(ENABLE); //使能自動喚醒
- }
- void RTC_Config_old(void)
- {
- CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
- #ifdef USE_LSE
- CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
- #else
- CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);
- #endif
- /* Configures the RTC wakeup timer_step = RTCCLK/16 = LSE/16 = 488.28125 us */
- RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
- Calendar_Init();
- RTC_BypassShadowCmd(DISABLE);/////////////////////move here 2016-05-29
- /* Enable wake up unit Interrupt */
- RTC_ITConfig(RTC_IT_WUT, ENABLE);
-
- }
- uint8_t WakeUpModeParser(uint8_t wakeupsource,uint8_t timeout_func,uint8_t up_func,uint8_t down_func)
- {
- uint8_t sys_mod = SYS_STANDBY_MODE;
- if(wakeupsource == 1)///up
- {
- sys_mod = up_func;
- }
- else if(wakeupsource == 2)///down
- {
- sys_mod = down_func;
- }
- else if(wakeupsource == 3)////RTC wake up
- {
- sys_mod = timeout_func;
- #ifdef DEBUG
- printf_string("RTC wake\n");
- #endif
- }
- else
- {
- sys_mod = SYS_STANDBY_MODE;
- }
- return sys_mod;
-
- }
- void RTC_SetSleepTimer(uint8_t sleeptype,uint16_t counter)
- {
- if(counter == DISABLE)
- {
- RTC_WakeUpCmd(DISABLE);
- CLK_PeripheralClockConfig(CLK_Peripheral_RTC, DISABLE);
- }
- else
- {
- /////////定時器打開。///////1秒后喚醒RTC_Config();
- /* RTC wake-up event every 500 ms (timer_step x (1023 + 1) )*/
- CLK_PeripheralClockConfig(CLK_Peripheral_RTC,ENABLE);/////////temp 是不是可以移動到初始化的地方?2017-01-06
- if(sleeptype == TYPE_SHORTTIME)
- {
- RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
- RTC_SetWakeUpCounter((counter<<1));//RTC wakeup timer_step = RTCCLK/16 = LSE/16 = 488.28125 us */////2048->1000ms //////~~= y=2X
- }
- else if(sleeptype == TYPE_LONGTIME)
- {
- RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);////RTC_WakeUpClock_RTCCLK_Div16////---2375/16 = 148.43Hz == 0.0067368s///////////設(shè)置為1秒
- RTC_SetWakeUpCounter(counter);
- }
- RTC_WakeUpCmd(ENABLE);
- }
-
- }
- volatile uint32_t g_timer_count = 0;
- void TIMER_Configuration(void)
- {
- TIM4_DeInit();
- /* Enable TIM4 Clock */
- CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, ENABLE);
- /* Time base configuration */
- TIM4_TimeBaseInit(TIM4_Prescaler_16384, 0xf0 );
- /* Enable TIM4 IT UPDATE */
- TIM4_ITConfig(TIM4_IT_Update, ENABLE);
- /* Clear the Flag */
- TIM4_ClearFlag(TIM4_FLAG_Update);
- /* Enable TIM4 */
- TIM4_Cmd(ENABLE);
- }
- RTC_InitTypeDef RTC_InitStr;
- /**
- * @brief Calendar Configuration.
- * @param None
- * @retval None
- */
- void Calendar_Init(void)
- {
- RTC_InitStr.RTC_HourFormat = RTC_HourFormat_24;
- RTC_InitStr.RTC_AsynchPrediv = 0x7c;
- RTC_InitStr.RTC_SynchPrediv = 0x012F;
- RTC_Init(&RTC_InitStr);
- }
- ///////////////////////////////////////////////////////////////
- #define RELOAD_VALUE 254
- /**
- * @brief Configures the IWDG to generate a Reset if it is not refreshed at the
- * correct time.
- * @param None
- * @retval None
- */
- void IWDG_Config(void)
- {
- /* Enable IWDG (the LSI oscillator will be enabled by hardware) */
- IWDG_Enable();
-
- /* IWDG timeout equal to 214 ms (the timeout may varies due to LSI frequency
- dispersion) */
- /* Enable write access to IWDG_PR and IWDG_RLR registers */
- IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
-
- /* IWDG configuration: IWDG is clocked by LSI = 38KHz */
- IWDG_SetPrescaler(IWDG_Prescaler_128);////>510ms
-
- /* IWDG timeout equal to 214.7 ms (the timeout may varies due to LSI frequency dispersion) */
- /* IWDG timeout = (RELOAD_VALUE + 1) * Prescaler / LSI
- = (254 + 1) * 32 / 38 000
- = 214.7 ms */
- IWDG_SetReload((uint8_t)RELOAD_VALUE);
-
- /* Reload IWDG counter */
- IWDG_ReloadCounter();
- }
- void IWatchdogReset()
- {
- /* IWDG Configuration */
- IWDG_Config();
-
- while(1);///////////等待reset
- #if 0
- while (1)
- {
- /* Reload IWDG counter */
- IWDG_ReloadCounter();
- }
- #endif
- }
- void SoftReset_AtFirstTimeStartup(void)
- {
- uint32_t startadd = FLASH_DATA_EEPROM_START_PHYSICAL_ADDRESS;// + (uint16_t)FLASH_BLOCK_SIZE;
- if(FLASH_ReadByte(startadd) != 0xfb)/////////如果沒有寫過0xfa,寫入0xfa,并reset
- {
- /* Define flash programming Time*/
- FLASH_SetProgrammingTime(FLASH_ProgramTime_Standard);
- /* Unlock flash data eeprom memory */
- FLASH_Unlock(FLASH_MemType_Data);
- /* Wait until Data EEPROM area unlocked flag is set*/
- while (FLASH_GetFlagStatus(FLASH_FLAG_DUL) == RESET)
- {}
- FLASH_ProgramByte(startadd,(uint8_t)(0xfb));///////不用擦,直接寫
- FLASH_Lock(FLASH_MemType_Data);/////鎖定
-
- IWatchdogReset();//////通過watchdog 軟reset
- }
- /* Check if the system has resumed from IWDG reset */
- if (RST_GetFlagStatus(RST_FLAG_IWDGF) != RESET)//////////////檢查是否有watchdog reset的flag。去掉
- {
- /* IWDGF flag set */
- /* Clear IWDGF Flag */
- RST_ClearFlag(RST_FLAG_IWDGF);
- #ifdef DEBUG
- printf_string("Reset by watchdog\n");
- #endif
- }
- else
- {
- /* IWDGF flag is not set */
- #ifdef DEBUG
- printf_string("Normal reset\n");
- #endif
- }
- }
- ///////////////////////////////////////////////////////////////
- void IWDG_test(void)
- {
- printf_string("reset\n");
- IWDG_ReloadCounter();
- while(1)
- {
- testpin(1);
- delay_us(102660);////////max delay_us(102660) == 840ms
- IWDG_ReloadCounter();
- testpin(0);
- delay_us(102660);
- IWDG_ReloadCounter();
- }
- }
- //**********************************************************
- uint8_t SPIx_ReadWriteByte(uint8_t dat)///////////sw spi
- {
- uint8_t i = 0;
- uint8_t temp = 0;
- //uint8_t b = 0;
- SCLK_L;//GPIOSetValue(PORT0,6,0);//GPIO_ResetBits(GPIOB, GPIO_Pin_0); //SCK=0
- delay_us(2);
- for(i=0;i<8;i++)
- {
- if(dat&0x80) //1000,0000;輸出1
- {
- MOSI_H;//GPIOSetValue(PORT0,9,1);//GPIO_SetBits(GPIOB, GPIO_Pin_1); //MOSI=1
- }
- else
- {
- MOSI_L;//GPIOSetValue(PORT0,9,0);//GPIO_ResetBits(GPIOB, GPIO_Pin_1); //MOSI=0
- }
- dat = (dat << 1); //串行輸出
- temp = (temp << 1); //串行輸入
- //if(LPC_GPIO0->DATA&(1<<8))
- if((GPIOB->IDR & (uint8_t)GPIO_Pin_2)!=0)
- {
- temp++; //讀入1
- }
- delay_us(2);
- SCLK_H;////GPIO_SetBits(GPIOB, GPIO_Pin_0); //SCK=1
- delay_us(2);
- SCLK_L;////GPIO_ResetBits(GPIOB, GPIO_Pin_0); //SCK=0
- }
- return temp; //返回讀入的數(shù)據(jù)
- }
- void LED_onoff(uint8_t led,uint8_t onoff)
- {
- uint8_t led_light = 0x00;
-
- switch(led)
- {
- case 0:
- if(onoff == 1)
- {
- led_light |= 0x01;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x01);///斷電
- }
- break;
- case 1:
- if(onoff == 1)
- {
- led_light |= 0x02;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x02);///斷電
- }
- break;
- case 2:
- if(onoff == 1)
- {
- led_light |= 0x04;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x04);///斷電
- }
- break;
- case 3:
- if(onoff == 1)
- {
- led_light |= 0x08;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x08);///斷電
- }
- break;
- case 4:
- if(onoff == 1)
- {
- led_light |= 0x10;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x10);///斷電
- }
- break;
- case 5:
- if(onoff == 1)
- {
- led_light |= 0x20;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x20);///斷電
- }
- break;
- case 6:
- if(onoff == 1)
- {
- led_light |= 0x40;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x40);///斷電
- }
- break;
- case 7:
- if(onoff == 1)
- {
- led_light |= 0x80;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0x80);///斷電
- }
- break;
- case 8:
- if(onoff == 1)
- {
- led_light |= 0xff;// GPIO_ResetBits(GPIOB, GPIO_Pin_0);///通電
- }
- else
- {
- led_light &= (~0xff);///斷電
- }
- break;
- default:
- break;
-
- }
- GPIOB->ODR = (~led_light);////低電平為開2017-03-02
- }
- //**********************************************************
- uint8_t ParallelPort_in(void)
- {
- uint8_t value = 0x00;
- if ((GPIOA->IDR & (uint8_t)GPIO_Pin_3)!=0)//(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3));///0
- {
- value|= 0x01;
- }
- if((GPIOA->IDR & (uint8_t)GPIO_Pin_2)!=0)//(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2));///1
- {
- value|= 0x02;
- }
- if((GPIOC->IDR & (uint8_t)GPIO_Pin_6)!=0)//(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6));///2
- {
- value|= 0x04;
- }
- if((GPIOC->IDR & (uint8_t)GPIO_Pin_5)!=0)//(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5));///3
- {
- value|= 0x08;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
0.png (42.39 KB, 下載次數(shù): 84)
下載附件
2018-7-31 17:22 上傳
所有資料51hei提供下載:
818A的八位電容觸摸按鍵方案_PDF_C97370_2017-03-10.7z
(13.16 MB, 下載次數(shù): 238)
2021-8-19 01:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|