精华内容
下载资源
问答
  • 51串口发送数据
    千次阅读
    2021-01-20 15:33:45

    串口通信

    需要知道几个基础知识点。
    波特率 起始位 停止位 校验位,具体的可以去查书。
    串口通信为串行通信方式,即每次只能发送一位,且为单工,一端固定为发送端,另一端为接收端。
    51单片机的串口需要配置的寄存器可以直接通过STC-ISP这个软件配置,选择好晶振的频率和波特率直接生成就可以了
    在这里插入图片描述下面直接贴代码

    bit uart1_busy=0;
    
    void UartInit(void) //115200bps@12.000MHz
    {
        SCON = 0x50;  //8位数据,可变波特率
        AUXR |= 0x01; //串口1选择定时器2为波特率发生器
        AUXR |= 0x04; //定时器2时钟为Fosc,即1T
        T2L = 0xE6;   //设定定时初值
        T2H = 0xFF;   //设定定时初值
        AUXR |= 0x10; //启动定时器2
    }
    
    void uart1_sendByte(char byte)	//串口发送一个字节
    {
        while (uart1_busy);
        uart1_busy = 1;
        SBUF = byte;
        TI = 0;
    }
    
    void uart1_sendstring(char* str)	//串口发送字符串
    {
        while(*str)
        {
            uart1_sendByte(*str++);
        }
    }
    
    char putchar(char c)		//	用于printf函数
    {
        uart1_sendByte(c);
        return c;
    }
    
    void UART1_IRQ_Handle(void) interrupt 4 using 1
    {
        if (TI)
        {
            TI = 0;
            uart1_busy = 0;
        }
        if (RI)
        {
            RI = 0;
        }
    }
    
    void Delay100ms()		//@12.000MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	_nop_();
    	i = 5;
    	j = 144;
    	k = 71;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
    
    void main()
    {
        UartInit(); //初始化串口
        EA = 1;     //开总中断
        ES=1;		//打开串口中断
        while (1)
        {
            uart1_sendstring("Hellow World!\n");
            Delay100ms();
            printf("Hello World!\n"); //串口打印结果
        }
    }
    

    51单片机用SBUF来储存发送和接收的到的数据,所以可以直接将需要发送的值赋值给SBUF。另外如果想要使用printf函数,需要重定义一下putchar函数才行。

    更多相关内容
  • c# 串口发送数据c# 串口发送数据c# 串口发送数据c# 串口发送数据
  • windows脚本给串口发送16进制数据
  • java语言,模拟串口,但是又是一款专用的串口测试软件,初次接触java,做的很笨拙,只供学习之用,文件里还有需要导入的包,以及生成的windows下可执行程序!
  • linux串口发送数据

    热门讨论 2010-09-05 21:55:35
    linux串口数据,linux串口数据,linux串口数据
  • 这里写目录标题串口发送数据串口接受数据 串口发送数据 1、串口发送数据最直接的方式就是标准调用库函数 。 void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); 第一个参数是发送的串口号,第二个参数是...

    串口发送数据

    1、串口发送数据最直接的方式就是标准调用库函数 。

    void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
    

    第一个参数是发送的串口号,第二个参数是要发送的数据了。但是用过的朋友应该觉得不好用,一次只能发送单个字符,所以我们有必要根据这个函数加以扩展:

    void Send_data(u8 *s)
    {
     while(*s!='\0')
     { 
      while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET); 
      USART_SendData(USART1,*s);
      s++;
     }
    }
    

    以上程序的形参就是我们调用该函数时要发送的字符串,这里通过循环调用USART_SendData来一 一发送我们的字符串。

    while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);
    

    这句话有必要加,他是用于检查串口是否发送完成的标志,如果不加这句话会发生数据丢失的情况。这个函数只能用于串口1发送。有些时候根据需要,要用到多个串口发送那么就还需要改进这个程序。如下:

    void Send_data(USART_TypeDef * USARTx,u8 *s)
    {
     while(*s!='\0')
     { 
      while(USART_GetFlagStatus(USARTx,USART_FLAG_TC )==RESET); 
      USART_SendData(USARTx,*s);
      s++;
     }
    }
    

    这样就可实现任意的串口发送。但有一点,我在使用实时操作系统的时候(如UCOS,Freertos等),需考虑函数重入的问题。
    当然也可以简单的实现把该函数复制一下,然后修改串口号也可以避免该问题。然而这个函数不能像printf那样传递多个参数,所以还可以在改进,最终程序如下:

    void USART_printf ( USART_TypeDef * USARTx, char * Data, ... )
    {
     const char *s;
     int d;   
     char buf[16];
     
     va_list ap;
     va_start(ap, Data);
     
     while ( * Data != 0 )     // 判断是否到达字符串结束符
     {                              
      if ( * Data == 0x5c )  //'\'
      {           
       switch ( *++Data )
       {
        case 'r':                 //回车符
        USART_SendData(USARTx, 0x0d);
        Data ++;
        break;
     
        case 'n':                 //换行符
        USART_SendData(USARTx, 0x0a); 
        Data ++;
        break;
     
        default:
        Data ++;
        break;
       }    
      }
      
      else if ( * Data == '%')
      {           //
       switch ( *++Data )
       {    
        case 's':            //字符串
        s = va_arg(ap, const char *);
        
        for ( ; *s; s++) 
        {
         USART_SendData(USARTx,*s);
         while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
        }
        
        Data++;
        
        break;
     
        case 'd':   
         //十进制
        d = va_arg(ap, int);
        
        itoa(d, buf, 10);
        
        for (s = buf; *s; s++) 
        {
         USART_SendData(USARTx,*s);
         while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
        }
        
        Data++;
        
        break;
        
        default:
        Data++;
        
        break;
        
       }   
      }
      
      else USART_SendData(USARTx, *Data++);
      
      while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );
      
     }
    }
    

    该函数就可以像printf使用可变参数,方便很多。通过观察函数但这个函数只支持了%d,%s的参数,想要支持更多,可以仿照printf的函数写法加以补充。
    2、 直接使用printf函数。
    很多朋友都知道想要STM32要直接使用printf不行的。需要加上以下的重映射函数;
    在这里插入图片描述如果不想添加以上代码,也可以勾选以下的Use MicroLI选项来支持printf函数使用:
    在这里插入图片描述

    串口接受数据

    串口接收最后应有一定的协议,如发送一帧数据应该有头标志或尾标志,也可两个标志都有。
    这样在处理数据时既能能保证数据的正确接收,也有利于接收完后我们处理数据。串口的配置在这里就不在赘述,这里我以串口2接收中断服务程序函数且接收的数据包含头尾标识为例。

    #define Max_BUFF_Len 18
    unsigned char Uart2_Buffer[Max_BUFF_Len];
    unsigned int Uart2_Rx=0;
    void USART2_IRQHandler() 
    {
     if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生 
     {
      USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志
        
      Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2);     //接收串口1数据到buff缓冲区
      Uart2_Rx++; 
            
      if(Uart2_Buffer[Uart2_Rx-1] == 0x0a || Uart2_Rx == Max_BUFF_Len)    //如果接收到尾标识是换行符(或者等于最大接受数就清空重新接收)
      {
       if(Uart2_Buffer[0] == '+')                      //检测到头标识是我们需要的 
       {
        printf("%s\r\n",Uart2_Buffer);        //这里我做打印数据处理
        Uart2_Rx=0;                                   
       } 
       else
       {
        Uart2_Rx=0;                                   //不是我们需要的数据或者达到最大接收数则开始重新接收
       }
      }
     }
    }
    

    数据的头标识为“\n”既换行符,尾标识为“+”。该函数将串口接收的数据存放在USART_Buffer数组中,然后先判断当前字符是不是尾标识,如果是说明接收完毕,然后再来判断头标识是不是“+”号,如果还是那么就是我们想要的数据,接下来就可以进行相应数据的处理了。但如果不是那么就让Usart2_Rx=0重新接收数据。
    这样做的有以下好处:
    1.可以接受不定长度的数据,最大接收长度可以通过Max_BUFF_Len来更改
    2.可以接受指定的数据
    3.防止接收的数据使数组越界
    这里我的把接受正确数据直接打印出来,也可以通过设置标识位,然后在主函数里面轮询再操作。

    以上的接收形式,是中断一次就接收一个字符,这在UCOS等实时内核系统中频繁的中断,非常消耗CPU资源,在有些时候我们需要接收大量数据时且波特率很高的情况下,长时间中断会带来一些额外的问题。
    所以以DMA形式配合串口的IDLE(空闲中断)来接受数据将会大大的提高CPU的利用率,减少系统资源的消耗。首先还是先看代码。

    #define DMA_USART1_RECEIVE_LEN 18
    void USART1_IRQHandler(void)                                 
    {     
        u32 temp = 0;  
        uint16_t i = 0;  
          
        if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  
        {  
            USART1->SR;  
            USART1->DR; //这里我们通过先读SR(状态寄存器)和DR(数据寄存器)来清USART_IT_IDLE标志    
            DMA_Cmd(DMA1_Channel5,DISABLE);  
            temp = DMA_USART1_RECEIVE_LEN - DMA_GetCurrDataCounter(DMA1_Channel5); //接收的字符串长度=设置的接收长度-剩余DMA缓存大小 
            for (i = 0;i < temp;i++)  
            {  
                Uart2_Buffer[i] = USART1_RECEIVE_DMABuffer[i];  
                    
            }  
            //设置传输数据长度  
            DMA_SetCurrDataCounter(DMA1_Channel5,DMA_USART1_RECEIVE_LEN);  
            //打开DMA  
            DMA_Cmd(DMA1_Channel5,ENABLE);  
        }        
    } 
    

    之前的串口中断是一个一个字符的接收,现在改为串口空闲中断,就是一帧数据过来才中断进入一次。而且接收的数据时候是DMA来搬运到我们指定的缓冲区(也就是程序中的USART1_RECEIVE_DMABuffer数组),是不占用CPU时间资源的。

    最后在讲下DMA的发送:

    #define DMA_USART1_SEND_LEN 64
    void DMA_SEND_EN(void)
    {
     DMA_Cmd(DMA1_Channel4, DISABLE);      
     DMA_SetCurrDataCounter(DMA1_Channel4,DMA_USART1_SEND_LEN);   
     DMA_Cmd(DMA1_Channel4, ENABLE);
    }
    

    这里需要注意下DMA_Cmd(DMA1_Channel4,DISABLE)函数需要在设置传输大小之前调用一下,否则不会重新启动DMA发送。

    展开全文
  • timestamp=1563807838&req_id=201907222303570100230601438916BD5&group_id=67160264916892390441、这节课我们来实现串口的写入与接收,同样查看pyseri...

    https://m.toutiaocdn.com/group/6716026491689239044/?app=news_article&timestamp=1563807838&req_id=201907222303570100230601438916BD5&group_id=6716026491689239044

    1、这节课我们来实现串口的写入与接收,同样查看pyserial的在线文档,查看数据的写入与发送。

    2、Write方法,文档中表明,写的方法只能写bytes,所以我们在com.py,增加两个函数用来写数据:

    def comwritebytes(self,b):

    wlen=self.com.write(b)

    return wlen

    def comwritestring(self,b):

    wlen=self.com.write(b.encode('utf-8'))

    return wlen

    一个用来直接发送bytes数据,另一个将string数据转为bytes再发送,接着我们需要更新下主界面:

    增加一个line edite命名为txt_send,一个checkbox命名为cb_send,一个发送与接收按钮,分别命名为btn_send、btn_receive.

    我们串口发送的代码已经完成了,那么我们将功能增加到界面中来。

    1、在界面中发送string类型的数据,先更新最新的界面代码,在cmd中输入指令:pyuic5 -o uart.py uart.ui

    接着在uartform.py中增加代码:

    def WriteData(self):

    try:

    msg=self.new.txt_send.text()

    cbcheck=self.new.cb_send.checkState()

    if cbcheck:

    pass

    else:

    self.com.comwritestring(msg)

    except Exception as e:

    self.ShowBox(str(e))

    当cb_send没有被选中的时候,也就是默认发送string类型,如果我要发送hex数据,如:01 ff 00 12这类数据的时候呢?

    我们来实现一个将hex数据转为bytes的代码:

    def HexToBytes(self):

    bl=[]

    try:

    text=self.new.txt_send.text()

    slist=text.split(' ')

    for e in slist:

    b=int(e,16)

    bl.append(b)

    except Exception as e:

    self.ShowBox(str(e))

    return bl

    将发送代码更新为:

    def WriteData(self):

    try:

    slen=0

    msg=self.new.txt_send.text()

    cbcheck=self.new.cb_send.checkState()

    if cbcheck:

    bl=self.HexToBytes()

    slen=self.com.comwritebytes(bl)

    else:

    slen=self.com.comwritestring(msg)

    self.ShowMsg('发送数据长度'+str(slen))

    except Exception as e:

    self.ShowBox(str(e))

    将函数绑定到按钮:self.new.btn_send.clicked.connect(self.WriteData)

    运行一下,不打开串口发送,提示错误:

    打开串口发送string:

    勾选hex,发送:

    提示数据格式错误,接着我们更改数据格式后发送:

    到此为止,串口的数据发送我们已经完成,下一节课将实现串口接收数据。

    展开全文
  • C#通过串口读取和发送数据,简单的串口读取发送数据例子,简单易懂,适合初学者,欢迎下载
  • 基于c51单片机的数据采集串口发送数据到pc的C程序
  • STM32串口发送数据

    万次阅读 多人点赞 2019-05-15 15:35:53
    串口通信经常作为开发调试的工具,所以先介绍下串口通信。 串口通讯(Serial Communication)...目前STM32一般只使用 RXD、TXD 以及 GND 三条信号线,直接传输数据信号。 STM32的串口通信外设有USART和UART。USART是...

    串口通信经常作为开发调试的工具,所以先介绍下串口通信。

    串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。目前STM32一般只使用 RXD、TXD 以及 GND 三条信号线,直接传输数据信号。

    STM32的串口通信外设有USART和UART。USART是Universal Synchronous Asynchronous Receiver and Transmitter的缩写,即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。UART(Universal Asynchronous Receiver and Transmitter)在USART基础上裁减了同步通信功能,只有异步通信。

    接口通过三个引脚从外部连接到其它设备(如以下USART框图所示)。任何 USART 双向通信均需要至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX)。

    RX :接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据。

    TX :发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O用于发送和接收数据(USART 电平下,随后在 SW_RX 上接收数据)。

    TX和RX分别用PA9和PA10。即使用USART1。

    配置串口时,首先要对相应的GPIO口进行初始化,初始化方式和LED灯初始化类似。开启外设时钟,设置端口模式,端口输出类型、输出速度、上下拉、初始输入输出状态。由于USART属于可选功能项,所以两个端口工作模式都为复用功能模式。

    GPIO口配置好后,需要选用复用的功能USART1。

    从图中可以知道USART1属于寄存器GPIOx_AFRH中的AF7。需要在相应GPIO口写入0111。

    接着,设置USART1模式。

    根据寄存器说明,配置为过采样16倍、字长8位、不校验,设置一个停止位,设置波特率,使能发送器和接收器。最后使能USART。

    波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,单位为波特。比特率指单位时间内传输的比特数,单位 bit/s(bps)。对于 USART 波特率与比特率相等。波特率越大,传输速率越快。USART 的发送器和接收器使用相同的波特率。

    波特率计算公式

    其中,f PLCK 为 USART 时钟,OVER8 为 USART_CR1 寄存器的 OVER8位对应的值,USARTDIV 是一个存放在波特率寄存器(USART_BRR)的一个无符号定点数。其中 DIV_Mantissa[11:0]位定义 USARTDIV 的整数部分,DIV_Fraction[3:0]位定义USARTDIV 的小数部分,DIV_Fraction[3]位只有在 OVER8 位为 0 时有效,否则必须清零。

    可通过状态寄存器USART_SR的第七位判断发送数据寄存器是否为空,进行下一步的发送数据。

    这个函数虽然可以发送数据,但只能单个发送,如果想发送一个字符串就要多次调用这个函数,所以把这个函数再进行封装。判断要输出的数是否为‘\0’,如果是,则这个数发送结束,不再进行发送数据。这样就可以一次发送一个完整的字符串了。

    主函数

    usart源文件

    usart头文件

    最终编译后将程序烧入,STM32发送数据,电脑通过串口助手接收到数据,串口发送数据成功。这样以后就可以很方便的进行调试了。      品略图书馆 http://www.pinlue.com/ http://m.pinlue.com/

     

     

     

    展开全文
  • 上篇文章讲述了electron和serialport的环境搭建,以及打包流程,实现了串口通信,本篇,继续上篇,讲述另一个操作,向串口发送数据,因为最近有个需求,需要收银系统,打通设备上的客显设备,于是有了本篇。...
  • python 实现串口发送数据

    万次阅读 2019-07-19 11:04:35
    功能: 发送指定AT命令到设备 实现关机 ''' import serialser def poweroffSchedule(): ser=serial.Serial("COM5",115200,timeout=0.5) ser.write('AT+POWER_OFF\r\n'.encode()) print(ser.readline()); ser....
  • 51单片机 串口发送数据(只是发送)用于调试。 #include <reg51.h> #define uchar unsigned char #define uint unsigned int #define XTAL 11059200 // CUP 晶振频率 #define baudrate 9600 // 通信波特...
  • 使用DMA串口发送数据,UART1发送数据(串口1)1、STM32CubeMX引脚设置和代码生成1.相关定时器的知识点:2.相关参数选择与设置:2、编写相关中断的C文件1.相关串口发送函数:2.相关串口发送函数的编写:3.改进相关...
  • stm32f103串口接收数据发送数组的数据,代码主要在中断函数里,接收到数据后会发送数组中的数据,可以根据要求修改,简单易学,通过了编译
  • 使用STM32F103芯片,通过串口USART1发送数据,复位之后,第一次发送数据时,所发送的数据中第一个数据丢失,之后发送的数据正常。代码是从正点原子STM32F1例程中扒出来的,接收和发送同时使用时,是正常的,只有单独...
  • 实现芯片串口收发数据,按键中断串口发送数据:按下按键,向串口发送数据,并通过虚拟终端显示出来; 串口接收数据中断来控制LED亮/灭:通过串口助手向MCU发送数据,“A”把LED灯点亮,“B”把LED灯熄灭。 led_key.c...
  • 串口发送数据和接收数据,在此作一个简单的Demo.此Demo可以实现按下硬件按钮,灯亮,发送灯状态数据过来。并且可以实现几个灯同时亮,发送灯的状态数据过来。PC端实现点击按钮让硬件灯亮。 此处为4个灯,发送过来...
  • STC8A串口发送数据

    千次阅读 2018-08-25 20:56:24
    上手了一块STC8A8K64S4A12,STC公司推出的... 目前还没使用到高级的功能,只使用了串口功能,上手感觉和51没太大差别。逻辑一致,需要注意的是里面一些寄存器的配置,跟51有些区别,可以在stc-isp下载器那里查询相...
  • 我想用stm32单片机的uart串口发送一个十进制的数据(例如adc转换的电压值)到上位机上面。请问怎么把一个十进制的数字发送出去,这个程序要怎么写。我查了一下资料,好像要发送的数据都要求是二进制的。求大佬
  • 本文档一共整理了六种方案操纵串口数据,希望对大家有所帮助
  • python 用pyserial模块通过串口发送数据的注意点 最近开始在工作中开始边学边用python,其中需要用python实现串口读写,在编程调试过程中发现通过pyserial模块的write方法发送字符串时,数据并没有被发送去到串口...
  • 我们在用串口发送数据的时候首先将待发送的数据/符号转换为对应的ASCII码,然后将这些ASCII码按照二进制的方式一位一位地发送出去。 (注:以下图片来自https://blog.csdn.net/wityy/article/details/8234739) ...
  • 今天主要写一个串口数据发送的应用程序,只专门用来发送数据,具体效果图如下 1.功能要求 发送数据,数据由下拉框进行选择,然后点击按钮进行发送 2.功能实现 (1)上位机界面实现 界面看起来很简单,可以...
  • class UartQThread : public QThread { Q_OBJECT public: UartQThread();...但是run 函数中,循环write 发送数据,对端串口只收到一次, 如果将UartInit放到run 里面初始化,一条也发送不出去,也收不到
  • Qt使用自带类实现串口通信,包括串口发送数据串口的接收数据
  • 最近用stm32编写串口发送程序,在硬件方面需要做如下准备: 1.stm32开发板,这里我的是stm32f030f4p4开发板,单片机的串口发送的引脚为PA9-TX,PA10-RX。 2.为了调试串口,我们需要用到串口调试助手,实现单片机的...
  • 向STM32串口发送数据的标准函数

    千次阅读 2018-06-15 14:03:42
    向STM32串口发送数据的标准函数 例子:1 void UART_Send_Message(u8 *Data,u8 lenth) { while(lenth--) { USART_SendData(USART2, *Data); ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,492
精华内容 39,396
关键字:

串口发送数据

友情链接: ExtiKey.rar