- 打卡等级:初来乍到
- 打卡总天数:6
- 最近打卡:2025-04-12 10:34:29
中级会员
- 积分
- 213
|
我移植了触摸按键驱动程序,现在编译可以通过,但仿真时进入不了触摸按键的中断服务函数,请大家指点
//普通IO口控制数码管
/*******************接口说明*********************
P2.0~P2.7: 接SEG0~SEG7
P3.4~P3.7: 接COM0~COM3
P1.0-->TK0, P1.1-->TK1, P5.4-->TK2, P1.3-->TK3
************************************************/
#define MAIN_Fosc 1200000L //定义主时钟
#include "STC8Hxxx.h"
u16 xdata TK_cnt[4]; // 键计数值
u16 xdata TK_zero[4]; // 0点读数
u16 KeyState; //键状态
u8 KeyCode; //键码 1~16
bit B_TK_Lowpass; //允许低通
bit B_ReadKeyOk; //标志已转换完成16个键
u8 TrigLimit; //触发转换限时
u8 KeyValue; //显示参数的键号, 0~15
u8 read_cnt;
u8 isr_index;
u16 code T_KeyState[16] = {0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
// u16 code T_KeyPress[16] = {400,300,200,200, 400,300,200,200, 400,300,200,200, 400,300,200,200}; //读数无平均, 这个值是各键触摸后的变化值, 由于分布电容不同, 所以各键读数变化量不同
u16 code T_KeyPress[16] = {200,150,100,100, 200,150,100,100, 200,150,100,100, 200,150,100,100}; //读数有平均, 这个值是各键触摸后的变化值, 由于分布电容不同, 所以各键读数变化量不同
//---------------------------------------------------------------------------------------------
// 0 1 2 3 4 5 6 7 8 9
u8 FontCode[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //字形码
// P3.4 P3.5 P3.6 P3.7
u8 Tab[] = {0x10,0x20,0x40,0x80}; //位码
u8 Dispbuf[4]; //显示缓存区
u8 Num = 0; //显示位数计数器
//---------------------------------------------------------------------------------------------
/****************** 检测 计算键码 **************************************/
u8 CheckKey(u16 j)
{
u8 i;
if(j == 0) return 0; //无键按下
for(i=0; i<16; i++)
{
if(j & 0x0001)
break;
j >>= 1;
}
return (i+1); //键码1~16
}
void AUXR_ISR(void) interrupt 13
{
u8 j;
switch(isr_index)
{
case 32: //0103H ²¨Ðη¢ÉúÆ÷5 ÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 33: //010BH ²¨Ðη¢ÉúÆ÷Òì³£2 ÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 34: //0113H ²¨Ðη¢ÉúÆ÷Òì³£4 ÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 35: //011BH ´¥Ãþ°´¼ü ÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
j = TSSTA2;
if(j & 0x40) //Êý¾ÝÒç³ö, ´íÎó´¦Àí(ÂÔ)
{
TSSTA2 |= 0x40; //д1ÇåÁã
}
if(j & 0x80) //ɨÃèÍê³É
{
j &= 0x0f;
TSSTA2 |= 0x80; //д1ÇåÁã
if(!B_TK_Lowpass) TK_cnt[j] = TSDAT/4; //±£´æÄ³¸öͨµÀµÄ¶ÁÊý ÎÞµÍͨÂ˲¨
else TK_cnt[j] = ((TK_cnt[j] * 3)>>2) + TSDAT/16; //±£´æÄ³¸öͨµÀµÄ¶ÁÊý µÍͨÂ˲¨
if(j == 15) B_ReadKeyOk = 1; //¶ÁÍêÒ»´ÎÑ»·
}
break;
case 36: //0123H RTC ÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 37: //012BH P0¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 38: //0133H P1¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 39: //013BH P2¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 40: //0143H P3¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 41: //014BH P4¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 42: //0153H P5¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 43: //015BH P6¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 44: //0163H P7¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 45: //016BH P8¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
case 46: //0173H P9¿ÚÖжÏÈë¿Ú
//Óû§Öжϴ¦Àí´úÂë
break;
default:
break;
}
}
void TM0_Isr() interrupt 1
{
// P14 = !P14; //????
P3 = P3&0x0f;
P3 = P3|Tab[Num]; //高位按位数置1 低4位不变
P2 = FontCode[Dispbuf[Num]];
Num++;
if(Num>3)
Num = 0;
}
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i) ;
}
while(--ms);
}
void main()
{
u8 i;
u16 j;
P_SW2 |= 0x80; //允许访问XSFR(扩展特殊功能寄存器)
P0M0 = 0x00; //准双向口,传统8051模式
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
// P2M0 = 0x00;
// P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P2n_push_pull(0xff); //P2口数码管段码设置为推挽输出
P3n_push_pull(0xf0); //位码(P3.4~P3.7)线设置为推挽输出
P1n_pure_input(0x0f); //Touch Key设置为高阻
P5n_pure_input(0x10); //P5.4设置为高阻
P2DR = 0x00; //段码线设置为强电流驱动 0 强电流驱动
P3DR = 0x0f; //位码线设置为强电流驱动
TSCHEN1 = 0x0f; //TK0~TK3 按键扫描通道
TSCFG1 = (7<<4) + 6; //开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
TSCFG2 = 1; //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4) 1(1/2) 2(5/8) 3(3/4)
TSRT = 0x00; //没有LED分时扫描
IE2 |= 0x80; //允许触摸按键中断
EA = 1;
delay_ms(50);
B_TK_Lowpass = 1; //允许低通滤波
for(read_cnt=0; read_cnt<40; read_cnt++) //读40次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均, 读数大约为无平均的一半
TSCTRL = (1<<7) + (1<<6) +1; //开始扫描, 2次平均, 读数大约为无平均的一半
// TSCTRL = (1<<7) + (1<<6); //开始扫描, 只转换1次, 无平均
B_ReadKeyOk = 0;
for(i=0; i<100; i++)
{
if(B_ReadKeyOk) break;
delay_ms(1);
}
}
for(i=0; i<4; i++)
TK_zero = TK_cnt; //保存0点
B_TK_Lowpass = 1; //允许低通
KeyState = 0;
read_cnt = 0;
B_ReadKeyOk = 0;
KeyValue = 10;
KeyCode = 0;
//-----------------------------------------------------------------------------------
TMOD = 0x00; //16位自动重载模式 受TR0控制 对内部震荡器计数
TL0 = 0x66; //65536-11.0592M/12/1000
TH0 = 0xfc;
TR0 = 1; //启动定时器
ET0 = 1; //使能定时器0中断
// EA = 1;
//P3 = P3&0x0f; //P3.4~P3.7高4位清0 低4位不变
Dispbuf[0] = 3;
Dispbuf[1] = 4;
Dispbuf[2] = 8;
Dispbuf[3] = 9;
while (1)
{
delay_ms(1);
if(++TrigLimit >= 100) //触发转换
{
TrigLimit = 0;
// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均, 读数大约为无平均的一半
TSCTRL = (1<<7) + (1<<6) +1; //开始扫描, 2次平均, 读数大约为无平均的一半
// TSCTRL = (1<<7) + (1<<6); //开始扫描, 只转换1次, 无平均
}
if(B_ReadKeyOk) // 16个键都转换完毕
{
B_ReadKeyOk = 0;
TrigLimit = 100;
// ShowValue(KeyValue); //显示读数
j = KeyState; //读入上一次键状态
for(i=0; i<4; i++)
{
if(TK_zero > TK_cnt) //计算与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
{
KeyState &= ~T_KeyState;
if((TK_cnt - TK_zero) > 100)
TK_zero += 50; //差别很大, 则快速回0点
else
TK_zero += 10; //差别不大, 则慢速回0点
}
}
j = (j ^ KeyState) & KeyState; //检测键是否按下
if(j != 0)
{
KeyCode = CheckKey(j); //计算键码 1~16
}
}
}
}
下面的isr.asm文件加入到工程中了
EXTRN DATA (isr_index)
CSEG AT 0103H ;32ºÅ ²¨Ðη¢ÉúÆ÷5 ÖжÏÈë¿Ú
MOV isr_index, #32 ;±ê¼ÇÖжϺÅ32
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 010BH ;33ºÅ ²¨Ðη¢ÉúÆ÷Òì³£2 ÖжÏÈë¿Ú
MOV isr_index, #33 ;±ê¼ÇÖжϺÅ33
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0113H ;34ºÅ ²¨Ðη¢ÉúÆ÷Òì³£4 ÖжÏÈë¿Ú
MOV isr_index, #34 ;±ê¼ÇÖжϺÅ34
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 011BH ;35ºÅ ´¥Ãþ°´¼ü ÖжÏÈë¿Ú
MOV isr_index, #35 ;±ê¼ÇÖжϺÅ35
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0123H ;36ºÅ RTC ÖжÏÈë¿Ú
MOV isr_index, #36 ;±ê¼ÇÖжϺÅ36
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 012BH ;37ºÅ P0¿ÚÖжÏÈë¿Ú
MOV isr_index, #37 ;±ê¼ÇÖжϺÅ37
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0133H ;38ºÅ P1¿ÚÖжÏÈë¿Ú
MOV isr_index, #38 ;±ê¼ÇÖжϺÅ38
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 013BH ;39ºÅ P2¿ÚÖжÏÈë¿Ú
MOV isr_index, #39 ;±ê¼ÇÖжϺÅ39
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0143H ;40ºÅ P3¿ÚÖжÏÈë¿Ú
MOV isr_index, #40 ;±ê¼ÇÖжϺÅ40
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 014BH ;41ºÅ P4¿ÚÖжÏÈë¿Ú
MOV isr_index, #41 ;±ê¼ÇÖжϺÅ41
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0153H ;42ºÅ P5¿ÚÖжÏÈë¿Ú
MOV isr_index, #42 ;±ê¼ÇÖжϺÅ42
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 015BH ;43ºÅ P6¿ÚÖжÏÈë¿Ú
MOV isr_index, #43 ;±ê¼ÇÖжϺÅ43
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0163H ;44ºÅ P7¿ÚÖжÏÈë¿Ú
MOV isr_index, #44 ;±ê¼ÇÖжϺÅ44
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 016BH ;45ºÅ P8¿ÚÖжÏÈë¿Ú
MOV isr_index, #45 ;±ê¼ÇÖжϺÅ45
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
CSEG AT 0173H ;46ºÅ P9¿ÚÖжÏÈë¿Ú
MOV isr_index, #46 ;±ê¼ÇÖжϺÅ46
LJMP 006BH ;Ìø×ªµ½ÖжϺÅ13µÄÏòÁ¿
END
|
|