使用STC15W408AS的ADC做的电容感应触摸键
#include #include #define MAIN_Fosc 24000000UL //定义主时钟 typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; #define Timer0_Reload (65536UL -(MAIN_Fosc / 600000)) //Timer 0 重装值, 对应300KHZ sfr P1ASF = 0x9D; //只写,模拟输入选择 sfr ADC_CONTR = 0xBC; //带AD系列 sfr ADC_RES = 0xBD; //带AD系列 sfr ADC_RESL = 0xBE; //带AD系列 sfr AUXR = 0x8E; sfr AUXR2 = 0x8F; sfr P1M1 = 0x91; // sfr P1M0 = 0x92; // sfr P0M1 = 0x93; // sfr P0M0 = 0x94; // sfr P2M1 = 0x95; // sfr P2M0 = 0x96; // sfr P3M1 = 0xB1; // sfr P3M0 = 0xB2; // sfr P4M1 = 0xB3; // sfr P4M0 = 0xB4; // sfr P5M1 = 0xC9; // sfr P5M0 = 0xCA; // sfr P6M1 = 0xCB; // sfr P6M0 = 0xCC; // sfr P7M1 = 0xE1; sfr P7M0 = 0xE2; #define TOUCH_CHANNEL 8 //ADC通道数 #define ADC_90T (3<<5) //ADC时间 90T #define ADC_180T (2<<5) //ADC时间 180T #define ADC_360T (1<<5) //ADC时间 360T #define ADC_540T 0 //ADC时间 540T #define ADC_FLAG (1<<4) //软件清0 #define ADC_START (1<<3) //自动清0 sbit P_LED7 = P2^7; sbit P_LED6 = P2^6; sbit P_LED5 = P2^5; sbit P_LED4 = P2^4; sbit P_LED3 = P2^3; sbit P_LED2 = P2^2; sbit P_LED1 = P2^1; sbit P_LED0 = P2^0; u16 idata adc[TOUCH_CHANNEL]; //当前ADC值 u16 idata adc_prev[TOUCH_CHANNEL]; //上一个ADC值 u16 idata TouchZero[TOUCH_CHANNEL]; //0点ADC值 u8 idata TouchZeroCnt[TOUCH_CHANNEL]; //0点自动跟踪计数 u8 cnt_250ms; void delay_ms(u8 ms); void ADC_init(void); u16 Get_ADC10bitResult(u8 channel); void AutoZero(void); u8 check_adc(u8 index); void ShowLED(void); void main(void) { u8 i; P0M1 = 0; P0M0 = 0; //设置为准双向口 P1M1 = 0; P1M0 = 0; //设置为准双向口 P2M1 = 0; P2M0 = 0; //设置为准双向口 P3M1 = 0; P3M0 = 0; //设置为准双向口 P4M1 = 0; P4M0 = 0; //设置为准双向口 P5M1 = 0; P5M0 = 0; //设置为准双向口 P6M1 = 0; P6M0 = 0; //设置为准双向口 P7M1 = 0; P7M0 = 0; //设置为准双向口 delay_ms(50); ET0 = 0; //初始化Timer0输出一个300KHZ时钟 TR0 = 0; AUXR |= 0x80; //Timer0 set as 1T mode AUXR2 |= 0x01; //允许输出时钟 TMOD = 0; //Timer0 set as Timer, 16 bits Auto Reload. TH0 = (u8)(Timer0_Reload >> 8); TL0 = (u8)Timer0_Reload; TR0 = 1; ADC_init(); //ADC初始化 delay_ms(50); //延时50ms for(i=0; i adc_prev[i] = 1023; TouchZero[i] = 1023; TouchZeroCnt[i] = 0; } cnt_250ms = 0; while (1) { delay_ms(50); //每隔50ms处理一次按键 ShowLED(); if(++cnt_250ms >= 5) { cnt_250ms = 0; AutoZero(); //每隔250ms处理一次0点自动跟踪 } } } void delay_ms(u8 ms) { unsigned int i; do{ i = MAIN_Fosc / 13000; while(--i) ; }while(--ms); } void ADC_init(void) { P1ASF = 0xff; //8路ADC ADC_CONTR = 0x80; //允许ADC } u16 Get_ADC10bitResult(u8 channel) //channel = 0~7 { ADC_RES = 0; ADC_RESL = 0; ADC_CONTR = 0x80 | ADC_90T | ADC_START | channel; //触发ADC _nop_(); _nop_(); _nop_(); _nop_(); while((ADC_CONTR & ADC_FLAG) == 0) ; //等待ADC转换结束 ADC_CONTR = 0x80; //清除标志 return(((u16)ADC_RES << 2) | ((u16)ADC_RESL & 3)); //返回ADC结果 } void AutoZero(void) //250ms调用一次 这是使用相邻2个采样的差的绝对值之和来检测。 { u8 i; u16 j,k; for(i=0; i j = adc[i]; k = j - adc_prev[i]; //减前一个读数 F0 = 0; //按下 if(k & 0x8000) F0 = 1, k = 0 - k; //释放 求出两次采样的差值 if(k >= 20) //变化比较大 { TouchZeroCnt[i] = 0; //如果变化比较大,则清0计数器 if(F0) TouchZero[i] = j; //如果是释放,并且变化比较大,则直接替代 } else //变化比较小,则蠕动,自动0点跟踪 { if(++TouchZeroCnt[i] >= 20) //连续检测到小变化20次/4 = 5秒. { TouchZeroCnt[i] = 0; TouchZero[i] = adc_prev[i]; //变化缓慢的值作为0点 } } adc_prev[i] = j; //保存这一次的采样值 } } u8 check_adc(u8 index) //判断键按下或释放,有回差控制 { u16 delta; adc[index] = 1023 - Get_ADC10bitResult(index); //获取ADC值, 转成按下键, ADC值增加 if(adc[index] < TouchZero[index]) return 0; //比0点还小的值,则认为是键释放 delta = adc[index] - TouchZero[index]; if(delta >= 40) return 1; //键按下 if(delta <= 20) return 0; //键释放 return 2; //保持原状态 } void ShowLED(void) { u8 i; i = check_adc(0); if(i == 0) P_LED0 = 1; //指示灯灭 if(i == 1) P_LED0 = 0; //指示灯亮 i = check_adc(1); if(i == 0) P_LED1 = 1; //指示灯灭 if(i == 1) P_LED1 = 0; //指示灯亮 i = check_adc(2); if(i == 0) P_LED2 = 1; //指示灯灭 if(i == 1) P_LED2 = 0; //指示灯亮 i = check_adc(3); if(i == 0) P_LED3 = 1; //指示灯灭 if(i == 1) P_LED3 = 0; //指示灯亮 i = check_adc(4); if(i == 0) P_LED4 = 1; //指示灯灭 if(i == 1) P_LED4 = 0; //指示灯亮 i = check_adc(5); if(i == 0) P_LED5 = 1; //指示灯灭 if(i == 1) P_LED5 = 0; //指示灯亮 i = check_adc(6); if(i == 0) P_LED6 = 1; //指示灯灭 if(i == 1) P_LED6 = 0; //指示灯亮 i = check_adc(7); if(i == 0) P_LED7 = 1; //指示灯灭 if(i == 1) P_LED7 = 0; //指示灯亮 }
上一篇:用AT89C51单片机显示倒计时程序
下一篇:用汇编语言做一个看门狗测试
推荐阅读最新更新时间:2024-11-10 10:22
推荐帖子
- 【讨论】JTAG能够只接5根线就用吗?请求回答!!!
- 【讨论】JTAG能够只接5根线就用吗?请求回答!!!是。还应该共地TDO/TDI,TDI,TMS,TCK,REST这五根吗?再加地Reset可以不接,外接个复位按钮,我一直这样用。tocool430:真的吗?我可一直用TDO/TDI,TDI,TMS,TCK,REST.外加共地线,,请问rest在JTAG中骑什么作用呢??只要工作正常都一样的,TI的隔离JTAG就只用了这5根连线。这个得到了认可吗?我的意思是定义了函数putchar后,就可以直接在程序里使用Print
- hhyyzzcool 微控制器 MCU
- 你最省钱的设计,赢LPC1114开发板!(已颁奖)
- 感谢chenzhufly贡献了一块LPC1114开发板,由于他老人家感冒在身,所以由我越权来发这个板子。板子只有一块,感兴趣的朋友估计不止一个,所以想了个比较有意思的话题,希望大家多多参与。话题:谈谈你做过的最省钱的设计?——越省钱越好参与方式:跟帖结束日期:06月30日7月1日的时候,我们将确定获得LPC1114板子的人选。板子图赏(这是上次做活动的图,LPC1114就是其中一个,故图片仅供参考)lyzhangxia
- soso NXP MCU
- 【FireBeetle 2 ESP32 C6开发板】8、使用触屏 + espnow控制led灯
- ###前言lvgl已经出到9.x版本了,github上的lv_port_esp32还是7.x版本,由于我自己有Linux和esp32两种设备的开发需求,esp32的RAM和Flash也不算小,我打算直接使用9.1版本的lvgl,然后使用lvgl_esp32_drivers仓库,仓库地址是https://github.com/lvgl/lvgl_esp32_drivers.git####远程点灯前面我们已经实现了微雪板子的lvgl按钮和触屏案例,现在使用espnow来实现远程点灯,效果
- walker2048 RF/无线
- 关于GPRS模块的拨号连接问题
- 用windows的拨号连接,可以接通网络,上网也没有问题。拨号设置的是*99***2#如果用AT命令ATD*99***2#,如何连接GPRS网络?AT+CGDCONT=1,IP,CMNETOKATD*99***2#CONNECT~?}#9}}&}}*}}}\'}}(}}%}&~?}#~?}#~?}#~?}#~?}#~?}#~?}#~?}#~?}#NOCARRIER不知道这是什么原因,请问还需要别的什么吗?关于GPRS模块的拨号连接问题对了,
- yes2250 嵌入式系统
- 在WINCE60里面把CELLCORE组件加进了NK,怎么测试这块是不是可以正常工作?有没简单的测试AP可用?怎么测试RIL组件绑定了物理通信的串口?
- 在WINCE60里面把CELLCORE组件加进了NK,怎么测试这块是不是可以正常工作?有没简单的测试AP可用?怎么测试RIL组件绑定了物理通信的串口?在WINCE60里面把CELLCORE组件加进了NK,怎么测试这块是不是可以正常工作?有没简单的测试AP可用?怎么测试RIL组件绑定了物理通信的串口?想用VS2005写个简单的AP来测试RIL功能,执行RIL_Initialize()函数老是不成功,错误码又显示调用成功了,搞不懂啊。还要调整什么地方???Ril.lib库的问题,找一个旧一点
- ali50m WindowsCE
- [STM32H7R/S]测评 ⑥使用CUBE AI移植模型至开发板运行
- 在开始自己训练模型并运行到开发板上前,我得先尝试一下把一个现成的模型移植到STM32开发板上,先积累经验。训练好的模型是无法直接在STM32上运行的,我浅薄的理解就是STM32只是一个单片机,他的硬件能力和软件架构无法直接运行AI模型,那么就需要一个工具,把这些复杂的东西转换成C语言的代码,这样STM32单片机就可以运行AI模型里,CUBEAI就是ST为各位开发者准备好的工具。一.安装CUBEAICUBEAI是CUBEMX中的一个软件包,
- 不爱胡萝卜的仓鼠 stm32/stm8
设计资源 培训 开发板 精华推荐
- LT3973EMS 1.21V 降压转换器的典型应用
- LTC1414、14 位、2.2Msps 采样 A/D 转换器的典型应用
- MPC86XADS、XPC8xx 参考板,基于 XPC855T MPU PowerQUICC MPC8xx 处理器
- DC2380A-B,基于 LTC7851EUHH 双路输出、4 相电压模式降压控制器的演示板,7V = VIN = 14V,Vout1 = 1.8V @ 60A,Vout3 = 1.2V @ 60A
- LT3973IDD-5 1.21V 降压转换器的典型应用
- LT4276BIUFD 90W LTPoE++ 电源在正向模式下的典型应用电路,具有 12V、7A 输出
- 使用 Analog Devices 的 LTC2908CTS8-C1 的参考设计
- SI2439AFM18-EVB,带有 UART 接口的 SI2439 ISOmodem 评估板
- 4X4RGBCLICK,基于 MCP1826 LDO 稳压器的评估套件
- LT5506 的典型应用 - 具有 VGA 的 40MHz 至 500MHz 正交解调器