串口收发实验——键盘键入数字**.*,PC端循环接收显示**.*

发布者:Amy啊111111最新更新时间:2022-01-18 来源: eefocus关键字:串口收发  PC端 手机看文章 扫描二维码
随时随地手机看文章

小编今天笔记一下串口的收发实验,实验的灵感来源于对蓝牙模块收发的学习。我们在电路中使用蓝牙,其实就是把蓝牙看做是一个中转站,这个中转站在透传的模式下,不会对接收到的数据做任何变动,而是直接转发出去。


那么,我们只要知道单片机串口收发和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端显示**.*并换行循环显示直至键入新的数

关键字:串口收发  PC端 引用地址:串口收发实验——键盘键入数字**.*,PC端循环接收显示**.*

上一篇:51单片机实验1——串行通信(TX/RX)
下一篇:小白学习HC-05蓝牙透传模块

推荐阅读最新更新时间:2024-11-11 20:57

51单片机的串口收发C51程序
//晶振11.0592Mhz //2010年10月9日给网友改,在硬件上调试通过 #include reg52.h unsigned char a1; bit flag; void main() { TMOD=0x20; TH1=0xfd; TL1=0xfd; TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1; while(1) { if(flag==1) { ES=0; flag=0; SBUF=a1; while(!TI); TI=0; ES=1; } } } void ser() interrupt 4 { i
[单片机]
写一个串口接收发送程序
对于串口,流,的编程一直是相当头疼的,总是分不清头尾,写出来的程序总是没有把握,传输间的的程序尚可,但是发送一些带协议的东西就受不了了。 经过查资料,学习,得到一些经验,可以使用定界符法,显式长度法来发送数据。 一贯习惯是使用定界符+显式长度,写的不论不类,现在想想没有这个必要,如果在单片机上的话使用定界符,在中断里快速判断定界符和过滤每一个字符是相当奢侈的事情。故而转用显式长度法 显式长度的具体用法是,先发送要发送数据的字节数,在发送数据 接收也比较简单,先接收数据长度区,判断大小是否适合自己的RAM空间, 确定需要接收的长度后,启动正常的接收,并设置一个超时(在有限的时间里没有收到完整的数据,则丢弃)。在实际的应用中,发
[单片机]
STM32串口收发数据为什么要使用DMA?有哪些常见问题?
直接存储器访问(Direct Memory Access),简称DMA。DMA是CPU一个用于数据从一个地址空间到另一地址空间“搬运”(拷贝)的组件,数据拷贝过程不需CPU干预,数据拷贝结束则通知CPU处理。因此,大量数据拷贝时,使用DMA可以释放CPU资源。 在STM32控制器中,芯片采用Cortex-M3架构,总线结构有了很大的优化,DMA占用另外的总线,并不会与CPU的系统总线发生冲突。也就是说,DMA的使用不会影响CPU的运行速度。 DMA数据拷贝过程,典型的有:(1)内存— 内存,内存间拷贝;(2)外设— 内存,如uart、spi、i2c等总线接收数据过程;(3)内存— 外设,如uart、spi、i2c等总线发送
[单片机]
STM32<font color='red'>串口</font><font color='red'>收发</font>数据为什么要使用DMA?有哪些常见问题?
51单片机串口收发字符串源程序
想要通过串口控制led,但是串口每次中断只能发送一个字符,这样在控制的时候不太容易清楚各个命令是控制哪一部分,所以参考网上的资料,写了个简单的字符串收发函数。本程序的功能是:电脑串口助手发送数据给单片机,单片机接收后返回给电脑,在发送的时候,需要空两格再输入想要传送的内容,不然的话传输的数据会丢失,因为这个情况不影响串口控制LED,所以就没管了。 单片机源程序如下: #include reg52.h typedef unsigned char uchar; typedef unsigned int uint; sbit led=P2^0; void Usart_Init() { TMOD=0X20; PCON=0X80; S
[单片机]
51单片机<font color='red'>串口</font><font color='red'>收发</font>字符串源程序
Stm32RS232串口通信——中断接收发送数据
main.c配置: /* *说明: *PA0:KEY1;PA1:KEY2; *PA2:LED1;PA3:LED2; *PA9:USART1_TX;PA10:USART1_RX */ #include stm32f10x.h #include stm32f10x_rcc.h #include stm32f10x_gpio.h #include stm32f10x_usart.h #include stm32f10x_exti.h #include system_stm32f10x.h #include misc.h void RCC_Configurati
[单片机]

推荐帖子

嵌入式12寸工业平板电脑
产品特性:12.1″LCD工业级平板电脑材料采用铝美合金,体积轻巧、造型美观。达到军工级别.具备坚固、防震、防潮、防尘、耐高温多插槽和易于扩充等特点,是各种工业控制、交通控制、环保控制等自动化领域应用的最佳平台。整机配置12.1”宽温、高亮度LCD液晶显示屏,集成工业级低功耗嵌入式主板,支持CF、HDD,具有多个I/O接口;可扩展一个,PCI卡,电阻式触摸屏可选;12.1寸LCD显示屏,亮度、对比度可调节,并具有待机节能模式。
xt107 PCB设计
低成本无线射频通信芯片选型
低成本无线射频通信芯片选型最近要做一款无线通信的遥控控制装置,要求成本低。TI带无线的MCU就TI而言:带无线的MCU,低成本的有:大概都是12元左右单片机+射频芯片就单向通信而言:430G2553:0.797=5.53元CC113L:0.797=5.53元CC115L:0.597=3.39元CC110L:0.957=6.55元CC1101:1.45*7=10.15元如果只是单向通信430G2553+CC113L价
Jacktang 无线连接
觉得泰格功分器的幅度平衡,相位平衡还是差了点。
觉得泰格功分器的幅度平衡,相位平衡还是差了点。觉得泰格功分器的幅度平衡,相位平衡还是差了点。
xujia525 RF/无线
四轴飞行器视频
四轴飞行器视频集锦http://u.youku.com/user_video/id_UODQyOTgyNDQ=.html 四轴飞行器视频haahhaaaaaa
绿茶 DIY/开源硬件专区
自己买的430开发板电路图
和大家分享自己买的430开发板电路图楼主精神可嘉!JTAG电路图有吗,我要做一个
hrr666 DIY/开源硬件专区
该怎么理解全桥图腾柱功率因数校正图,这4个MOS管是整流还是什么意思?
该怎么理解全桥图腾柱功率因数校正图,这4个MOS管是整流还是什么意思?该怎么理解全桥图腾柱功率因数校正图,这4个MOS管是整流还是什么意思?从电路的组成形式来看,象是全桥整流电路,Q1,Q2的电路符号没有见过了。左边这两个是什么?图腾柱PFC是一种交流转直流的转换器概念,它用半导体开关替代了电流路径上的所有二极管输入电流根据占空比在晶体管Q1和Q2之间切换图腾柱式的整流电路相对于普通整流二极管电路,效率高了很多。目前实物没怎么见过有具体的实物电路产品吗?
kal9623287 电源技术
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved