单片机通过如何发送字符串(ASCII转Uint8)

关于printf的知识很零碎,感觉成体系的总结有点麻烦,这里就用列出的方法。

1、printf 与 fputc、putchar…的关系

无论是51还是ARM,都可以在标准输入输出头文件“iostd.h”中找到printf函数;
printf函数可以方便的选择输出的内容,包括字符串,甚至是汉字形式的字符串;
当使用printf函数输出字符串的时候,肯定是一个字节一个字节的输出,而fputc和putchar是printf的子函数,就是用来输出一个字节的;
fputc是STM32里面的,putchar是51里面的,他们都是printf的子函数;
在vc中,使用printf默认输出到当前输出设备——一般是显示屏; 
在单片机里面,可以通过更改putchar函数或fputc函数,自己设定printf输出的方向。

2、通过串口实现高级打印函数printf

很简单,在单片机里面,只需要对putchar函数做出如下定义:

在STM32里面,需要对fputc函数做出如下定义:

很明显,以上工作都是有芯片库的支持,比如printf函数的搭建,定义printf和putchar函数的关系,把字符串变量转换为单个字节,识别%d,%f……等工作的完成。我们不需要关心这个,只要会调整printf函数的方向就好了。
 

还有一个哥们,说用printf实现OLED屏幕的显示很方便;

我们可以想一下这样的话,需要做什么条件: 
1.假如OLED显示屏是SPI或者I2C通信,要在fputc函数中换成响应写一个字节的函数; 
2.它的这个OLED屏要有相应的软件或硬件库,把接收到的字符串按照通信标准(ASCII或者其他)转化为字节;

3、自己写串口打印程序prints

 

prints是自己写的函数,名字是随便取的;

发送之前我们需要了解,当我们用printf发送字符串的时候,我们发送的实际是什么?

英文字符串,发送的其实是ASCII编码对应的十进制序号; 
比如h在ASCII中对应序号为104,那就拿出一个字节,用来发送104; 
由于计算机常用16进制表示,所以在串口助手上会显示“68”; 
实际上,发送的既不是10进制,也不是16进制,而是104表示成8位的二进制代码,一串01而已;

中文的话,会有另外一种编码机制(UCS2?),但这个不重要,我们只要在串口助手里面写上中文,点击16进制发送,就可以得到中文字节,每个中文占两个字节; 
其他和英文字符串没有区别;

使用printf函数,发送的其实是表示字符串的一个个字节,字符串与字节的对应关系就是上面说的,是固定的。

每次发送字符串,发送的都是字符串的表示字节; 
字符串和表示字节之间有转化规则,我们不用知道是什么规则,用指针发送就省去了这个规则——无论什么规则,转化成什么字节,我都可以通过指针寻址找到这些字节,并发送。

比如,我写发送: 
prints(“hello world”);

执行的是: 


其中,“hello world”字符串,作为输入参数,说明字符串其实表示的这个字符串的首地址!

自己写的字符串打印程序,只能输出字符串,不能处理%d,%f等,不能随意设定输出的格式。

原文:https://blog.csdn.net/u013082827/article/details/78087149 

<pre name="code" class="cpp">利用51单片机的串口通信,发送字符串
 
代码如下(模块函数):
 
void main()
{
    UartInit();
    SendString("finish!");
    while(1);
}

void  SendString(unsigned char *p)
{
    while(*p)
    {
        SendChar(*p); 
        p++;
    }
}
 
void SendChar(unsigned char Char)
{
    SBUF=Char;  
    while(!TI);  
    TI=0;
}
 
/*UART.C*/
#include "REG52.H"
sfr AUXR  = 0x8E; 
void UartInit(void)		//9600bps@11.0592MHz
{
    PCON &= 0x7F;		//波特率不倍速
    SCON = 0x50;		//8位数据,可变波特率
    AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
    AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
    TMOD &= 0x0F;		//清除定时器1模式位
    TMOD |= 0x20;		//设定定时器1为8位自动重装方式
    TL1 = 0xFD;		//设定定时初值
    TH1 = 0xFD;		//设定定时器重装值
    ET1 = 0;		//禁止定时器1中断
    TR1 = 1;		//启动定时器1
}

 

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的单片机c51程序,用于16×16点阵显示收到的ASCII码的字符串。请注意,这只是一个示例,具体的实现方式可能因点阵屏幕型号、通信方式等因素而有所不同。 ```c #include <reg52.h> #define uchar unsigned char #define uint unsigned int // 定义点阵显示的缓存数组 uchar code Tab[]={ // 点阵数据 }; // 定义点阵屏幕的行数和列数 #define ROW 16 #define COL 16 // 定义串口通信相关的寄存器 sfr SCON = 0x98; sfr TMOD = 0x89; sfr TH1 = 0x8D; sfr TL1 = 0x8B; // 定义延时函数,用于控制点阵显示速度 void delay(uint ms) { uint i, j; for(i=0; i<ms; i++) for(j=0; j<125; j++); } // 初始化串口通信模块 void InitUART() { SCON = 0x50; TMOD &= 0x0F; TMOD |= 0x20; TH1 = 0xFD; TL1 = 0xFD; TR1 = 1; } // 通过串口接收ASCII字符串,并换为点阵数据后显示 void main() { InitUART(); while(1) { uchar buf[32]; uchar i, j, k; uchar ch; // 等待串口接收到完整的ASCII字符串 while(RI == 0); RI = 0; // 将收到的ASCII字符串换为点阵数据 for(i=0; i<16; i++) { ch = buf[i]; for(j=0; j<16; j++) { Tab[i*16+j] = code[(ch-32)*16+j]; } } // 逐行显示点阵数据 for(i=0; i<ROW; i++) { for(j=0; j<COL; j++) { for(k=0; k<8; k++) { if(Tab[i*16+j] & (1<<k)) P1 = 0; else P1 = 1; } delay(1); // 延时1ms,控制显示速度 P1 = 1; // 关闭点阵屏幕 } } } } ``` 请注意,以上代码只是一个示例,具体的实现方式可能因点阵屏幕型号、通信方式等因素而有所不同。在实际应用中,请根据具体情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值