|
从开始玩STM32F开始就用官方库.感觉快上手,外设配置用官方库. 常用的输出等(如更新I/O)就直接操作寄存器. 在不追求处理速度下完全可以接受. 在一个用F051的项目也直接用触摸库,连芯片手册都没看;- W- [3 M M0 T+ ]/ `. b 花了不少时间才将变量定义好,% v7 f: E" ` n. R 又花了不少时间初始化成功 -------注意:触摸库会挨个将GPIO的CLK打开,* Z+ \" l0 G6 l& _' J 最后发现整个触摸功占用了快(整个系统)1/5的时间, 看了手册才发现原来F051的触摸功能就像USART或其它外设一样,都有对应的寄存器,计数寄存器,中断等.简单易用9 `/ k; f* r" S# M --------注:STM8/STM32L1XX并非这样,比较麻烦 大家没必要去找库. 另:硬件电路上,采样(充电)电容不一定要用那么大的,用小点灵敏度高很多(要不是1S内采样不了几次); 要不是本来速度就慢,再要虑波一下,就其慢无比了. |
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
小白也能明白的STM32的低功耗与唤醒机制
STM32系统中2种数据掉电保护的方法
分享STM32F051中文参考手册(重制书签版)
AI工具训练营-用ChatGPT解决HID Keyboard实现的问题
STM32固件库分享,超全系列整理
STM32小白入门指南:从基础到OTA实现方案
STM32超详细学习笔记
新手必看!STM32单片机应该怎么学?
如果你解决了这些问题,就可以直接学STM32
微信公众号
手机版
//电容测量型按键检测支持 定义和函数 & w; x1 e' A* J
//-----------------------------------------------------------------------------) Z3 e3 X+ b( `2 @' u: D3 L
#define KEY1_R (GPIOD->IDR & 0x04)//PD2, }+ m/ o f8 C5 I* A5 H0 W
//#define KEY2_R (GPIOC->IDR & 0x80)//PC7 g, l7 Z' p; p! }9 g. J
//#define KEY3_R (GPIOD->IDR & 0x20)//PD5% q- Z, y1 o. M, j
//#define KEY4_R (GPIOD->IDR & 0x40)//PD67 z# A8 b8 C, K( T" B' r
#define KEY_SH (GPIOD->ODR |=0x08)//PD32 b3 v: G! r0 K
#define KEY_SL (GPIOD->ODR &=0xf7)//PD3
//-----------------------------------------------------------------------------; a5 f+ c E$ J, S
#define KEY1_O_1 {GPIOD->ODR|=0x04;GPIOD->DDR|=0x04;GPIOD->CR1|=0x04;}//PD2
#define KEY1_O_0 {GPIOD->ODR&=0xFb;GPIOD->DDR|=0x04;GPIOD->CR1|=0x04;}//PD2
#define KEY1_I {GPIOD->CR1&=0xfb;GPIOD->DDR&=0xfb;}//PD2
; I% ~0 Q- L" ~
//#define KEY2_R (GPIOC->IDR & 0x80)//PC7& [, M5 v$ F# \
//#define KEY3_R (GPIOD->IDR & 0x20)//PD58 e% W4 j0 p; s6 P/ I! P0 _( B
//#define KEY4_R (GPIOD->IDR & 0x40)//PD6
//-----------------------------------------------------------------------------" x' \; w# w6 o( T; w$ P
#define GT_GATE 5. F; \& ^" x4 i m l; K
//-----------------------------------------------------------------------------
unsigned char key_time_sta1;//充电开始时间
unsigned char key_time1;//动态时间
unsigned char key_CH1;//按键充放电时间基准
unsigned char key_delay1;//按键保持存在的时间倒计时3 }; k( T: c& Y- m4 b4 @
unsigned char key_filter1;//按键滤波 毛刺消除
unsigned char key_count;//按键计数count 用于长按设置
unsigned char key_value;//按键数据* Z6 |: ?, q& p) \0 c
#define SET_K1 (key_value|=0x01)
#define SET_K2 (key_value|=0x02)+ i3 \. N v, T& _1 Y1 S/ d
#define SET_K3 (key_value|=0x04)
#define SET_K4 (key_value|=0x08)
#define Key_on (key_value&0x01); O9 D( [5 ] u/ s/ ^
#define Key_set (key_value&0x02)
#define Key_add (key_value&0x04)
#define Key_pause (key_value&0x08)- z, L _( f6 ^7 T1 C2 Z( m2 N- S
unsigned char key_shadow;//按键影子数据/ `! t& Z1 _) x" x5 A$ P* _
#define lkey_add (key_shadow&0x04)
unsigned char key_buf[64];
unsigned char key_i;
//-----------------------------------------------------------------------------% p& a# f6 G; n2 f- \
void CM_filter()
{//按键滤波调用+ ]% \( R6 R1 M2 u% N. H6 |2 k
if(key_filter1<10)
{( B4 n2 f3 R" j8 Z& f
} Y) s$ F2 ?3 h7 F1 s7 a1 j5 z
}. G/ D* r7 f# @/ v& t+ K
//-----------------------------------------------------------------------------1 y7 J& x5 U/ Q- ]1 d* C& }
void CM_Key_scan()& B8 ?+ Q, L( `) j/ x" L
{//1ms 调用一次 刷新键值
unsigned char temp;
key_value=0;//键值清0
//key_time_sta1=TIM2->CNTRH;
//key_time_sta1<<=8;
key_time_sta1=TIM2->CNTRL;
KEY1_O_0;//准备充电 先放光
KEY_SH;/ ]! F: z* i3 c. }" W H7 Y4 T. f
KEY1_I;//高阻! ]* m2 s- f1 ^4 L. R& _5 B
while(!KEY1_R);& G$ e- Q9 ]* t* T( X( d
5 g2 j) } o! C% C1 s1 { g
KEY1_O_1;//准备放电 先充满. z* Z/ [/ m% f$ `/ b
KEY1_I;//高阻9 A! i6 U; l _6 u4 {
KEY_SL;& U) f" W) A- u9 b
while(KEY1_R);
//temp=TIM2->CNTRH;7 x3 H' U2 O h; E/ D
//temp<<=8;
temp=TIM2->CNTRL;
key_time1=temp-key_time_sta1;//单位是us% d. ?8 Q8 [4 i% ]" J( p4 j5 k- p
0 ^6 Z- C% c) \; F6 {
if(key_time1>(key_CH1+GT_GATE)); Q' b& ?( c5 x0 ]1 y. i y
{//溢出阀值
if(key_filter1<8)key_filter1++;6 j* B/ s- I6 i. @9 ~% I# W- E
else
{//连续8次才有效
key_delay1=200;//0.2s a6 I, P" M& O) J5 r, G- x
//if(key_delay1==0)key_CH1-=GT_GATE;
key_CH1-=(key_CH1>>4);// 15/16+ a1 H# m" A6 k8 u
key_CH1+=(key_time1>>4);
}0 a% m: j1 a9 s3 B. Y* R
}
else
{//未溢出情况下累计基准2 D, d- \7 X2 u' {& U8 M% A
key_filter1=0;
2 z/ G4 [. _$ s8 S$ L
key_CH1-=(key_CH1>>4);// 15/16
key_CH1+=(key_time1>>4);
}
6 z( P, V+ [6 V' k) P m
if(key_delay1): ~& O0 k: W @: N [; I4 J4 L
{//在key_delay1不为0期间 K1保持按下状态$ w' v- H5 b; M+ k5 m: W
key_delay1--;, v4 \: y$ n9 R
SET_K1;' x* `/ k# V' c2 Y* F. ]
}6 h' w- P H) D+ z
, U9 g: b! S; n9 q9 L1 v0 w6 \
key_i++;
if(key_i>=64)key_i=0;
key_buf[key_i]=key_time1;! o; ^9 Z% Q" I) J- Z! O
//key_CH1-=(key_CH1>>4);// 15/16
//key_CH1+=(key_time>>4);
& m# S5 p# L, H
temp=key_value;% k8 P; ]( q5 F3 A$ J1 o! u0 g
key_value=key_value&(key_value^key_shadow);
key_shadow=temp;
}3 r* e1 p( M# h- o c, a# }/ m
& n4 P$ A# _8 ~' S" T* \, S