串口发送接收字符串
单片机串口通信的发送与接收(可编辑修改word版)
51 单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。
当串行发送完毕后,将在标志位TI 置1,同样,当收到了数据后,也会在RI 置1。
无论RI 或TI 出现了1,只要串口中断处于开放状态,单片机都会进入串口中断处理程序。
在中断程序中,要区分出来究竟是发送引起的中断,还是接收引起的中断,然后分别进行处理。
看到过一些书籍和文章,在串口收、发数据的处理方法上,很多人都有不妥之处。
接收数据时,基本上都是使用“中断方式”,这是正确合理的。
即:每当收到一个新数据,就在中断函数中,把RI 清零,并用一个变量,通知主函数,收到了新数据。
发送数据时,很多的程序都是使用的“查询方式”,就是执行while(TI ==0); 这样的语句来等待发送完毕。
这时,处理不好的话,就可能带来问题。
看了一些网友编写的程序,发现有如下几条容易出错:1.有人在发送数据之前,先关闭了串口中断!等待发送完毕后,再打开串口中断。
这样,在发送数据的等待期间内,如果收到了数据,将不能进入中断函数,也就不会保存的这个新收到的数据。
这种处理方法,就会遗漏收到的数据。
2.有人在发送数据之前,并没有关闭串口中断,当TI = 1 时,是可以进入中断程序的。
但是,却在中断函数中,将TI 清零!这样,在主函数中的while(TI ==0);,将永远等不到发送结束的标志。
3.还有人在中断程序中,并没有区分中断的来源,反而让发送引起的中断,执行了接收中断的程序。
对此,做而论道发表自己常用的方法:接收数据时,使用“中断方式”,清除RI 后,用一个变量通知主函数,收到新数据。
发送数据时,也用“中断方式”,清除TI 后,用另一个变量通知主函数,数据发送完毕。
这样一来,收、发两者基本一致,编写程序也很规范、易懂。
更重要的是,主函数中,不用在那儿死等发送完毕,可以有更多的时间查看其它的标志。
实例:求一个PC 与单片机串口通信的程序,要求如下:1、如果在电脑上发送以$开始的字符串,则将整个字符串原样返回(字符串长度不是固定的)。
51串口 发送字符串 源程序
bit read_flag=0;
void init_serialcomm(void)
{
SCON = 0x50; //SCON: 方式1, 8-bit UART
TMOD |= 0x20; //TMOD: timer 1,方式2, 8-bit 自动重装
PCON |= 0x80; //SMOD=1;
TH1 = 0xF4; //波特率:4800 11.0592MHz
IE |= 0x90; //开中断
TR1 = 1; //开定时器1
// TI=1;
{
unsigned int k=0;
do
{
send_char_com(*(str + k));
k++;
} while(k < strlen);
}
//串口接收中断函数
void serial () interrupt 4 using 3
send_string_com(inbuf1,INBUF_LEN);
}
}
}
/*通信协议:第1字节,MSB为1,为第1字节标志,第2字节,MSB为0,为非第一字节标志,其余类推……,最后一个字节为前几个字节后7位的异或校验和。
测试方法:可以将串口调试助手的发送框写上 95 10 20 25,并选上16进制发送,接收框选上16进制显示,如果每发送一次就接收到95 10 20 25,说明测试成功。
}
main()
{
init_serialcomm(); //初始化串口
while(1)
{
stm32串口发送字符串STM32串口发送注意问题
stm32串口发送字符串STM32串口发送注意问题导读:就爱阅读网友为您分享以下“STM32串口发送注意问题”资讯,希望对您有所帮助,感谢您对的支持!使用stm32f10x调试串口通讯时,发现一个出错的现象,硬件复位重启之后,发送测试数据0x01 0x02 0x03 0x04..接收端收到的数据为:0x02 0x03 0x04,第一个数据丢失。
换成发送别的数值的数据,如0x06 0x0ff,则接收到0x0ff,0x06丢失。
错误依旧。
故障排除过程:1、刚开始怀疑是接收端的错误,我是使用电脑串口,运行串口辅助调试工具接收,换成其他软件后,发现故障依旧,而且电脑软件一直是开启状态,不像和电脑软件有关。
2、使用单步调试,单步运行各个发送指令,都正常。
能收到0x01 0x02 0x03 0x04的数据。
间接的排除了不是电脑软件的问题,而是其他的错误。
3、单步调试运行虽然正常了,但连续运行时,错误依旧。
现在有点摸不到头绪了,单步运行正常,看起来编程没有出错,那故障在哪里呢?测试程序如下USART_SendData(USART2, 0x01); //Awhile(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET); //BUSART_SendData(USART2, 0x02); //Cwhile(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);USART_SendData(USART2, 0x03);while(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);USART_SendData(USART2, 0x04);while(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);4、猜测,也许是因为某个特殊原因,使第二个数据覆盖了首个数据,使得首个数据丢失。
串口调试助手的十六进制发送与字符串发送
串口调试助手的十六进制发送与字符串发送
串口调试助手的十六进制发送与字符串发送
两天调试一个zigbee模块,要求命令要求使用16进制格式发送给模块。
用串口助手的16进制发送功能控制zigbee,换单片机发送怎么试都不好用,只知道是数据格式转换有问题,一直没搞明白串口助手的16进制发送是怎么发的,直到网上看到一篇文章,下边直接复制过来了。
在使用串口发送数据时可以选择字符串发送或者十六进制发送,通常情况下我们习惯选用字符串发送数据。
关于两者的区别,需要从计算机存储数据的格式说起。
在计算机中,数据是以二进制的形式存储的,例如十进制1(10)在计算机中用0000 0001(2)来表示。
我们在用串口发送数据的时候首先将待数据转换为对应的ASCII码,然后再将这些ASCII码按照二进制的方式一位一位的发送出去。
例如我们要发送一串数据“A852010100000000A91A”,以字符串和十六进制两种方式发送:
(1)字符串发送
串口以字符串发送数据,首先将字符串转化为二进制,格式如下:
然后按照8位(串口设置数据位为8位)形式将数据发送出去。
串口接收的数据格式如下:。
51串口发送字符串
51串⼝发送字符串刚开始也是⼀直乱码,直到昨天我才解决了乱码的问题,原来这⼀切都是晶振频率惹的祸,今天开始不会乱码了。
可以发送单个字符了。
但是⼜出现了⼀个新的问题,⼀个很长的字符串怎么办?很多⼈想,那好办啊,下⾯这个程序就可以:/*发送⼀个字符串*/void send_string(uchar *p){while(*p!= '\0'){send_byte(*p);p++;}}这样不就可以实现字符串的发送了吗?是的,没错,但是在send_byte()这个函数⾥⾯该怎么写?其实这个函数写不好很容易和中断函数冲突。
当然,你可以这样写:/*发送⼀个字符*/void send_byte(uchar by){SBUF = by;while(!TI);//等待发送完毕TI = 0;}如果你这样写了,那么你要么不要打开串⼝中断,要么就在串⼝中断⾥⾯什么都不写(如果你只是发送,不接收的话),这⾥只是讲发送,接收是⼀个道理的。
如果你在中断函数⾥⾯写了下⾯这样的程序:void uart_interrupt() interrupt 4{if(RI==1)RI = 0;if(TI==1)TI = 0;}那么,恭喜你,你不会在电脑端收到任何数据的(不对,你能收到字符串的第⼀个字符)。
原因很简单:当⼀个字符发送/接收完毕的时候,发送/接收标志位TI/RI会⾃动置1,如果你在初始化⾥⾯打开了串⼝中断的话,程序⼀定进⼊中断函数⾥⾯去执⾏:if(TI==1)TI = 0;⽽不是先执⾏while(!TI);//等待发送完毕,所以,在中断⾥⾯TI⼜置了0,然后回到while(!TI);这样,就陷⼊了⼀个死循环。
你的程序就卡在这⾥了。
总结:当你发现⽆法发送字符串的时候,⾸先检查⾃⼰的⽐特率是否对,就是检查能不能发送单个字符,如果单个字符发送没有问题,那么⼀定能发送字符串。
接下来检查你的初始化程序中有没有打开串⼝中断。
如果打开,看中断函数有没有和单个字符发送函数冲突。
7Zigbee实验报告《串口通讯-发送字符串》
签字: 年 月 日
相关寄存器:
,相关寄存器UxCSR, UxCSR, UxGCR. UxBUF, UxBAUD, CLKCONCMD,CLKCONSTA如
第二页
实验内容与步骤
实验步骤
第三页
实验内容与步骤
CC2530配置串口的一般步骤:1、配置10,使用外部设备功能。此处配置PO-2和Po3用作串口UARTO2、配置相应串口的控制和状态寄存器。3、配置串口工作的波特率。
2019——2020学年第二学期
专业
班级
讯-发送字符串
实验目的
1)、通过实验掌握CC2530芯片串口配置与使用
2)、观察D2串口发送指示灯的变化,每发送一串字符闪一次
注:嵌入式开发中,当程序能跑起来后,串口是第一个要跑起来的设备,所有的工作状态,交互信息都会从串口输出
实验总结
该实验完成串口的基本通讯。在串口通讯中一般有两种方式来接受数据种是查询法、一种是中断法。查询法就是要串口一致处于等待状态,看串口上是不是有数据,一旦数据接收完毕,就开始对接收的数据进行相应的操作。这个方法需要让程序一致等待串口,所以这种方法效率还是比较低的。中断法师运用串口的中断服务子程序来完成的,如果串口上有数据的话,那么会调用中断向量,中断向量把程序指针指到相应的中断服务服务程序上。在中断服务程序完成之后程序只能还会跳转到中断之前的地址。这个方法的效率比较高,但是从稳定性上面讲,这种方法不如查询法。本实验用的是中断法。
实验内容与步骤
实验内容:
相关电路图:
注:图中OR的电阻是空贴的哦
PO 2,PO 3配置为外设功能时: PO2为Rx, PO3为TX. USARTO和USART1是串行通信接口,它们能够分别运行于异步UART模式或者同步SPI模式。两个USART具有同样的功能,可以设置在单独的1/0引脚。此种串口设计是没有流控功能的
串口接收字符串技巧
串口接收字符串技巧串口接收字符串,就像是在一个神秘的信息通道口守着,等着一串串神秘的字符像小蚂蚁排队一样一个接一个地进来。
这可不是个简单事儿,里面的门道可多啦。
咱先说说这个串口的设置。
串口就像一个小管家,你得告诉它一些规则,它才能好好地接收字符串。
比如说波特率,这就好比是小蚂蚁们走路的速度。
如果波特率设置错了,那就像小蚂蚁们不是按照正常速度走,有的走得太快,有的走得太慢,那接收到的字符串肯定是乱七八糟的。
我就曾经遇到过这个问题,当时怎么都接收不对字符串,就像在跟一个外星人对话,完全不明白对方在说啥。
后来才发现是波特率这个小调皮鬼捣的乱。
再说说数据位和停止位。
这两个东西啊,就像是小蚂蚁队伍的编排规则。
数据位决定了每次过来的字符的长度,停止位就像是队伍末尾的小旗帜,表示这个字符已经传输完了。
要是这两个没设置好,就像小蚂蚁队伍没有排整齐,东倒西歪的,接收的字符串也会出错。
这就好比你在数一群排得歪歪扭扭的小蚂蚁,数着数着就乱套了。
接收缓冲区也很重要。
这个缓冲区就像是一个小仓库,用来暂时存放接收到的字符串。
要是这个小仓库太小了,就像一个小盒子装不了太多小蚂蚁,有些字符串就可能会丢失。
我有次做一个小项目,没注意这个缓冲区的大小,结果就像一个粗心的孩子丢了自己心爱的玩具一样,好多字符串都没接收到,可把我急坏了。
在接收字符串的时候,还得注意字符的编码格式。
这就像是小蚂蚁们身上的标记。
不同的编码格式下,同样的字符看起来可能是不一样的。
如果不搞清楚这个,就像认错了小蚂蚁身上的标记,把原本是“朋友”的小蚂蚁当成了“敌人”。
比如说ASCII码和UTF - 8编码,它们就像两种不同的语言,如果搞混了,接收到的字符串解读出来可能就是一堆乱码,就像看天书一样,完全不知道是什么意思。
那怎么知道接收到的字符串是完整的呢?这就像等小蚂蚁们全部排好队一样。
有时候,我们可以通过特定的结束标志来判断。
就像小蚂蚁队伍最后有一个特殊的小蚂蚁表示队伍结束了。
Arduino串口接收字符串
Arduino串口接收字符串用惯Arduino串口传输的朋友都知道,Arduino的Serial.read()每次只能读一个字节,但是有时想进行字符串通讯,就很麻烦了。
废话少讲,直接上完整例子:编译只要一块Arduino,不需要任何外置元件。
用Arduino编译器的串口监视器即可看到结果,我们打什么文字进去,下面就会返回什么文字。
String comdata = "";void setup(){Serial.begin(9600);}void loop(){while (Serial.available() > 0){comdata += char(Serial.read());delay(2);}if (comdata.length() > 0){Serial.println(comdata);comdata = "";}}代码很简单,comdata是一个字符串类型变量。
Serial.available()是当前串口缓冲池的数据量。
Serial.read()是读缓冲池的语句,每次只能读一个字节。
用了String类型变量,很简单的实现了字符到字符串的加入,还有字符串输出,赋值等麻烦问题,所以很简单的代码就能处理串口数据。
特别留意的是读串口时的delay(2)不能删掉,否则串口缓冲区不够时间接受数据。
即使调小延时也会出错。
具体数值也可以实验决定。
再提醒一个:comdata说是一个字符串,也是一个数组,引用每个字的话可以用comdata[0],comdata[1]。
comdata[n]。
如果我们要每个字节取出的话,可以每个引用。
效果:输入什么字符串,输出就是什么。
输入:按send之后:再附送一个例子,在串口输入1011101..的话,就会令Arduino的D2~Dx引脚产生高/低电平,当然,一次发送的数据视Arduino引脚数而定,比如Arduino UNO/nano之类的,只有D2~D13十二个引脚。
STM32串口发送字符串的几种写法
STM32用USART发送字符串
代码含义是:当接收引脚有数据时,状态寄存器的USART_FLAG_RXNE就会为1,此时USART_GetFlagStatus(USART1,USART_FLAG_RXNE)的返回值就为1(SET),若无数据则为RESET。
代码常见写法,及其接收数据效果
1
这种写法在不是特殊(不掉电、不待机等)情况下,问题不大,USART数据会成功发送出去。
但是在上面说的特殊情况下,问题就来了,代码只将数据放到了发送缓冲区,而没有发送出去就掉电或待机了,这个时候其实最后两个字符是没有发送出去的。
2
这种写法达到的效果和上面存在不同的就是倒数第二个数据发送出去了,也就是只有最后一个字符是没有发送出去的。
3
这种写法达到的效果和上面两种写法有不一样,发送了10个字符。
4
这种写法按理说可以实现功能,但实际多次试验结果确实第一字节数据丢失了。
5
这种写法是比较完成,为了保守起见,在特殊情况下使用该写法。
单片机实现接收从电脑发送过来的字符串的方法
rw=0;
rs=1;
P2=dat;
delay1ms(1);
e=1;
delay1ms(1);
e=0;
}
void lcd_int(void)
{
rw=0;
e=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x80);
for(i=0;i<f;i++)
for(j=0;j<120;j++);
}
void receivem(void)
{
while(RI==1)
{
if(k==32){k=0;}
receive[k]=SBUF;
RI=0;
k++;
}
}
void timer_int(void)
{
TMOD=0x11;//00010001
for(i=16;i<k;i++)
{
write_data(receive[i]);
}
}
}
void main()
{
timer_int();
lcd_int();
write_com(0x01);
while(1)
{dis();}
}
//1602实时显示单片机串口接收到电脑串口发送的字符串
//波特率600bps由T2中断产生,晶振12M
//最高等级中断T0负责定时查询串口输入SBUF
//接线注释:
uart发送和接收字符串(可proteus仿真)
//此程序主要用于uart发送字符和字符串(proteus终端不能显示汉字,但串口助手可以),输入换行符结束#include<reg52.h>void uart_init(void);//串行口初始化unsigned char getbyte(void);void sendbyte(unsigned char c);void sendstring(unsigned char *string);void getstring(unsigned char *string);int main(void){unsigned char c,string[100];uart_init();while(1){//发送字符c=getbyte();sendbyte(c);//换两行sendbyte('\r');//'\r'为终端换行符sendbyte('\r');//发送字符串getstring(string);sendstring(string);}return 0;}void uart_init(void){TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2TH1=0xfd;//设置波特率为9600TL1=0xfd;TR1=1;//启动定时器/计数器1SCON=0x50; //0101 0000.串口工作方式1,允许串行控制PCON=0x00;//设置SMOD=0IE=0X90; //CPU允许中断,串行允许中断}void sendbyte(unsigned char c){SBUF=c;while(!TI);//等待发送完成TI=0;}unsigned char getbyte(void){unsigned char c;while(!RI);//等待接收器不忙c=SBUF;RI=0;return c;}void sendstring(unsigned char *string)//此处*string相当于数组{while(*string!='\0')//判断是否到字符串末尾{sendbyte(*string);string++;}}void getstring(unsigned char *string)//读取字符串存入string中{while( (*string=getbyte()) !='\r')//换行符结束输入{string++;}}下面是proteus仿真图(虚拟终端不能发送和显示汉字,但串口助手可以)。
stm32串口接收字符串经验
stm32串口接收字符串经验/jishu_578041_1_1.html2016分享一个stm32的串口就收字符串以十六进制数解析的程序。
好多朋友在用stm32写串口接收的时候说用串口发送数据的时候有丢失的现象,或者发送的数据与接收的数据不一样,比如发送01 串口接收到的是40。
还有好多好多的不明现象。
今天就和大家讨论一下这些问题是怎么出现的。
在调试串口通信的时候首先要确定硬件是好用的,大家应该都用的是开发板所以硬件部分应该是没问题的。
如果是最小系统的话要缺定外接串口模块是不是好的也就是rs3232,如果串口不好使,程序在对也是没用的,再有就是关于电平的问题,在这里说几个芯片就是rs3232芯片和ch340芯片这两个芯片大家都很熟悉了专业性的知识咱就不复i述了,为什么要说这两个芯片呢。
因为有的童鞋的板子上没有板载rs3232的芯片,所以直接将九针串口线的的2、3、5引脚直接接到单片机上了,所以出现可上述发送01收到的是40的情况,这种接是错误的要将串口线接到rs3232的串口上才能开始调试。
硬件部分就这些,注意一下就行,下面说说软件部分的在写串口程序是首先要配置串口的初始化我直接贴出程序再说,#include "pbdata.h"uint8_t TxBuffer1[] = "USART Interrupt Example: This isUSART1 DEMO";uint8_t RxBuffer1[],rec_f,tx_flag;volatile uint8_t TxCounter1 = 0x00;volatile uint8_t RxCounter1 = 0x00; uint32_tRec_Len;int main(void){ u8 a=0;RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration();USART_Config(USART1); while(1) { if(rec_f==1){rec_f=0; USART_OUT(USART1,&TxBuffer1[0]);if(a==0){GPIO_SetBits(GPIOA, GPIO_Pin_2); a=1;}else{GPIO_ResetBits(GPIOA,GPIO_Pin_2);a=0; } }}}这是主函数部分,在主函数中只有几个函数的初始化,还有就是定义的数组和标志位。
(完整版)c51单片机从串口接收发送字符串
c51单片机从串口接收发送字符串#include 〈reg52。
h>#define uchar unsigned char#define uint unsigned intuchar data table[10]; //暂存数组,可以将10改为你需要的数值/***********************************************串行口初始化波特率9600,定时器1,工作方式2 *************************************************/void serial_init(void){TMOD=0x20;//计时器1作为比特率发生器,方式2TH1=0xfd;TL1=0xfd; //装入初值TR1=1;//计时中断允许SM0=0;SM1=1;//串行口工作于方式2ES=1;//串行口中断允许REN=1;//接收允许EA=1;// 总中断允许}/***********************************************串行口传送数据传送显示数组各字符给计算机*************************************************/void send(uchar *dis){while(*dis!='\0’){SBUF=*dis;dis++;while(!TI);TI=0; //软件请发送中断}}void main(){serial_init();//初始化while(SBUF!=0x0d);//计算机键盘按下回车键,则开始将接收到的数据回传给计算机send(table);}/***********************************************串行中断服务函数单片机接收数据,存入table数组*************************************************/ void serial() interrupt 4{int i;ES=0; //关串口中断table[i++]=SBUF;//命令存到命令数组RI=0; //软件清除接收中断ES=1;//开串口中断}已经通过proteus仿真如下。
8266串口发送和接收数据的一般方法
一、概述在嵌入式系统开发中,串口通信作为一种常见的通信方式,广泛应用于各种嵌入式设备中。
ESP8266芯片作为一款性能稳定、功能强大的芯片,其串口发送和接收数据的方法备受开发者关注。
本文将介绍8266串口发送和接收数据的一般方法,帮助开发者更好地理解和应用串口通信。
二、串口发送数据的一般方法1. 打开串口在使用8266芯片进行串口通信之前,首先需要打开串口。
通过调用串口初始化函数,设置波特率、数据位、停止位和校验位等参数,可以成功打开串口。
2. 准备发送数据在串口发送数据之前,需要准备好待发送的数据。
可以将需要发送的数据存储在一个数组中,或者直接在程序中定义发送的字符串。
3. 发送数据通过调用串口发送函数,将数据发送到指定的串口设备上。
发送函数需要传入待发送的数据和数据长度等参数,以确保数据能够被成功发送。
4. 关闭串口在数据发送完成后,需要及时关闭串口以释放资源。
通过调用串口关闭函数,可以关闭打开的串口设备,避免资源浪费和冲突。
三、串口接收数据的一般方法1. 打开串口与数据发送类似,串口接收数据之前也需要先打开串口。
通过调用串口初始化函数,设置相应的参数,可以成功打开串口。
2. 接收数据通过调用串口接收函数,可以从串口设备中接收数据。
接收函数需要传入接收数据的缓冲区和接收数据长度等参数,以确保数据能够被成功接收。
3. 处理接收数据接收到数据后,需要对数据进行相应的处理。
可以根据数据的格式和内容进行解析、存储或者其他操作。
4. 关闭串口在数据接收完成后,同样需要及时关闭串口以释放资源。
通过调用串口关闭函数,可以关闭打开的串口设备,避免资源浪费和冲突。
四、总结本文介绍了8266串口发送和接收数据的一般方法。
通过打开串口、准备发送/接收数据、发送/接收数据以及关闭串口等步骤,可以实现串口通信的基本功能。
开发者可以根据具体的应用场景和需求,结合8266芯片的特性和功能,灵活地应用串口通信,实现各种嵌入式系统中的数据传输和交互。
(完整版)单片机串口接收发送并显示字符串
#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit rs=P2^5; //命令/数据选择sbit rw=P2^4; //读写口sbit e=P2^3; //锁存控制uchar data table[32]; //暂存数组,可以将10改为你需要的数值/***********************************************串行口初始化波特率9600,定时器1,工作方式2*************************************************/void serial_init(void){TMOD=0x20;//计时器1作为比特率发生器,方式2TH1=0xfd;TL1=0xfd; //装入初值TR1=1;//计时中断允许SM0=0;SM1=1;//串行口工作于方式2ES=1;//串行口中断允许REN=1;//接收允许EA=1;// 总中断允许}/********************* **************************串行口传送数据传送显示数组各字符给计算机*************************************************/void send(uchar *dis){while(*dis!='\0'){SBUF=*dis;dis++;while(!TI);TI=0; //软件请发送中断}}//*************************************************************************************** ***********//延时函数//*************************************************************************************** ***********void delay(uint time) //int型数据为16位,所以最大值为65535{uint i,j; //定义变量i,j,用于循环语句for(i=0;i<time;i++) //for循环,循环50*time次for(j=0;j<100;j++); //for循环,循环50次}//*************************************************************************************** ***********//向LCD写一命令//*************************************************************************************** ***********void wcode(uchar t){rs=0; // 写的是命令rw=0; // 写状态e=1; //使能P0=t; //写入命令delay(20); //等待写入,如果时间太短,会导致液晶无法显示e=0; //数据的锁定}//*************************************************************************************** ***********//向LCD写一数据//*************************************************************************************** ***********void wdata(uchar t){rs=1; // 写的是数据rw=0; // 写状态e=1; //使能P0=t; //写入数据delay(20); //等待写入,如果时间太短,会导致液晶无法显示e=0; //数据的锁定}//*************************************************************************************** ***********//LCD显示第一行//**************************************************************************************************void xian1(){uchar i;wcode(0x80); //设置第一行显示地址for(i=0;i<16;i++) //循环16次,写完1行{wdata(table[i]); //写入该行数据}}//*************************************************************************************** ***********//LCD显示第二行//*************************************************************************************** ***********void xian2(){uchar i;wcode(0xc0); //设置第二行显示地址for(i=16;i<33;i++) //循环16次,写完1行{wdata(table[i]); //写入该行数据}}//*************************************************************************************** ***********//LCD 初始化//*************************************************************************************** ***********void InitLCD(){wcode(0x01); //清屏wcode(0x06); //输入方式控制,增量光标不移位wcode(0x0e); //显示开关控制wcode(0x38); //功能设定:设置16x2显示,5x7显示,8位数据接口}//*************************************************************************************** ***********//主函数//*************************************************************************************** ***********void main(){。
CC2530UART串口实验1(UART0串口发送字符串)
/*****************************************
//by 虚幻代码
//说明:从CC2530 上通过串口不断发送字符串到PC 端,实验使用UART0,波特率为19200
*****************************************/
{
intj;
for(j=0;j<len;j++)
{
U0DBUF=*data++;
while(UTX0IF==0);
UTX0IF=0;
}
}
chartxdata[25]="start transmit:\n";
//主函数
voidmain(void)
{
//初始化LED
P1DIR=0X03;
rled=1;
gled=1;
//初始化串口
CLKCONCMD&=0XBF;//系统时钟为32MHZ
while(CLKCONSTA&0X40);//等待时钟稳定
CLKCONCMD&=0XF8;//主时钟频率为32MHZ
PERCFG&=0XFE;//设USART0的ALT 1
P0SEL|=0X3C;//P0口2、3、4、5做外设
P2DIR&=0X3F;//P0外设优先级USART0最高
U0CSR|=0X80;//设USART0 工作方式为 UART
U0GCR|=9;
U0BAUD|=59;//设波特率
UTX0IF=0;//UART0 TX中断标志位清0
//传送字符串
uarttx_send_string(txdata,25);
串口接收字符串程序
入口参数:无
返回:无
备注:无
******************************************************/
void UartISR(void) interrupt 4
{
if(RI)
{
RI=0;
st[i++]=SBUF;//把电脑串口发送到缓冲区的数据保存到数组
if(num==10000&&flag==0)
//如果延时一段时间后,标志位还是为0,说明没有接收到数据,可以进行数据输出
{
num=0;
for(x=0;x<i;x++) //i变量是接收到的字节数
{
Sending=1; //设置发送标志
SBUF=st[j缓存,让电脑串口显示出来
#define uchar unsigned char
#define Fclk 11059200UL //晶体频率
#define BitRate 9600UL //波特率
uchar st[100]; //保存串口数据的缓冲区数组,如果想接收更多的字符可创建多个数组
volatile uchar Sending;
static uchar i=0;
uchar flag;
/****************************************************
函数功能:串口初始化
入口参数:无
返回:无
备注:无
*****************************************************/
TL1=256-Fclk/(BitRate*12*16);
串口接收字符串[技巧]
串口接收字符串串口接收字符串.txt22真诚是美酒,年份越久越醇香浓型;真诚是焰火,在高处绽放才愈是美丽;真诚是鲜花,送之于人手有余香。
一颗孤独的心需要爱的滋润;一颗冰冷的心需要友谊的温暖;一颗绝望的心需要力量的托慰;一颗苍白的心需要真诚的帮助;一颗充满戒备关闭的门是多么需要真诚这一把钥匙打开呀!//串口接收以特定字符为开头的字符串并且保存特定字符之后的有效位#include<reg52.h>#define uint unsigned char#define uchar unsigned intuchar ser_receive; //串口接收到的数据uchar ser_flag=0;uchar receive_number[11]={0};//接收串口发送来的数据的数组uchar i=0;uchar j;uchar come=0;void init_ser(){TMOD=0X20;//定时器1工作在方式2TH1=0XFD;TL1=0XFD; //波特率9600TR1=1;EA=1;SM0=0;SM1=1;REN=1;//允许串口接收ES=1;//开串口中断}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/********************************************************** ******************************* 程序目的:串口接收字符串,但是要以字符a为开头的后面的11位字符,若开头不为a则接收不写入数组* 若开头为a 但是发送有效位超过11位就把后面的截断只要前11位**补充:该程序也可以改为接受任意字符串 (但是字符串的长度必须是大体确定的)************************************************************* *****************************/void ser() interrupt 4 //中断函数不用声明{if(RI==1){RI=0;ser_receive=SBUF;if(come==1){if(ser_receive!='\0'&&ser_receive!='a'){receive_number[i]=ser_receive;i++;if(i==11){i=0;ser_flag=1;come=0;}}}else if(ser_receive=='a'){come=1;}}}void main(){init_ser();while(1){if(ser_flag==1){ES=0;ser_flag=0;for(j=0;j<11;j++){SBUF=receive_number[j];while(!TI);TI=0;delay(10);}ES=1;}}}/////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////下面程序接收字符串(不用特定字符开头)/////////////////////////////////////////////////////////// ////////////////下面程序接收字符串(不用特定字符开头)/////////////////////////////////////////////////////////// /////////////////下面程序接收字符串(不用特定字符开头)/////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////#include<reg52.h>#define uint unsigned char#define uchar unsigned intuchar ser_receive; //串口接收到的数据uchar ser_flag=0;uchar receive_number[12]={0};uchar i=0;uchar j;void init_ser(){TMOD=0X20;//定时器1工作在方式2TH1=0XFD;TL1=0XFD; //波特率9600TR1=1;EA=1;SM0=0;SM1=1;REN=1;//允许串口接收ES=1;//开串口中断}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void ser() interrupt 4 //中断函数不用声明{if(RI==1){RI=0;ser_receive=SBUF;if(ser_receive!='\0'){receive_number[i]=ser_receive;i++;if(i==12){i=0;ser_flag=1;}}}}void main(){init_ser();while(1){if(ser_flag==1){ES=0;ser_flag=0;for(j=0;j<12;j++){SBUF=receive_number[j];while(!TI);TI=0;delay(10);}ES=1;}}}。
stm32串口接收字符串经验
stm32串口接收字符串经验/jishu_578041_1_1.html2016分享一个stm32的串口就收字符串以十六进制数解析的程序。
好多朋友在用stm32写串口接收的时候说用串口发送数据的时候有丢失的现象,或者发送的数据与接收的数据不一样,比如发送01 串口接收到的是40。
还有好多好多的不明现象。
今天就和大家讨论一下这些问题是怎么出现的。
在调试串口通信的时候首先要确定硬件是好用的,大家应该都用的是开发板所以硬件部分应该是没问题的。
如果是最小系统的话要缺定外接串口模块是不是好的也就是rs3232,如果串口不好使,程序在对也是没用的,再有就是关于电平的问题,在这里说几个芯片就是rs3232芯片和ch340芯片这两个芯片大家都很熟悉了专业性的知识咱就不复i述了,为什么要说这两个芯片呢。
因为有的童鞋的板子上没有板载rs3232的芯片,所以直接将九针串口线的的2、3、5引脚直接接到单片机上了,所以出现可上述发送01收到的是40的情况,这种接是错误的要将串口线接到rs3232的串口上才能开始调试。
硬件部分就这些,注意一下就行,下面说说软件部分的在写串口程序是首先要配置串口的初始化我直接贴出程序再说,#include "pbdata.h"uint8_t TxBuffer1[] = "USART Interrupt Example: This isUSART1 DEMO";uint8_t RxBuffer1[],rec_f,tx_flag;volatile uint8_t TxCounter1 = 0x00;volatile uint8_t RxCounter1 = 0x00;uint32_t Rec_Len;int main(void){u8 a=0;RCC_Configuration();NVIC_Configuration();GPIO_Configuration();USART_Config(USART1);while(1){if(rec_f==1){rec_f=0;USART_OUT(USART1,&TxBuffer1[0]);if(a==0){GPIO_SetBits(GPIOA, GPIO_Pin_2); a=1;} else{GPIO_ResetBits(GPIOA, GPIO_Pin_2);a=0; }}}}这是主函数部分,在主函数中只有几个函数的初始化,还有就是定义的数组和标志位。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
RI = 0; //清除RI接受中断标志
ReData = SBUF; //SUBF接受/发送缓冲器。单片机会自动串口接收寄存器中的数据取走给SenData
SenData=ReData;
while(TI==0);
TI=0; // 清除数据传送标志
}
}
}
void ser_int (void) interrupt 4 //中断接收上位机发送的字符
{
TR1 = 1; //开启定时器1
ES = 1; //开串口中断
EA = 1; // 开总中断
P2=~SenData;//将数据以二进制形式显示在P2口
markde=1; //如果接收到数据 标志位=1,以方便在主程序中查询判断是否已经收到数据
}
}
/**************************************************
P1=0x7f;
P0=table[SenData/100];
delay(4);
P1=0xbf;
P0=table[SenData%100/10];
delay(4);
P1=0xdf;
P0=table[SenData%10];
{
init();
while(MESSAGE[a] != '\0')
{
SBUF = MESSAGE[a]; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
//单片机自动将 MESSAGE[a]里的字符发送到上位机
if (markde==1) //说明程序已经执行过串口中断服务程序
{ markde=0; //清除标志
SBUF=SenData; //单片机将接收到的数据发送给上位机 并且显示在上位机的接收区
while(!TI); // 等特数据完毕 传送标志
a++; // 下一个字符
}
while(1)
{ a=0;
//display(); //数码管前三位以十进制显示数据,最后二位以十六进制显示数据
}
void display()
{
P1=0xfe;
P0=table[SenData%16];
delay(4);
P1=0xfd;
P0=table[SenData/16];
delay(4);
for(m=k;m>0;m--)
for(n=110;n>0;n--);
}
void init()
{
SCON = 0x50; //REN=1允许串行接收,串口工作模式2
TMOD= 0x20; //定时器1工作方式2 8位初值自动重装的8位定时器/计数器
方/32*T1的溢出率,如果SMOD=0,9600=1/32/((256-N)*1us)得N=253,它的十六进制是0xFD 但
是如果SMOD=1, 9600=2/32/((256-N)*1us)得N=250,可见再不变化N的情况下SMOD由0变为1,
波特率便增加一倍。*/
unsigned char code table3[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //位选编码
void delay(unsigned int i); //函数声明
void init();
void display();
void main (void) //主函数查询用以由单片机发送到上位机字符并且显示在上位机的接收区
取出的。初值的计算方法:假设所求的初值是N,如果单片机的晶振为12M,一个机器周期等于12
个时钟周期,所以计数一次的时间12/12M=1us,定时器每计数(256-N)次溢出一次,那么定时器
溢出一次的时间为(256-N)*1us,则T1的溢出率就是它的倒数。串口方式1的波特率=2的SMOD次
延时处理程序
**************************************************/
void delay(unsigned int k)
{
unsigned int m,n;
delay(4);
}
PCON= 0x80; //SMOD=0波特率提高一倍 SMOD=0波特率正常
TL1 = 0xfd;
TH1 = 0xfd; /* 波特率9600、数据位8、停止位1。效验位无 (12M晶振)
在这里,TL1与TH1中装的初值必须是一样的,因为每次计数溢出后TL1中装入的新值是从TH1中
#include <reg52.h>
char code MESSAGE[]= "请输入一行字符串";
unsigned char a,i;
unsigned char markde=0;
unsigned int ReData,SenData;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};