51单片机学习入门 AD采集正弦波 加串口发送

51单片机串口通信使用类似printf函数的两种办法
我的图书馆
51单片机串口通信使用类似printf函数的两种办法
http://blog.csdn.net/googlemi/article/details/89966052013& & &今天就简单来说说怎么在51单片机中使用"printf"函数:包括使用自带的printf函数和自己动手写一个printf函数,再贴代码之前先介绍几个相关的知识,主要用于自己写printf函数。
①函数:vsprintf,
其原型为int vsprintf(char *string, char *format, va_list param);,作用为将param按格式format写入字符串string中,因此他可以用于将任何格式数据转化为字符串数据,比如把整数97转化为ASCII码的97的程序就像下面这样vsprintf(string,"%d",97),当然还有一点需要注意:在keil里面使用sprintf需要包含stdio.h这个头文件(当然这里也可以使用sprintf,作用完全差不多,只需要稍加修改即可,不多介绍)。说到这里,再来说说另一个函数itoa吧,其实他比vsprintf更简单,其原型为char
*itoa(int value, char *string, int radix),作用为将value按radix进制写入到string字符串中,使用时需要包含头文件stdlib.h,可是在keil里面却无法使用,头文件里面不包含itoa,即使把VC里面的复制进来貌似还是不行,呵呵,目前不知道原因。
②可变参数函数
具体来说就是stdarg.h里面的这几个函数va_start,va_arg,va_list,va_end,这几个参数用于开辟一段内存区域,可以配合vsprintf使用,但是对内存使用较大,需要单片机具备一定的RAM,否则程序就算能编译通过也是无法运行的,用法见这里
③内部拓展RAM
定义:集成在单片机内部的数据存储器,在物理上是内部,但逻辑上是外部,访问时需要使用MOVX或者xdata访问,具体可以看STC8051手册,如下所示
从这里可以看出,STC12C5A60S2单片机内部含有1024byte=1Kbyte的内部拓展RAM,在访问的时候,使用C语言的时候,需要加上xdata才可以访问,使用汇编的时候需要用MOVX指令访问。
到这里我们先来算一算STC12C5A60S2单片机在不接外部RAM的情况下总的RAM大小,先看一下内部的RAM分布图
:内部RAM(256byte)包括三部分:低128byte,高128byte和特殊功能寄存器区,特别注意和51不同,他的特殊功能寄存器和高128byte地址重叠,但是物理上是分开的,所有内部可用的RAM有256byte,所以到此为止可以得到内部RAM大小总共有:256byte+1024byte=1280byte
说了这么多,下面不多说,直接上程序
《一》直接使用系统自带的printf函数:特别注意需要置位TI=1,否则是无法发送的,程序如下:
//此程序主要用于uart发送(proteus终端不能显示汉字,但串口助手可以),输入换行符\n换行&&#include&reg52.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)&&&&&&{&&&&&&&&&&printf("%d&&%x&&%c&&%s&&%p\n",a,a,(char)a,string,string);&&&&&&&&&&delay(1000);&&&&&&}&&&&&&return&0;&&}&&&&void&uart_init(void)&&{&&&&&&TMOD=0x20;//即,定时器/计数器1,工作方式2&&&&&&TH1=0//设置波特率为9600&&&&&&TL1=0&&&&&&TR1=1;//启动定时器/计数器1&&&&&&&&&&&&SCON=0x50;&//.串口工作方式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的函数:uart_printf
但是这种情况占用RAM较多,因为需要开辟大数组,所以需要使用拓展型的51单片机,普通的AT89C51和STC89C52之类的会造成内存不够用、堆栈溢出等等问题,所以以下程序都是基于STC12C5A60S2的,因为它含有内部拓展的1024byte的RAM,可以用来存储大数组
//此程序主要用于uart发送(proteus不能仿真,但实际是可以运行的),输入换行符\n换行&&#include&reg52.h&&&//stdio.h,stdarg.h用于vsprintf函数原型&&#include&stdio.h&&&#include&stdarg.h&&&&&void&delay(unsigned&int&z);&&void&uart_init(void);//串行口初始化&&void&sendbyte(unsigned&char&c);&&void&sendstring(unsigned&char&*string);&&void&uart_printf(const&char&*fmt,...);&&&&int&main(void)&&{&&&&&&int&a=99;&&&&&&uart_init();&&&&&&while(1)&&&&&&{&&&&&&&&&&uart_printf("10进制:%d&&16进制:%x&&字符格式:%c\n",a,a,a);&&&&&&&&&&delay(1000);&&&&&&}&&&&&&return&0;&&}&&&&void&uart_init(void)&&{&&&&&&TMOD=0x20;//即,定时器/计数器1,工作方式2&&&&&&TH1=0xf3;//设置波特率为2400&&&&&&TL1=0xf3;&&&&&&TR1=1;//启动定时器/计数器1&&&&&&&&&&&&SCON=0x50;&//.串口工作方式1,允许串行控制&&&&&&PCON=0x00;//设置SMOD=0&&&&&&IE=0x00;&//由于是查询方式,故需要禁止中断,CPU不允许中断,串行不允许中断&&&&&&&&}&&&&void&delay(unsigned&int&z)&&{&&&&&&unsigned&int&x,y;&&&&&&for(x=z;x&0;x--)&&&&&&&&&&for(y=110;y&0;y--);&&}&&&&void&sendbyte(unsigned&char&c)&&{&&&&&&if(c=='\n')//如果遇到\n就换行&&&&&&{&&&&&&&&&&//发送CR(carriage&return)&&&&&&&&&&SBUF=0x0D;&&&&&&&&&&&while(!TI);//等待发送完成&&&&&&&&&&TI=0;&&&&&&&&&&&&&&&&&&&&//发送&LF(NL&line&feed,new&line)&&&&&&&&&&SBUF=0x0A;&&&&&&&&&&&while(!TI);//等待发送完成&&&&&&&&&&TI=0;&&&&&&&&&&&&&}&&&&&&else&&&&&&{&&&&&&&&&&SBUF=c;&&&&&&&&&&while(!TI);//等待发送完成&&&&&&&&&&TI=0;&&&&&&}&&}&&&&void&sendstring(unsigned&char&*string)//此处*string相当于数组&&{&&&&&&while(*string!='\0')//判断是否到字符串末尾&&&&&&{&&&&&&&&&&sendbyte(*string);&&&&&&&&&&string++;&&&&&&}&&}&&&&void&uart_printf(const&char&*fmt,...)&&{&&&&&&va_list&&&&&&&char&xdata&string[1024];//访问内部拓展RAM,非访问外部RAM,不能超过内部拓展RAM大小(此处为1024)&&&&&&&&&&&&va_start(ap,fmt);&&&&&&vsprintf(string,fmt,ap);//此处也可以使用sprintf函数,用法差不多,稍加修改即可,此处略去&&&&&&sendstring(string);&&&&&&va_end(ap);&&}&&
最后简单总结 :其中第一种方法用于中断方式工作会有问题,因为其底层是调用putchar函数实现的,工作方式为中断,但是比较简单,可以通过proteus仿真;第二种方法更完善,不过程序比较复杂,不能使用proteus仿真,但实际是可以工作的。
[转]&[转]&[转]&[转]&[转]&[转]&
喜欢该文的人也喜欢博客访问: 963131
博文数量: 177
博客积分: 3640
博客等级: 中校
技术积分: 1768
注册时间:
分类: C/C++ 09:12:16
串口通信是单片机和其它系统交换数据的主要形式。上周有几位网友问到单片机双机通信的问题,做而论道为此特意设计了软件、硬件,进行了测试。下列程序,经过编译、硬件仿真调试成功。要点如下:两个51单片机,两机的串**叉连线,双机互发数据;发送方大约每隔
发送一个字节,内容递增(或递减);接收方采用两位数据显示器显示收到的数据。网友实验时,显示函数应该根据自己的设备进行改写下面的程序,既包括了发送功能,也包括了接收功能,也就是说:进行双机通信实验时,两个单片机使用同一个程序就可以。//=========================================#include#define
uchar unsigned char#define uint unsigned intuchar Rbuf = 0;uchar
code dis_7[] = {
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
//共阴段码
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};
//段码表 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, off
//-------------------------------void delay(uint k){
for(i = 0; i < i++)
for(j = 0; j < 200;
j++);}//-------------------------------void Display(uchar
P2 = 0xFF;
P0 = dis_7[x / 16];
//输出高四位
P2 = 0xFF;
P0 = dis_7[x % 16];
//输出低四位
P2 = 0xFD;
delay(2);}//-------------------------------void UART()interrupt 4
//清除中断标志
//清除中断标志
}}//-------------------------------void main(){
SCON = 0x50;
//串口工作在方式1
TMOD = 0x20;
//定时器1当做波特率发生器
TH1 = 0xFD;
//初值, 9600 @ 11.0592MHz
TL1 = 0xFD;
while (1) {
for (i = 0; i <
100; i++)//多次循环,便于观察与发送
Display(Rbuf);
//显示收到的数据
//发送数据
//本机显示
}}//=========================================上述程序,用PROTEUS仿真截图如下:&&&图片链接:#图中的两个单片机,都是使用上述的同一个程序。
阅读(5281) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
请登录后评论。后使用快捷导航没有帐号?
请完成以下验证码
查看: 5480|回复: 12
触摸屏发出的指令通过串口如何让51单片机接收到
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
我有个触摸屏,然后串口和并且单片机想通讯的程序已经写好了,现在的问题就是,我要怎么做才可以让单片机读懂并且读懂,执行我的命令呢
在线时间1764 小时
威望1734分
芯币1216枚
E金币318枚
TA的帖子TA的资源
纯净的硅(高级), 积分 1734, 距离下一级还需 266 积分
纯净的硅(高级), 积分 1734, 距离下一级还需 266 积分
你不是说串口吗,那就制定好串口通讯的协议,单片机解码就行了
在线时间586 小时
芯币3683枚
TA的帖子TA的资源
自己弄个通信协议啊
例如&&触摸屏&&发送& & 204 , 204,0x0d,0x0a;
就表示&&触摸到了&&坐标为 x = 204,y =204&&;0x0d 0x0a 就作为数据尾
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
自己弄个通信协议啊
例如&&触摸屏&&发送& & 204 , 204,0x0d,0x0a;
就表示&&触摸到了&&坐标为 x = 204, ...
还是不太明白
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
自己弄个通信协议啊
例如&&触摸屏&&发送& & 204 , 204,0x0d,0x0a;
就表示&&触摸到了&&坐标为 x = 204, ...
通讯协议我也经写好了,触摸屏上面的指令也能通过串口调节助手读取数据
在线时间586 小时
芯币3683枚
TA的帖子TA的资源
那你就按着你串口助手读取数据的&&的指令来操作啊,
用单片机定时发送读取指令啊,这样就行啊。就相当于定时扫描按键的方式一样了
在线时间3231 小时
威望1906分
芯币13952枚
TA的帖子TA的资源
1、触摸屏连接的是单片机的RXD 和TXD吗?
2、目前你的触摸屏都会向单片机发送哪些固定的指令?
如果连接的是RXD,读取接收寄存器的值,比较相关指令
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
那你就按着你串口助手读取数据的&&的指令来操作啊,
用单片机定时发送读取指令啊,这样就行啊。就相当于定 ...
谢谢,我懂了
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
1、触摸屏连接的是单片机的RXD 和TXD吗?
2、目前你的触摸屏都会向单片机发送哪些固定的指令?
对的 ,我现在读取的TXD和RXD的数据
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
1、触摸屏连接的是单片机的RXD 和TXD吗?
2、目前你的触摸屏都会向单片机发送哪些固定的指令?
对的 ,我现在读取的TXD和RXD
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
谢谢各位了,我的问题已经得到解决了
在线时间3618 小时
威望31866分
芯币59552枚
TA的帖子TA的资源
& 然后串口和并且单片机想通讯的程序已经写好了 &
在线时间628 小时
威望1226分
芯币1938枚
TA的帖子TA的资源
纯净的硅(高级), 积分 1226, 距离下一级还需 774 积分
纯净的硅(高级), 积分 1226, 距离下一级还需 774 积分
程序都写好了,不知道怎么让单片机知道,你程序是别人写的吧?
天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,,添加说明EEworld好友
EEWORLD 官方微信
Powered by求助 有没有大佬帮我写个程序。
51单片机 每隔1秒通过串行口向上位机发送一组数据。用c语言_单片机吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:150,853贴子:
求助 有没有大佬帮我写个程序。
51单片机收藏
求助 有没有大佬帮我写个程序。
51单片机 每隔1秒通过串行口向上位机发送一组数据。用c语言。
为用户提供各种低成本,低功耗,低能耗,功能强的微控制器解决方案.恩智浦微控制器,高性能,设计新颖,性能稳定,价格超低,欲购从速,欢迎垂询!
一秒中断 发数就好了
printf(&&)delay1s;
我怎么感觉发的程序会被删
我发你,私聊不了
#include &reg51.h&void InitUART(void){
TMOD = 0x21;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
TH0 = 0x4C;
TL0 = 0x00;
PCON = 0x00;
TR1 = 1;}void SendOneByte(unsigned char c){
while(!TI);
TI = 0;}void main(void){
InitUART();}void UARTInterrupt(void) interrupt 4{
//add your code here!
TI = 0;}void Timer0Interrupt(void) interrupt 1{
TH0 = 0x4C;
TL0 = 0x00;
Send one bytet(0xff);
}}没测试。完整的。
我要发送一串好几个数字的话,下边要写好几个send one byte吗
#include &reg51.h&sbit
led=P2^0 ;sbit
led1=P2^1 ;void InitUART(void){ TMOD = 0x21; SCON = 0x50; TH1 = 0xF3; TL1 = TH1; TH0 = 0x3C; TL0 = 0xB0; EA = 1; ET0 = 1; TR0 = 1;
PCON = 0x00; EA = 1; ES = 1; TR1 = 1; TR0 = 1; }void SendOneByte(unsigned char c){ SBUF = while(!TI); TI = 0;}void main(void){ InitUART();
while(1);}void UARTInterrupt(void) interrupt 4{ if(RI) { RI = 0; //add your code here! } else TI = 0;}void Timer0Interrupt(void) interrupt 1{ TH0 = 0x3C; TL0 = 0xB0; led1=~led1; i++; if(i==20) {i=0; TR0=0; led=~ SendOneByte(0xff);
TR0=1; }}可以写多个,发送指令,现在的是时间是,1秒+上发字节数的时间,,测试过的,波特率是2400
怎么还用到led了
登录百度帐号豆丁微信公众号
君,已阅读到文档的结尾了呢~~
51单片机AD转换和串口收发子程序代码  相关说明性文字来自网络收集,欢迎下载
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
51单片机AD转换和串口收发子程序代码 
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

更多关于 单片机学习入门 的文章

 

随机推荐