历史上的今天
今天是:2024年12月23日(星期一)
2021年12月23日 | 串口收发实验——键盘键入数字**.*,PC端循环接收显示**.*
2021-12-23 来源:eefocus
小编今天笔记一下串口的收发实验,实验的灵感来源于对蓝牙模块收发的学习。我们在电路中使用蓝牙,其实就是把蓝牙看做是一个中转站,这个中转站在透传的模式下,不会对接收到的数据做任何变动,而是直接转发出去。
那么,我们只要知道单片机串口收发和PC端键盘的输入都是以字符的ASCII码的形式进行的,PC端收到后显示则是正常字符的形式
即:
键盘键入字符(ASCII码形式)–>单片机收到字符(ASCII码形式)
敲击3,实质键入0x33–>单片机读buff收到消息0x33
单片机发送字符(ASCII吗形式)–>模拟PC收到字符(正常形式显示)
单片机发送字符3,实质写buff发0x33–>模拟PC收到后显示3
废话少说,上仿真电路图:

代码:
main.c
#include #include #define uint unsigned int #define uchar unsigned char #define ulong unsigned long sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; //38译码器的片选 bit lanya = 0 ; //蓝牙发送标志,单片机发送给PC uchar LanYa_DATA_count=0; //用于后面LnaYa_receive[]数组的各位数赋值,相当于[i]中的i uchar LanYa_receive[4]; //LanYa串口接收数据缓存 uint Receive_Data; //最后单片机接收的整合的数据 ,必须是uint,因为uchar不能超过255 uchar Display_Data[3]; //处理要显示在数码管的数据缓冲数组 uchar Computer[4]; //要发给PC的数组 uchar T0RH = 0; //用于后面的TH0赋值 uchar T0RL = 0; //用于后面的TL0赋值 uchar UART_data; /*设一个中间变量,获取读sbuf的数据,在串口中断服务函数中用到*/ uchar code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79}; /******************************************************** 函数名称:void delay(uint i) 函数作用:延时函数 参数说明: ********************************************************/ void delay(uint i){ //延时函数 while(i--); } /******************************************************** 函数名称:ConfigUart(uint baud) 函数作用:串口初始化函数 参数说明: baud:要设置的波特率 ********************************************************/ void ConfigUart(uint baud){ SCON = 0x50; //配置串口:工作方式1,既可以接,也可以收 TMOD |= 0x20; //配置定时器T1为工作方式2:自动重装 ;使用T1的目的就是作为波特率发生去的一部分 TH1 = 256 - (11059200/12/32)/baud; //利用公式,加上参数,计算T1重载值 TL1 = TH1; //初值等于重载值 ET1 = 0; //禁止定时器T1中断(因为它作为波特发生器一部分) TR1 = 1; //启动T1,即使能T1 EA=1; //开总中断 ES=1; //开串行口中断 } /******************************************************** 函数名称:send_char_com(uchar ch) 函数作用:利用串口发送一个字符 ,串口接/收的其实就是8位的ASCII,即一个字符 参数说明: uchar ch:要发送的字符 ********************************************************/ void send_char_com(uchar ch) { SBUF=ch; //发sbuf,发送字符ch while(TI==0); //TI被硬件置1表示发送成功,跳出死循环 TI=0; //软件将TI置零,接着准备下次发送 } /******************************************************** 函数名称:send_string_com(unsigned char *str,unsigned int strlen) 函数作用:利用串口发送字符串 参数说明: unsigned char *str:指针指向字符串的首地址,unsigned int strlen:想发送的长度(这个字符串的字符个数) ********************************************************/ void send_string_com(uchar *str,uint strlen){ uint k=0; do { send_char_com(*(str + k)); /*这里应该是用来指针的首地址+偏移量*/ k++; } while(k < strlen); } /******************************************************** 函数名称:void ConfigTimer0(unsigned int ms) 函数作用:定时器0初始化函数,ms级定时溢出中断 参数说明: unsigned int ms:设置定时溢出的ms数 ********************************************************/ void ConfigTimer0(uint ms){ ulong tmp; tmp = 11059200/12; tmp = (tmp * ms)/1000; tmp = 65536 - tmp; tmp = tmp + 18; EA = 1; T0RH = (uchar)(tmp >> 8); T0RL = (uchar)tmp; //上面的这些行直接用就行 TMOD &= 0xF0; TMOD |= 0x01; //设置TMOD的定时器0,方式1,需要重装初值的 TH0 = T0RH; TL0 = T0RL; ET0 = 1; //开定时器0的中断允许 TR0 = 1; //开定时器0的使能 } /******************************************************** 函数名称:void dispiay() 函数作用:数据处理并显示 参数说明: 无 ********************************************************/ void dispiay(){ uchar i; Display_Data[0]=smgduan[Receive_Data/100]; Display_Data[1]=smgduan[Receive_Data%100/10] | 0x80; //0x80是加个小数点 Display_Data[2]=smgduan[Receive_Data%10]; for(i=0;i<3;i++){ //先分别选中位,循环和switch实现 switch(i){ case 0: LSA=0;LSB=0;LSC=0;break; case 1: LSA=1;LSB=0;LSC=0;break; case 2: LSA=0;LSB=1;LSC=0;break; } P0=Display_Data[2-i]; //选中位后,传段选数据 delay(100); //延时1ms P0=0x00; //消隐 } } /******************************************************** 函数名称:void main() 函数作用:数据处理并显示 参数说明: 无 ********************************************************/ void main(){ //主程序 uchar i; ConfigUart(9600); //波特率设置为9600 ConfigTimer0(5); //定时器T0 5ms while(1){ for(i=0;i<4;i++){ Computer[i]= LanYa_receive[i]; } dispiay(); //显示在数码管 if(lanya==1&&(UART_data=='r')){//蓝牙标志位置1,表单片机发送,并且读buff收到回车字符(表示PC端发送结束) send_string_com(Computer,4); //将从PC端接收到的数据发送给PC端 send_char_com('r'); //发送r,表换行 lanya = 0; //蓝牙标志清零,单片机发送结束 } } } /******************************************************** 函数名称:void InterruptTimer0() interrupt 1 函数作用:定时器0中断服务程序 参数说明: 无 ********************************************************/ void InterruptTimer0() interrupt 1{ static uchar tmr1s = 0; TH0 = T0RH; //重新加载重载值 TL0 = T0RL; tmr1s++; if(tmr1s >= 200) //这个tmr1s变量起缓冲的 { tmr1s = 0; lanya = 1; //将”lanya“标志位置1,准备在main中单片机发送数据 } } /******************************************************** 函数名称:void uart(void) interrupt 4 函数作用:串口中断服务程序 参数说明: 无 ********************************************************/ void uart(void) interrupt 4 { uchar a,b,c; if(RI) { UART_data=SBUF; if(UART_data=='r'){ //如果检测到回车按键则得到Receive_Data,将其(PC发送给单片机的数)通过display函数显示在数码管上 a = LanYa_receive[0]-0x30; /*这些数都减0x30的原因是:微机原理中,数字0-9,对应ASCII吗为30H-39H 字母A-Z 对应ASCII码就是41H-5AH,字母a-z ASCII码就是61H-7AH 这样减30H就可以得到显示正确的数字*/ b = LanYa_receive[1]-0x30; c = LanYa_receive[3]-0x30; Receive_Data = a*100+b*10+c; LanYa_DATA_count=0; } else{ //否则将PC传来的字符串一个字符一个字符的存放至LanYa_receive[]数组中 LanYa_receive[LanYa_DATA_count]=UART_data; LanYa_DATA_count++; } } RI=0; } 仿真结果 键盘键入**.则 数码管显示*.* PC端显示**.*并换行循环显示直至键入新的数
下一篇:小白学习HC-05蓝牙透传模块
史海拾趣
|
SDRAM工作过程: 1. 上电稳定后经过8个刷新周期,进入模式寄存器设置(MRS),确定芯片的工作模式,CL,BL,突发传输方式。 2. 行有效,同时进行了片选和BANK选择工作。CS RAS有效 CAS WE ...… 查看全部问答> |
|
http://download.eeworld.net/source/2310249(软件地址)这个软件安装好了以后,不单单是现在表面所看到的!图片地址(http://home.51.com/wutuanfeng/photo/item/100133258.html)在这些文件夹里面还是一样的效果背景图也是变化万千的!文件夹的 ...… 查看全部问答> |
|
应用程序调用 wince5.0的 nandflash驱动 错误 使用 CreateFile 但始终都不成功,应用中代码如下 hFunction = CreateFile( TEXT(\"DSK1:\"), GENERIC_ ...… 查看全部问答> |
|
我现在下载的是keil uv3,安装成功后,能够输入程序,但是编译不起来,在编译的时候会出现提示框:uVision3-Path undefined,\'tOOLS.INI\' does contain a tool path ,you have selecteed a device where no toolchain has been install ...… 查看全部问答> |
|
各位有玩过传真芯片没 传真通讯过程中发送端要发送TCF,是1.5s的“0”串 是1.5s的0x00么 另外 接收端怎样确定正确接收TCF 是判断接收的是不是1.5s的0x00么 各位指点下 谢谢… 查看全部问答> |
|
如何在vs2005上的win32工程中加入一个对话框并且为上面的按钮加入消息处理函数,急急急急急急 如题,在资源界面添加了一个dialog,上面有一个ok和取消键, 自己曾经做过mfc的桌面程序,记得按ctrl+w就调出类向导界面为新对话框添加类, 但win32我就不懂了,请问高手们如何添加界面,并为按钮添加消息处理函数。 多谢。… 查看全部问答> |
|
单片机初学者问题,高人指点,急,在线等。谢谢了!!!!!!!!!!! 本人初学者,下载了平凡的单片机的电子书。本人初学,望高手指点,不要笑话。谢谢了。 问题如下: #include “reg51.h” sbit P1_0=P1^0; void main() { P1_1=0; } 这个是让接在p1.0脚上的led发光。既然都给p1_1赋了0,就是让p1.0脚发光 ...… 查看全部问答> |




