单片机向串口发送键盘指令,串口助手在同一个指令上一直不停的跑 代码如下 哪位大神帮帮忙

#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar key_scan(); uchar key;
void SendOneByte(unsigned char c)

{

SBUF = c;
while(TI==0);

TI = 0;

}
void delay(uint k) //延时程序

{

uint i,j;

for(i=k;i>0;i--)

for(j=110;j>0;j--);

}

void main() //主程序

{ uchar b;

TMOD = 0x20; //定时器T1的工作方式2,8位数据自动重装

SCON = 0x50; //串行口的方式1,8位异步收发,波特率可变。

TH1 = 0xfd; // 装定时器1初值.

TL1 = 0xfd;

PCON = 0x00;

EA = 1; //开总中断

ES = 1; //串行口中断源允许

TR1 = 1; //开定时器1

while(1) //循环开始

{

    b=key_scan();       
    switch(b)
    {
    case 1: SendOneByte('1');  break;
    case 2: SendOneByte('2');  break;
    case 3: SendOneByte('3');  break;
    case 4: SendOneByte('4');  break;
    case 5: SendOneByte('5');  break;
    case 6: SendOneByte('6');  break;
    case 7: SendOneByte('7');  break;
    case 8: SendOneByte('8');  break;
    case 9: SendOneByte('9');  break;
    case 0: SendOneByte('0');  break;
    case 11:SendOneByte('U');  break;
    case 12:SendOneByte('Y');  break;
    case 13:SendOneByte('N');  break;
    case 14:SendOneByte('L');  break;
    case 15:SendOneByte('D');  break;
    case 16:SendOneByte('R');  break;
   default :break;  
    }

}

}

uchar key_scan()
{
uchar cord_h,cord_l,x;//行列值
P1=0xf0; //行线输出全为0
cord_h=P1&0xf0; //读入列线值
if(cord_h!=0xf0) //先检测有无按键按下
{
delay(80); //去抖
if(cord_h!=0xf0)
{
cord_h=P1&0xf0; //读入列线值

P1=cord_h|0x0f; //输出当前列线值
cord_l=P1&0x0f; //读入行线值
x=cord_h+cord_l;//键盘最后组合码值
switch ( x )

{
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0x7e: key=4; break;
case 0xed: key=5; break;
case 0xdd: key=6; break;
case 0xbd: key=7; break;
case 0x7d: key=8; break;
case 0xeb: key=9; break;
case 0xdb: key=0; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
}

}
}

return key;

}

5个回答

我觉你的这个问题的原因是:b的值在上一次按键按下后就是一个固定的值了,比如你按下0xee之后,在按下第二个键之前,b的值就一直都是1,
所以while循环里会一直发送1.所以你需要在没有按键按下的时候,让keyscan()返回一个while的switch中没有的值,也就是执行default。

switch ( x )

{
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0x7e: key=4; break;
case 0xed: key=5; break;
case 0xdd: key=6; break;
case 0xbd: key=7; break;
case 0x7d: key=8; break;
case 0xeb: key=9; break;
case 0xdb: key=0; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
}

在这个switch中加一个default:key=0;break;

switch ( x )

{
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0x7e: key=4; break;
case 0xed: key=5; break;
case 0xdd: key=6; break;
case 0xbd: key=7; break;
case 0x7d: key=8; break;
case 0xeb: key=9; break;
case 0xdb: key=0; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
default:key=0;break;
}

你想要实现的是不是当检测到按键值时 只通过串口发送一次而不是连续发送吗?
思路为: 在串口发送函数前 判定本次按键值是否和上次检测的按键值相同, 如不同则表示有按键按下,发送键盘指令。相同无按键按下,不发送

在main函数外 定义1全局变量

prekeystate = 0; 上次检测按键状态
nowkeystate = 0; 本次检测全局变量

while(1) //循环开始
{
nowkeystate =key_scan(); //读取本次按键值

  if( nowkeystate != prekeystate )    //判定键值是否发生变化
    {
            switch(nowkeystate)                         //变化后 发送变化后的键值  只发送一次
            {   
            ……
            }

            prekeystate  =   nowkeystate;      //更新前次按键值    确保只发送一次 

    }


    希望可以帮助你
thinkflykasite
thinkflykasite 回复thinkflykasite: 说到扫描起码要让按键阵列扫描起来,网上应该有许多例子,这里不多说。不知道你外围电路,自己去检查一下哦,入门的问题。
一年多之前 回复
thinkflykasite
thinkflykasite 回复u013045220: 这个可以归为阵列按键扫描问题,键值其实是一个触发值。所以键值应该在按下的边缘或者弹起的边缘来触发更新,这些变化应该以空键为判断常态。处理好这一点就不存在同键按下不冒键值或者按下一次弹出多次啦。
一年多之前 回复
u013045220
君子筱宁 感谢您的帮助
一年多之前 回复
u013045220
君子筱宁 相同问题 两次按下相同的键 只响应一次 需要按下其他键才能回到原先的键 这样解决的话影响了数值的输入,例如11,这样的话应该怎么解决呢?
一年多之前 回复
HK_JY
灬Change 如果两次按下的键是同一个键呢,嘿嘿嘿
一年多之前 回复

你的key定义成局部变量就可以了,我觉得不需要定义成全局变量。

每次按键按下后把b清零就可以了

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
如何向串口发送指令?
厂家的技术参数提供如下:rnrnCLRrn名称:清屏命令rn格式:ASCII CLRrn 十进制 12rn说明:清除显示屏上的显示内容rnrnrn请问我如何向串口发出此指令?
如何向串口发送组合键指令
串口向下位机如何发送组合键指令,以下代码是发送文本指令的方法,现在有个指令要向下位机发送一个 Ctrl + u 的组合键指令,请高手指点下,该如何操作,谢谢!rn[code=csharp] private void TestCom_DataSend(string cmd) //发送串口指令rn rn if (ComDevice.IsOpen == true)rn rn byte[] SendBytes = null;rn string SendData = cmd;//指令rn //16进制发送rn tryrn rn //剔除所有空格rn SendData = SendData.Replace(" ", "");rn if (SendData.Length % 2 == 1)rn //奇数个字符rn SendData = SendData.Remove(SendData.Length - 1, 1);//去除末位字符rn rn List SendDataList = new List();rn for (int i = 0; i < SendData.Length; i = i + 2)rn rn SendDataList.Add(SendData.Substring(i, 2));rn rn SendBytes = new byte[SendDataList.Count];rn for (int j = 0; j < SendBytes.Length; j++)rn rn SendBytes[j] = (byte)(Convert.ToInt32(SendDataList[j], 16));rn rn rn catchrn rn MessageBox.Show("请输入正确的16进制数据!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);rn rn ComDevice.Write(SendBytes, 0, SendBytes.Length);//发送数据rn rn elsern rn MessageBox.Show("串口未打开,请打开串口后重试", "错误");rn Time_Read.Stop();rn rn [/code]
怎样向串口发送指令????? 急 VB
我不知怎样向地磅发送指令.??? 我们是耀华XK3190-A9地磅称,9针串口,现我们有VB读取数据。我现在不知怎么样向它发送读取毛重、净重的指令。我不会发指令。 rnrnrn下面是资料:(2). 指令方式: rn仪表按上位机所发送的指令,输出相应的数据,上位机每发一次指令,仪表就相应 rn地输出一帧数据。上位机发送指令: rn第X 字节 rn内 容 及 注 解 rn1 rn02(XON) 开始 rn2 rnA~Z 地址编号 rnA~E 命令A:握手 rn命令B:读毛重 rn命令C:读皮重 rn3 rn命令D:读净重 rn4 rn异或校验 高四位 rn5 rn异或校验 低四位 rn6 rn03(X0FF) 结束 rn异或=2⊕3 rn仪表输出内容: rn第X 字节 rn内 容 及 注 解 rn1 rn02(XON) 开始 rn2 rnA~Z 地址编号 rnA~E 命令A:握手 rn命令B:送毛重 rn命令C:送皮重 rn3 rn命令D:送净重 rn4 rn按命令内容输出相应数据 rn: rn按命令内容输出相应数据 rnn-1 rn按命令内容输出相应数据 rnn rn按命令内容输出相应数据 rnn+1 rn异或校验 高四位 rnn+2 rn异或校验 低四位 rnn+3 rn03(X0FF) 结束 rn异或=2⊕3⊕……( n-1 ) ⊕n rn仪表输出时4~n 的内容如下: rn命令A rn无数据 rn每帧由6 组数据组成 rn为毛重,格式: rna: 符号(+或-) rnb: 毛重值 ( 6 位) rn: (自高到低) rng rn命令B rnh: 小数点从右到左( 0~4) rn每帧由14 组数据组成 rn7 rnX K 3 1 9 0 – A 9 rn为皮重,格式: rna: 符号(+或-) rnb: 皮重值 ( 6 位) rn: (自高到低) rng rn命令C rnh: 小数点从右到左( 0~4) rn每帧由14 组数据组成 rn为净重,格式: rna: 符号(+或-) rnb: 净重值 ( 6 位 ) rn: (自高到低) rng rn命令D rnh: 小数点从右到左( 0~4) rn每帧由14 组数据组成 rn注1:异或校验高、低4 位的确定:异或和高、低4 位如果小于、等于9,则加上30h,成为 rnASCII 码数字发送,例如:异或校验高4 位为6,加30h 后,为36h 即ASCII 码的6 发送;异或和高、低4 位如果大于9,则加上37h,成为ASCII 码字母发送,例如:异或校验高4 位为B,加37h 后,为42h 即ASCII 码的B 发送。
单片机指令\C51指令详解
51单片机指令,单片机指令\C51指令详解.txt
单片机指令
单片机的指令资源 单片机编程的参考资料 为单片机的编程提供很好的资料
串口通信(串口助手发送指令控制单片机执行相应操作)
串口通信 (1)刚下载完程序,流水灯 (2)通过串口助手发送“ab01”,数码管显示温度,显示完当前温度后,将温度打印到串口助手上 (3)串口助手发送“ab02”,,蜂鸣器响 (4)执行完后都会回复最初的流水灯
Linux下的串口助手(可以调AT指令)
Linux下的串口助手,自己写的类通用信不好就改为使用的第三方类.可以发AT指令.代码注释也比较多. 1:串口打开格式一般为8N1(8位数据位,无校验位,1位的停止位)无流控制; 2:如果想让数据以16进制显示,请勾选HEX; 3:如果勾选上《回车》功能,那么每次接收到数据就在后面加个回车符; 4:如果想定时发送数据那么请勾选《定时发送》,并输入时间时间; 5:《AT》勾选上后,可以用于发送AT指令,先发送一个AT看是否返回"OK"; 6:在调AT指令时,可以在每次发送的字符后加个其他值,比如说发短信时要在结尾处加Ctrl+Z,那么我们就要选择插入checkBox,然后在框中输入0x1A,然后点发送. 7:对于不同的串口结点名请自己在comment.h头文件里更改; 8:确保本程序对串口结点有读写权根,不然打开串口失败; 9:如有问题请发Email;
VS2013+C#串口助手支持循环发送指令
VS2013+C#,串口助手,支持循环发送指令,自动识别串口
esp8266AT指令详解+(串口+TCP)调试助手
包含esp8266模块的AT指令详解,以及要用到的串口调试助手,TCP调试助手
哪位大拿知道如下指令的含义?
例如0X88是MOV指令;rn1/0X8Brn2/OXFFrn3/OXFFrn不知道上面这三个是什么指令。rnrn如果有类似的查询/对照文档,请给我一个。谢谢了。
串口调试助手发送数据一直不停
# includernrntypedef unsigned int u16; //对数据类型进行声明定义rntypedef unsigned char u8;rnvoid UsartInit()rnrn SCON=0X50;//模式1rn TMOD=0X20;//T1 定时/计数器1 方式2rn PCON=0X80;//SMOD置1 rn TH1=0XF4;rn TL1=0XF4;rn ES=1;rn EA=1;rn TR1=1;rnrnrnvoid main(void)rnrn UsartInit(); //串口初始化rn while(1);rnrnvoid Usart() interrupt 4rnrn u8 receivedata;rnrn receivedata=SBUF;rn RI=0;//清除接收中断标志位rn SBUF=receivedata;rn while(!TI)rn TI=0;//清除发送完成标志位rnrnrn大神些 帮我看看哪里有问题?
各种代码指令各种代码指令各种代码指令
各种代码指令各种代码各种代码指令指令各种代码指令各种代码指令各种代码指令
AT指令调试助手
之前测试通讯模块的AT命令,网上下载的好多串口调试工具什么的用起来都不爽(要么不自动回车要么显示繁琐),最后自己写了一个AT指令测试的程序,也分享给大家把,新编写的AT指令调试工具。 如果有什么意见或建议,请马上提出来,我尽快改进~~ 话说,是不是该加一个AT解析或者查询的...
关于QT怎样向串口发送十六进制指令的问题
各位高手,我现在又一个传感器,需要用向串口发送F0COAE这样的十六进制数据才可以,但不知道在QT下怎样实现,我用的是QT的第三方类,急救!
vim指令键盘图
vim指令键盘图,做桌面背景很合适
Java使用短信猫发信息(向串口发送AT指令)
使用Java发送短信息的方式有两种: 1>使用第三方平台的http请求进行发送,优点是接口简单,使用方便,发送的效率高,多条可以同时发送,缺点是短信平台,三大运营商不提供接口,都是第三方平台,但是第三方平台不稳定,如果倒闭,将意味着这套代码请求的服务器倒闭,则代码失效,需要再找另外的第三方公司; 2>硬件设备,短信猫,比如深圳宏电的H6221GPRS Mode模块,优点是发送稳定,不会出现担心
单片机指令快速记忆 111 条指令
学习单片机,除了搞清单片机内部功能、存储空间分配及 I/O接口外, 还应掌握其指令 系 统。MCS-51共有 111 条指令,现介绍我们总结出的快速记忆 MCS-51指令的方法,供大家参 考。
单片机课件 数据传送指令 算术运算指令
本课件介绍单片机的最基本的指令,和第四章还有第五章的中断时钟。希望大家喜欢啊!看了就知道啦。要不你试试看。呵呵 !MCS-51单片机指令系统包括111条指令,按功能可以划分为以下5类       数据传送指令(29条)    算术运算指令(24条)         逻辑运算指令(24条)      控制转移指令(17条)       位操作指令 (17条)
单片机指令111条附有指令说明。
单片机指令111条,附有指令说明。单片机指令111条,附有指令说明。单片机指令111条,附有指令说明。附有指令说明。
51单片机指令学习 单片机指令学习
51单片机指令学习(常用器件的资料).rar
如何向串口发送82H指令(不是数据)?
小弟有一难题,有个硬件通讯必须发送82H指令,但VB的CHR只发送小于80H的指rn令,有什么好办法,诚心求教。(听说可以分段发,但不知如何作到)
有用的指令代码各种代码指令各种代码指令各种代码指令
好不各种代码指令容易手机的各种代码指令各种代码指令各种代码指令各种代码指令
C#的serialport控件怎么向串口发送AT指令
我有一个金浪modem,想通过AT指令发送传真。我用serialport.write("ATDT001")或者serialport.write("ATDT001\r")发送后一点反应都没有。DataReceived事件也没有响应。rnrn需要一个简单的发送实例代码,接触这个比较少,不太懂AT指令。rn应该怎么在C#中控制串口发送指令并接受状态呢?rn
通过VB向串口发送和接收十六进制指令?
有个需要通过串口 传递数据的 测量仪器!rn通过串口测试软件测试发现,rn若想要读取仪器测量值,必须先向设备 发送8个字节的查询命令,形如“80 03 00 00 00 05 4B 1D ” ,rn才会返回一串21字节的数据,形如 80 03 10 01 00 03 23 00 00 00 00 00 00 00 00 00 00 00 00 48 4B rnrn取值过程如下:rn[img=https://img-bbs.csdn.net/upload/201712/01/1512119579_676185.png][/img]rnrn现想通过VB利用mscomm组件实现数据读取,但不知道如何做。请大家帮个忙!!!
向串口发送AT指令的问题,虚心向高手请教!
串口打开后,发送AT指令如下:rn sprintf(cmd,"AT\r");rn WriteComm(cmd,strlen(cmd));rn ReadComm(temp,20); rn 返回值是"OK"后面跟一些乱码类似“烫烫烫烫烫烫?
valgrind跑mxnet非法指令
删除src/operator/operator_tune.cc文件
串口发送指令
VC++,我是拿别人的改的,就是向串口发送指令,来实现功能的,得有下位机配合
AT指令简编(串口短信猫)
包括短信,语音,传真等。。。协议,很详细,
串口发送指令的问题
if(IC_ReadByte(TWIC_P3,0X13)&0x20)//uart 1 ===>OKrn rn if(UART1_BASE[0x14] & 0x01)//检测是否有接收到数据rn rn //IC_WritByte(TWIC_P3,0x13,0x10);rn a=UART1_BASE[0x00];//串口1接收数据rn //getuart_uart1(a); //接收到的数据放入Buffer rn Check_uartcmd(a);rn IC_WritByte(TWIC_P3,0x13,0x20);//清标志位rn rn rnrnvoid Check_uartcmd(unsigned char dat)rnrn static unsigned char data cmd[8],i=0;rn static unsigned char data datalen=0;rn unsigned short data checksum=0,j=0;rnrn if(dat!=0xFF&&cmd[1]!=0xFF)rn rn i=0; rn datalen=0;rn return ;rn rn elsern rn cmd[i]=dat;rn if(i==2)rn datalen=dat;rn if(i==(datalen+2))rn rn for(j=0;j=UARTCMD_MAXNUM)rn cmd_wr_idx=0;rn return cmd_wr_idx;rn求Check_uartcmd(unsigned char dat)及 char put_uart_event(unsigned char * cmd)rn这两个函数的解析
dwin串口屏指令
数据包长度: AA 指令 数据      CC 33 C3 3C        (最多248B) ------------------------------------------------------------------------ 握手指令 Tx:AA 00 CC 33 C3 3C Rx:AA 00 4F 4B 5F 56 37 2E 30 03 07 0C 00
串口指令发送软件
用了一些串口调试助手,也可以连续下发多条数据,不过很多时间都不可以配置,所以干脆自己写一个,下发的数据和时长可以在配置文件配置。有的时候可以用一下。
串口指令求教
用16进制计算发送指令(校验码):校验码=(设备地址0X01)XOR(命令) XOR(数据0X00)rnrn发送格式:rn设备地址(01-15)命令(0x00查状态、0x01停止、0x03起闸、0x05落闸、0x09查计数、0x0F清计数)数据(00)校验码rnrn以1号机为例:起闸指令 01-03-00-02(字节之间无空格)rn落闸指令 01-05-00-04(字节之间无空格)rnrn[color=#FF0000]起闸指令 01-03-00-02 (01是机器码,03是起闸命令 这个我能看懂,后边的00 02是什么意思,同理落闸指令后边的00 04又是什么意思,如果是1号机停止指令应该怎么写)没搞过串口,还请指教[/color]
AT指令进行串口操作
AT指令进行串口操作!可以备份通信录、短信息、通话记录。首先要装驱动,VS2008环境下。
VS2010+MFC串口助手,自动识别串口,支持循环发送指令
VS2010+MFC串口助手,自动识别串口,支持循环发送指令。SerialPort类,非控件。
串口调试器(可调式AT指令)
修复bug版,串口调试器,Ctrl+Shift+Z:发送Ctrl+Z字符,方便调试AT指令 本软件由C#编写,需要有dotnetframework2.0的支持哦 共享地址:http://www.uudisc.com/user/engin/file/3577261
stm32串口指令
单片机基础学习 STM32的GPIO输出模式:    STM32的GPIO输出模式就分为普通推挽输出(GPIO_Mode_Out_PP )、普通开漏输出 (GPIO_Mode_Out_OD)及复用推挽输出(GPIO_Mode_AF_PP )、复用开漏输出(GPIO_Mode_AF_OD )。 普通推挽输出模式一般应用在输出电平为 0和3.3伏的场合。而普通开漏输出一般应用在电平不匹配的场合,如...
SMS at指令串口测试工具
SMS at指令串口测试工具SMS at指令串口测试工具SMS at指令串口测试工具。(把串口的2、3脚相接可以在同一个串口通信。)
迪文科技串口指令
迪文科技串口指令屏指令手册
单片机ARM指令详解
ARM指令详解,指令详解.ARM指令详解.ARM指令详解,ARM指令详解.ARM指令详解.pdf
单片机汇编语言程序设计指令
用于了解单片机的汇编语言指令 PDF格式
相关热词 c#入门推荐书 c# 解码海康数据流 c# xml的遍历循环 c# 取 查看源码没有的 c#解决高并发 委托 c#日期转化为字符串 c# 显示问号 c# 字典对象池 c#5.0 安装程序 c# 分页算法