- 打卡等级:偶尔看看I
- 打卡总天数:14
- 最近打卡:2024-12-07 20:13:36
注册会员
- 积分
- 104
|
发表于 2024-5-13 16:58:15
|
显示全部楼层
你好,大师。红色是我修改的地方,其他未作修改。现在使用那个按键测试软件获取不了任何信息,不反馈。麻烦您帮我检查下到底是哪里的问题。
#define MAIN_Fosc 24000000L //定义主时钟 串口波特率 300 ~ 4800
#include "stc8hxxx.h"
#include "intrins.h"
/************* 本地常量声明 **************/
sbit P_RUN_LED = P3^6; // 测试指示LED
sbit P_K0_LED = P2^5; // 按键指示LED
sbit P_K1_LED = P0^7;
sbit P_K2_LED = P4^1;
sbit P_K3_LED = P2^1;
sbit P_K4_LED = P3^7;
sbit P_K5_LED = P4^6;
sbit P_K6_LED = P2^4;
sbit P_K7_LED = P0^5;
sbit P_K8_LED = P4^2;
sbit P_K9_LED = P4^3;
sbit P_K10_LED = P2^3;
sbit P_K11_LED = P4^5;
sbit P_K12_LED = P2^0;
sbit P_K13_LED = P2^7;
sbit P_K14_LED = P2^6;
sbit P_K15_LED = P0^6;
/************* 本地变量声明 **************/
u16 xdata TK_cnt[16]; // 按键计数值, 16位
u16 xdata TK_zero[16]; // 按键0点值, 16位
u16 KeyState; // 按键状态, 每个bit对应一个键, 1为按下, 0为释放
u8 read_cnt; // 读次数
bit B_TK_Lowpass; // 低通允许, 1允许, 0禁止
u8 cmd; //串口命令
bit B_TX1_Busy; // 串口发送忙标志
/************* 本地函数声明 **************/
void DisplayRTC(void);
void delay_ms(u8 ms);
void UART1_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4
void UART1_PrintString(u8 *puts);
void UART1_TxByte(u8 dat);
void ReturnValue(u8 channel, u16 value);
/**************** 外部函数声明和外部变量声明 *****************/
// K0 K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14 K15
u16 code T_KeyPress[16]={ 1300, 2000, 900, 800, 900, 1000, 1100, 1400, 1000, 1200, 900, 1200, 750, 900, 1300, 1800}; //触摸后的变化值
u16 code T_KeyState[16]={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000}; //16个键对应的状态, 0为未触摸,1为触摸
/********************* 主函数回调函数 *************************/
void main(void)
{
u8 i;
u16 j;
P3M0 &= ~0x03;
P3M1 &= ~0x03;
P_K0_LED = 0; P_K4_LED = 0; P_K8_LED = 0; P_K12_LED = 0; //熄灭所有LED
P_K1_LED = 0; P_K5_LED = 0; P_K9_LED = 0; P_K13_LED = 0;
P_K2_LED = 0; P_K6_LED = 0; P_K10_LED = 0; P_K14_LED = 0;
P_K3_LED = 0; P_K7_LED = 0; P_K11_LED = 0; P_K15_LED = 0;
P0n_push_pull(0xe0); //设置所有驱动LED的IO为推挽输出
P2n_push_pull(0xff);
P4n_push_pull(0x6e);
//P3n_push_pull(0x40); //P3.6设置为推挽输出
P1n_pure_input(0xff); //设置所有触摸键的O为高阻
P5n_pure_input(0x0f);
P0n_pure_input(0x0f);
P_SW2 |= 0x80; //允许访问扩展寄存器xsfr
EA = 1;
UART1_config(115200UL, 1, 0); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4
UART1_PrintString("STC8H系列触摸按键测试程序!\r\n");
TSCHEN1 = 0x10; //TK04
//TSCHEN2 = 0xff; //TK8~TK15
TSCFG1 = (7<<4) + 6; //B6~B4:开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), B2~B0:放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最好大于等于3(1000)
TSCFG2 = 1; //B1~B0:配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4) 1(1/2) 2(5/8) 3(3/4)
// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, B7: TSGO, B6: SINGLE, B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
TSRT = 0x00; //没有LED分时扫描
IE2 |= 0x80; //允许触摸按键中断
delay_ms(50); //延时一下
B_TK_Lowpass = 0; //禁止低通滤波
for(read_cnt=0; read_cnt<10; read_cnt++) //扫描10次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均
TSCTRL = (1<<7) + (1<<6); //开始扫描, 无平均
delay_ms(50); //延时一下, 等待扫描完成
}
for(i=0; i<16; i++) TK_zero = TK_cnt; //保存0点
B_TK_Lowpass = 1; //允许低通滤波
KeyState = 0;
read_cnt = 0;
while (1)
{
// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均
// TSCTRL = (1<<7) + (1<<6) +1; //开始扫描, 2次平均
TSCTRL = (1<<7) + (1<<6); //开始扫描, 无平均
delay_ms(20); //延时一下, 根据实际扫描速度调整
if(++read_cnt >= 3)
{
read_cnt = 0;
j = KeyState;
for(i=0; i<16; i++)
{
// if((TK_zero >= TK_cnt) && ((TK_zero - TK_cnt) >= 300)) ShowValue(i,TK_zero - TK_cnt); //6ms 有键按下则显示差值
// else ShowValue(i,TK_cnt); //无键按下则显示读数
if(TK_zero > TK_cnt) //0点值比当前值大, 则键按下, 缓慢0点跟踪
{
TK_zero--; //缓慢0点跟随
if((TK_zero - TK_cnt) >= T_KeyPress/2) KeyState |= T_KeyState; //变化值大于最大变化值的1/2, 则判断键已触摸
else if((TK_zero - TK_cnt) <= T_KeyPress/3) KeyState &= ~T_KeyState; //变化值小于最大变化值的1/3, 则判断键已释放
}
else //0点值比当前值小, 则键释放
{
KeyState &= ~T_KeyState; //键状态: 释放
// TK_zero = TK_cnt; //快速0点回归(比如按着键上电)
// TK_zero += 50; //比较快速0点回归(比如按着键上电)
if((TK_cnt - TK_zero) > 100) TK_zero += 100; //差别很大, 则快速回0点
else TK_zero += 10; //差别不大, 则慢速回0点
}
}
j = (j ^ KeyState) & KeyState; //LED指示处理
B = (u8)j;
if(B0) P_K0_LED = ~P_K0_LED;
if(B1) P_K1_LED = ~P_K1_LED;
if(B2) P_K2_LED = ~P_K2_LED;
if(B3) P_K3_LED = ~P_K3_LED;
if(B4) P_K4_LED = ~P_K4_LED;
if(B5) P_K5_LED = ~P_K5_LED;
if(B6) P_K6_LED = ~P_K6_LED;
if(B7) P_K7_LED = ~P_K7_LED;
B = (u8)(j >> 8);
if(B0) P_K8_LED = ~P_K8_LED;
if(B1) P_K9_LED = ~P_K9_LED;
if(B2) P_K10_LED = ~P_K10_LED;
if(B3) P_K11_LED = ~P_K11_LED;
if(B4) P_K12_LED = ~P_K12_LED;
if(B5) P_K13_LED = ~P_K13_LED;
if(B6) P_K14_LED = ~P_K14_LED;
if(B7) P_K15_LED = ~P_K15_LED;
}
if(cmd != 0)
{
if((cmd >= '0') && (cmd <= '9')) ReturnValue(cmd-'0', TK_cnt[cmd-'0']);
if((cmd >= 'a') && (cmd <= 'z')) cmd = cmd -'a'+'A'; //小写转大写
if((cmd >= 'A') && (cmd <= 'F')) ReturnValue(cmd-'A'+10, TK_cnt[cmd-'A'+10]);
cmd = 0;
}
}
}
/**********************************************/
//========================================================================
// 函数: void ReturnValue(u8 channel, u16 value)
// 描述: 返回按键值函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-12-23
// 备注:
//========================================================================
void ReturnValue(u8 channel, u16 value)
{
// value = value / 100; //缩小为1/100, 数值小一些比较容易观察
UART1_TxByte('K');
UART1_TxByte(channel/10+'0');
UART1_TxByte(channel%10+'0');
UART1_TxByte('=');
UART1_TxByte(value / 10000 + '0');
UART1_TxByte((value % 10000)/1000 + '0');
UART1_TxByte((value % 1000)/100 + '0');
UART1_TxByte((value % 100)/10 + '0');
UART1_TxByte(value % 10 + '0');
UART1_TxByte(0x0d);
UART1_TxByte(0x0a);
}
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i) ;
}while(--ms);
}
/**********************************************/
u8 isr_index;
//========================================================================
// 函数: void TKSU_ISR(void) interrupt TKSU_VECTOR
// 描述: 触摸按键中断服务函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2023-10-11
// 备注:
void TKSU_ISR(void) interrupt TKSU_VECTOR
{
u8 j;
j = TSSTA2;
if(j & 0x40) //数据溢出, 错误处理(略)
{
TSSTA2 |= 0x40; //写1清零
}
if(j & 0x80) //扫描完成
{
P_RUN_LED = 1; //整个处理时间 1.1us @24MHz
j &= 0x0f;
TSSTA2 |= 0x80; //写1清零
if(!B_TK_Lowpass) TK_cnt[j] = TSDAT; //保存某个通道的读数 1.1us @24MHz
// else TK_cnt[j] = (u16)(((u32)TK_cnt[j] * 3) >> 2) + (TSDAT >> 2); //保存某个通道的读数 低通滤波 8us @24MHz
// else TK_cnt[j] = (TK_cnt[j] >> 2) * 3 + (TSDAT >> 2); //保存某个通道的读数 低通滤波 4.6us @24MHz, 低通a=0.25, 未按键读数20000, 按键读数21600, 则要11个次采样点(100Hz采样110ms)读数才到21500.
else TK_cnt[j] = (TK_cnt[j] >> 1) + (TSDAT >> 1); //保存某个通道的读数 1/2低通滤波 4.6us @24MHz, 低通a=0.25, 未按键读数20000, 按键读数21600, 则要11个次采样点(100Hz采样110ms)读数才到21500.
P_RUN_LED = 0;
}
}
//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void SetTimer2Baudraye(u16 dat) // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
AUXR &= ~(1<<4); //Timer stop
AUXR &= ~(1<<3); //Timer2 set As Timer
AUXR |= (1<<2); //Timer2 set as 1T mode
TH2 = (u8)(dat >> 8);
TL2 = (u8)dat;
IE2 &= ~(1<<2); //禁止中断
AUXR |= (1<<4); //Timer run enable
}
//========================================================================
// 函数: void UART1_config(u32 brt, u8 timer, u8 io)
// 描述: UART1初始化函数。
// 参数: brt: 通信波特率.
// timer: 波特率使用的定时器, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率.
// io: 串口1切换到的IO, io=1: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_config(u32 brt, u8 timer, u8 io) // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =3: 切换到P4.3 P4.4
{
brt = 65536UL - (MAIN_Fosc / 4) / brt;
if(timer == 2) //波特率使用定时器2
{
AUXR |= 0x01; //S1 BRT Use Timer2;
SetTimer2Baudraye((u16)brt);
}
else //波特率使用定时器1
{
TR1 = 0;
AUXR &= ~0x01; //S1 BRT Use Timer1;
AUXR |= (1<<6); //Timer1 set as 1T mode
TMOD &= ~(1<<6); //Timer1 set As Timer
TMOD &= ~0x30; //Timer1_16bitAutoReload;
TH1 = (u8)(brt >> 8);
TL1 = (u8)brt;
ET1 = 0; // 禁止Timer1中断
INT_CLKO &= ~0x02; // Timer1不输出高速时钟
TR1 = 1; // 运行Timer1
}
if(io == 1) {S1_USE_P36P37(); P3n_standard(0xc0);} //切换到 P3.6 P3.7
else if(io == 2) {S1_USE_P16P17(); P1n_standard(0xc0);} //切换到 P1.6 P1.7
else if(io == 3) {S1_USE_P43P44(); P4n_standard(0x18);} //切换到 P4.3 P4.4
else {S1_USE_P30P31(); P3n_standard(0x03);} //切换到 P3.0 P3.1
SCON = (SCON & 0x3f) | (1<<6); // 8位数据, 1位起始位, 1位停止位, 无校验
// PS = 1; //高优先级中断
ES = 1; //允许中断
REN = 1; //允许接收
}
//========================================================================
// 函数: void UART1_TxByte(u8 dat)
// 描述: 串口1发送一个字节函数
// 参数: dat: 要发送的单字节数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_TxByte(u8 dat)
{
B_TX1_Busy = 1; //标志发送忙
SBUF = dat; //发一个字节
while(B_TX1_Busy); //等待发送完成
}
//========================================================================
// 函数: void UART1_PrintString(u8 *puts)
// 描述: 串口1字符串打印函数
// 参数: puts: 字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_PrintString(u8 *puts)
{
for (; *puts != 0; puts++)
{
UART1_TxByte(*puts);
}
}
//========================================================================
// 函数: void UART1_ISR (void) interrupt UART1_VECTOR
// 描述: 串口1中断函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_ISR (void) interrupt UART1_VECTOR
{
if(RI)
{
RI = 0;
cmd = SBUF;
}
if(TI)
{
TI = 0;
B_TX1_Busy = 0;
}
}
|
|