单片机串口打印数据_51单片机串口打印数据 - CSDN
  • 昨天遇到的问题是单片机串口给电脑发数据,本人用串口助手查看时乱码了,发送的数据是英文和数字,没有存在中文,马上进行问题排除:解决方案一:printf的原因吗?代码里用piintf函数来进行串口发送数据,可能...

    讲道理都tm大三暑假了还搞51单片机而且关键是还遇到了一个问题解决了一天才解决出来真的是很丢人了。

    不过我会珍惜这个机会的,毕竟这有可能是我辈子最后一次跟着老师搞这个破玩意了。

    好了不废话了 收!

    昨天遇到的问题是单片机用串口给电脑发数据,本人用串口助手查看时乱码了,发送的数据是英文和数字,没有存在中文,马上进行问题排除:

    解决方案一:printf的原因吗?

    代码里用piintf函数来进行串口发送数据,可能printf只适合于stm32不能适用于51,但是仔细一想又不对啊,我tm大三上的单片机大作业就是用printf函数进行串口发送数据的啊,怎么当时就可以啊。于是我把当时的代码拿过来修改,还是不行。

    解决方案一卒。

    解决方案二:硬件芯片的原因吗?

    换了另外一块芯片,还是不行。

    解决方案二卒。

    解决方案三:晶振的原因吗?

    赶紧查看开发板上面的晶振,刻着12Mhz,在keil4软件里面查看晶振,晶振的设置是12Mhz,这里算是对上了。想起上个学期的单片机晶振是11.0592Mhz,可能是这个原因吧,但是没有办法啊,晶振已经焊上去了,我能怎么办我也很绝望啊。

    解决方案三卒。

    解决方案四:波特率的原因吗?

    这里要感谢一篇博客给我的启发,详见参考资料。

    和博主一样,使用波特率9600,TL1和TH1都设置成0xfd,不管是中文还是英文都是乱码,那肿么办呢?波特率换成2400,2400,2400,重要的事情说三遍!!!TL1和TH1都设置成0xf3。

    哈哈哈哈终于不乱码了,开心。


    总结:没什么好总结了,就是菜。就是一个菜鸡发现了9600到2400的过程。

    参考资料:

    https://www.cnblogs.com/geekalan/p/4005427.html

    https://zhidao.baidu.com/question/110468495.html?fr=qrl&index=3

    展开全文
  • stc的89c52rc型号开发板,晶振是12m。是因为买的最小系统就是这个频率。使用波特率位9600,将TL、TH都设置成0xfd后不管是英文还是中文的都是乱码。 12M的晶振波特率只能是2400...为什么51单片机的晶振一般使用11.0592?

    stc的89c52rc型号开发板,晶振是12m。是因为买的最小系统就是这个频率。使用波特率位9600,将TL、TH都设置成0xfd后不管是英文还是中文的都是乱码。

    12M的晶振波特率只能是2400,9600的情况下会有7.8%的误差,所以会产生乱码,而2400波特率的情况下误差是0.16%,这样就不会产生乱码了,TH1和TL1都设为F3

    为什么51单片机的晶振一般使用11.0592?
    用11.0592晶振的原因是51单片机的定时器导致的。用51单片机的定时器做波特率发生器时,如果用11.0592Mhz的晶振,根据公式算下来需要定时器设置的值都是整数;如果用12Mhz晶振,则波特率都是有偏差的,比如9600,用定时器取0XFD,实际波特率10000,一般波特率偏差在4%左右都是可以的,所以也还能用
    STC90C516 晶振12M 波特率9600 ,倍数时误差率6.99%,不倍数时误差率8.51%,数据肯定会出错。 这也就是串口通信时大家喜欢用11.0592MHz晶振的原因,在波特率倍速时,最高可达到57600,误差率0.00%。 用12MHz,最高也就4800,而且有0.16%误差率,但在允许范围,所以没多大影响。
    
    
    #include<reg51.h>  
    //stdio.h,string.h用于printf函数原型  
    #include<stdio.h>  
      
      
    void delay(unsigned int z);  
    void uart_init(void);//串行口初始化  
      
    int main(void)  
    {  
        int a=99;  
        char *string="abde";  
        uart_init();  
        while(1)  
        {  
    	    puts("abcd");
            printf("%d  %x  %c  %s  %p\n",a,a,(char)a,string,string);  
            delay(1000);  
        }  
        return 0;  
    }  
      
    void uart_init(void)  
    {  
        TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2  
        TH1=0xf3;//设置波特率为9600  
        TL1=0xf3;  
        TR1=1;//启动定时器/计数器1  
          
        SCON=0x50; //0101 0000.串口工作方式1,允许串行控制  
        PCON=0x00;//设置SMOD=0  
        IE=0x90; //CPU允许中断,串行允许中断  
          
        TI=1;//直接使用printf必须加入此句才能实现发送  
    }  
      
    void delay(unsigned int z)  
    {  
        unsigned int x,y;  
        for(x=z;x>0;x--)  
            for(y=110;y>0;y--);  
    }
    
    
    
    
    
    实验结果如下:
    
    
    展开全文
  • 串口printf的使用函数原型如下:void USART0_Printf(char *fmt,...)//这个是我们的printf函数{ char* ap; //typedef char *va_list; va_list是char型的指针 charxdata string[128]; //访问外部RAM 两字节对齐 va_...

    串口printf的使用

    函数原型如下:

    void USART0_Printf(char *fmt,...)//这个是我们的printf函数

    {

     char* ap;  //typedef char *va_list; va_list是char型的指针

     charxdata string[128];  //访问外部RAM 两字节对齐

     va_start(ap,fmt);  //这个函数的功能是,找到第一个可变形参的地址,并把地址赋给ap

     vsprintf(string,fmt,ap);

     USART0_SendString(string);  //这个函数就是发送字符串函数,通过上一个函数,就把该提取的东西都提取了

     va_end(ap);  //结束函数

    }

    这个函数在51调试的时候还是非常好用的,特别是又用串口ISP下载的用户。接下来简述下函数的用法:

    1、在编写函数之前,首先需要添加stdarg.h头文件,其中va_start和va_end函数就是这个里面的库。


    2、其次就是需要分配一个空间,例如上面的char xdata string[128]; 因为空间有限,我这里给的是外部128字节。打印的长度超出了可能就会出问题了,根据情况,在空间充足的情况下可以分配大一点。


    3、编写底层的串口打印字符串函数,在51的程序里我一般写成如下:

    //串口0发送一个字节

    void USART0_SendByte(u8 value)

    {

           SBUF= value;  //发送一个字节                         

           while(!TI);   //等待TI置1              

                  TI=0;                                 

    }

    //串口0发送字符串

    void USART0_SendString(u8 *dat)

    {

           while(*dat!='\0')

                  USART0_SendByte(*dat++);

    }

    这是串口0的打印函数,如果换成串口1也是一样的。

    在使用的过程中需要注意有数据的情况下,数据需要强转成int型不能直接用unsigned char,这个不是我今天所遇到的问题,在上学期间实践过,所以使用的时候我都加了强转,例如:

    USART0_Printf("PWR_LEVEL=%d  MOD_LEVEL=%d  FAN_LEVEL=%d TIME_LEVEL=%d FUN_LEVEL=%d\n",

                               (int)PWR_LEVEL,(int)MOD_LEVEL,(int)FAN_LEVEL,(int)TIM_LEVEL,(int)FUN_LEVEL);


    转自:https://blog.csdn.net/qq997758497/article/details/77411404

    展开全文
  • 通过STM8单片机串口输出三组数据,然后通过串口波形显示软件实时显示单片机输出的数据。这种方法可以在ADC数据采集的时候实时显示数据波形,方便调试。
  • 单片机串口数据发送与接收源程序,已调试过啦
  • 单片机串口接收多字节数据 2017年07月14日 16:52:13Phenixyf阅读数:7123 http://bbs.elecfans.com/jishu_409918_1_1.html 各位大侠看一下,我下面的程序为什么不能接收两个字节的数据呢? #include<reg51.h&...

    单片机串口接收多字节数据

    2017年07月14日 16:52:13 Phenixyf 阅读数:7123

    http://bbs.elecfans.com/jishu_409918_1_1.html

    各位大侠看一下,我下面的程序为什么不能接收两个字节的数据呢?
    #include<reg51.h>
    #define uchar unsigned char
    #define uint unsigned int
    void rs232_init();
    uchar flag,i,g,d;
    uchar code table[]="I get ";
    //sbit led=P1^0;
    main()
    {
            rs232_init();
            while(1)
            {
                    if(flag==1)
                    {
                            ES=0;
                            for(i=0;i<6;i++)
                            {
                                    SBUF=table[i];
                                    while(!TI);
                                    TI=0;
                            }
                            SBUF=g;
                            while(!TI);
                            TI=0;
                            SBUF=d;
                            while(!TI);
                            TI=0;
                            ES=1;
                            flag=0;
                    }                
            }
    }
    void rs232_init()
    {
            TMOD=0x20;
            TH1=0xfd;
            TL1=0xfd;
            TR1=1;
            REN=1;
            SM0=0;
            SM1=1;
            EA=1;
            ES=1;        
    }
    void ser()interrupt 4
    {
            RI=0;
            g=SBUF;
            d=SBUF;
            flag=1;
    }

    我用串口调试助手调试时,上位机给单片机发送两个字节的数据,例如发送ck两个字母时,只接收到cc两个字母呢?

     

    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    首先数据发送是一位一位发送的,串口接收也是一位一位接收的,当接收8位数据后,申请中断。

    你的程序中,程序进入中断后,你用了g=SBUF,d=SBUF,程序之所以进入中断是因为串口接收到了八位数据,是八位数据,不是十六位数据,也就是你发送的字母ck中的c,k还没有发送完呢,所以g和d都被赋值了c,打印结果当然是cc了。

    你要了解串口是接收八位数据后申请中断,你必须在下一个八位数据接收完(下一次中断到来前)以前取走这个数据,不然这个数据将会丢失。

    我给你改 的程序如下,我定义一个宏N,N就是你每次发送的数据个数,然后一个数组,数组有N个元素,用于存储串口接受的数据。

    当串口有中断时,我立即把这个数据存储到数组中,同时将数组指针指向下一位,然后当下一个中断来时重复上面步骤,直到接收数据个数到达N。

    这里中断中程序不能太长,如果程序很长,我本次数据还没存储好,下一个数据已经到了,会丢失数据。

    1. #include<reg51.h>
    2. #define uchar unsigned char
    3. #define uint unsigned int
    4. #define N 2                                                        //可一次接收数据量
    5. void rs232_init();
    6. uchar flag,i;                                                       //删除无用变量                           
    7. uchar code table[]="I get ";
    8. uchar table1[N];                                              //接收缓存数组
    9. uchar j=0;                                                             //接收计数器
    10. //sbit led=P1^0;
    11. main()
    12. {
    13.          rs232_init();
    14.          while(1)
    15.          {
    16.                  if(flag==1)
    17.                  {
    18.                          ES=0;
    19.                          for(i=0;i<6;i++)
    20.                          {
    21.                                  SBUF=table[i];
    22.                                  while(!TI);
    23.                                  TI=0;
    24.                          }
    25.                          for(j=0;j<N;j++)                        //发送接收数组
    26.                                                  {
    27.                                                          SBUF=table1[j];
    28.                                  while(!TI);
    29.                                  TI=0;
    30.                                                 }
    31.                          j=0;                                           //清零接收计数器
    32.                          ES=1;
    33.                          flag=0;
    34.                  }                
    35.          }
    36. }
    37. void rs232_init()
    38. {
    39.          TMOD=0x20;
    40.          TH1=0xfd;
    41.          TL1=0xfd;
    42.          TR1=1;
    43.          SM0=0;
    44.          SM1=1;
    45.                  REN=1;                                                        //先设定号工作方式,在打开允许接收
    46.          EA=1;
    47.          ES=1;        
    48. }
    49. void ser()interrupt 4
    50. {                 
    51.                 RI=0;
    52.                 table1[j++]=SBUF;                                //存数据到接收缓存
    53.                 if(j==N)                                                //数组满时,允许发送
    54.                 flag=1;
    55. }

    复制代码

     

     

    受此贴启发,Starsky项目中,串口中断接收更改如下成功接收多字节:

    /*    串口接收数据中断服务函数    */
    #pragma vector = 0x14              //设置串口接收中断向量号 = 0X14 = 20
    __interrupt void UART1_RX_RXNE(void)
    {          
      static int cnt=0;


      UART1_SR_RXNE = 1;    //清除中断标志
      
      if(cnt == (COMBUFNUM-1))  //receive data done
      {    
        bufRec[cnt]= UART1_DR;  //last byte
        recCmd = bufRec[1];
        dutyPwm = (int) bufRec[2];
        cnt =0;
      }
      else{
        bufRec[cnt]= UART1_DR;
        cnt++;
      }
    }

    其中bufRec为接收buffer;

    UART1_DR为STM8S003F6 UART接收数据寄存器。

     

    展开全文
  • 这是我学习PIC单片机调试过程中尝试的PIC单片机串口发送实验,当按键RB0有按下时,num自加,同时RC0端口接的LED翻转,并把num的数传给发送寄存器发送至电脑端,波特率为9600,4M晶振. 代码如下: #include&amp;lt;pic...

    这是我学习PIC单片机调试过程中尝试的PIC单片机串口发送实验,当按键RB0有按下时,num自加,同时RC0端口接的LED翻转,并把num的数传给发送寄存器发送至电脑端,波特率为9600,4M晶振.

    代码如下:
    #include<pic.h>
    __CONFIG(0x3B31);

    unsigned int num=0;

    void GPIO_init()
    {
    TRISB=0xff;
    TRISC=0xfe;
    TRISC0=0;
    OPTION_REG=0x07;
    }

    void delay(unsigned int x)
    {
    unsigned int i,j;
    for(i=x;i>0;i–)
    for(j=110;j>0;j–);
    }

    void serialinit()
    {

    TXSTA=0x24;
    RCSTA=0x90;
    SPBRG=25;
    GIE=1;
    PEIE=1;
    TXIE=0;
    

    }
    void key_scan()
    {
    if(RB00)
    {
    delay(15);
    if(RB0
    0)
    {
    num++;
    TXIE=1;
    TXIF=1;
    if(!(num%2))
    {
    RC0=~RC0;
    }

    		while(!RB0);
    	}
    }
    

    }

    void interrupt serial0()
    {
    if(TXIE&&TXIF)
    {
    TXIF=0;
    TXIE=0;
    //RCREG=num;
    if(num==30)
    {
    num=0;
    TXREG=0x80;
    }
    else
    TXREG=num;
    while(!TRMT);
    }

    }

    void main()
    {
    GPIO_init();
    serialinit();
    while(1)
    {
    key_scan();
    }
    }

    代码不太会排版.如有会的大大教教以后发布就可以调整了.

    展开全文
  • 瑞萨单片机串口使用

    2019-06-16 03:08:39
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 我们都知道,单片机串口传输的单位是字节,而浮点型数是占四个字节,简单思路是用一个char型指针指向浮点型数据,利用指针寻址即可以将浮点数拆成四个char数据。接收端接收到四个char型数,为了还原成float型数据,...
  • 单片机自定义串口打印程序 #include <stdarg.h> #include <stdio.h> void printf(const char* format, …) { uint8_t buf[256]; //申请打印内容缓存,不得超过256字节 uint32_t len = 0; //实际打印的...
  • 自己编的,不过格式还是算规范的吧,单独建了个.C的文件,专门用于模块程序的放置,这样以后好调用些,希望对大家有用
  • 现在在做串口接收单片机返回的反馈码,串口定义的委托,有一个接收数据的事件,参数为(object sender,SerialDataReceivedEvenyArge e),在调用这个函数时候应该传什么参数呢?或者应该怎样改写这个函数?求大神指点...
  • 51单片机 串口接收字符串和发送字符串
  • 转自:... #include //------------------串口通信协议-----------------// /* 客户端数据包格式解释(长度恒为15): 例如:A01_fmq_01Off___# A--------数据包的开始标记(可以为A到Z,意味
  • 今天就简单来说说怎么在51单片机中使用"printf"函数:包括使用自带的printf函数和自己动手写一个printf函数,再贴代码之前先介绍几个相关的知识,主要用于自己写printf函数。 ①C语言函数:vsprintf, 其原型...
  • 以前使用MSP430做项目时也同样使用printf打印数据,所以现在想在stm32 上实现。  通常串口发送单字节库函数:USART_SendData(USART1, (uint8_t) ch);对显示小数等数据比较复杂,如果能够直接使用C语言 stdio.h中...
  • 51单片机一般使用串口的方法都是这样的 #include<reg52.h> #define uint unsigned int void UART_Init(); uint num ; /* ****************************************** **函数名称:主函数 *****************...
  • 效果图 虚拟串口 串口调试 Proteus电路设计图 51单片机程序代码 运行
1 2 3 4 5 ... 20
收藏数 3,983
精华内容 1,593
关键字:

单片机串口打印数据