文档库 最新最全的文档下载
当前位置:文档库 › 单片机串口printf数据

单片机串口printf数据

单片机串口printf数据
单片机串口printf数据

想做的利用串口打印出数据,在PC上的超级终端上显示出来。由于发送数据的未知和不确定性,所以不可能开辟一个数组来发送这些字符。

所以要重定义printf来作为串口的打印输出,需加头文件stdio.h

1.勾选usb micro lib

2.在程序中添加:(头文件需要添加#include )

#ifdef __GNUC__

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif

PUTCHAR_PROTOTYPE

{

USART_SendData(USART1, (u8) ch);

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

return ch;

}

很明显这个方法使用printf()只能输出到一个usart,如果需要使用多个usart呢,肯定不能都是用printf()。

方法如下是继续是用usart2的printf()功能:

1.勾选usb micro lib,跟上面类似

2.添加头文件#include ,编写USART2的printf函数:

void USART2_printf (char *fmt, ...)

{

char buffer[CMD_BUFFER_LEN+1]; // CMD_BUFFER_LEN长度自己定义吧

u8 i = 0;

va_list arg_ptr;

va_start(arg_ptr, fmt);

vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr);

while ((i < CMD_BUFFER_LEN) && buffer[i])

{

USART_SendData(USART2, (u8) buffer[i++]);

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

}

va_end(arg_ptr);

}

用法与printf类似,如int i=123;USART2_printf("%d",i);

如果需要使用USART3,USART4......的printf()函数自以此类推!

以上代码都是网上流传的一种写法,但在这里发送打印的不是采用中断发送的,即有好多时间都浪费在了循环检测发送完成位上。

在这个函数中有个叫不定参数的概念,相应的标准头文件为stdarg.h,是C语言中C标准函数库的标头档,stdarg是由stdandard(标准) arguments(参数)简化而来,主要目的为让函数能够接收不定量参数。不定参数函数的参数数量是可变动的,它使用省略号来忽略之后的参数。stdarg.h宏有以下几个:

va_start 使va_list指向起始的参数

va_arg 检索参数

va_end 释放va_list

va_copy 拷贝va_list的内容

各个va_xxx的作用。

va_list arg_ptr:定义一个指向个数可变的参数列表指针;

va_start(arg_ptr, argN):使参数列表指针arg_ptr指向函数参数列表中的第一个可选参数,说明:argN是位于第一个可选参数之前的固定参数,(或者说,最后一个固定参数;…之前的一个参数),函数参数列表中参数在内存中的顺序与函数声明时的顺序是一致的。如果有一va函数的声明是void va_test(char a, char b, char c, …),则它的固定参数依次是a,b,c,最后一个固定参数argN为c,因此就是va_start(arg_ptr, c)。

va_arg(arg_ptr, type):返回参数列表中指针arg_ptr所指的参数,返回类型为type,并使指针arg_ptr指向参数列表中下一个参数。

va_copy(dest, src):dest,src的类型都是va_list,va_copy()用于复制参数列表指针,将

dest初始化为src。

va_end(arg_ptr):清空参数列表,并置参数指针arg_ptr无效。说明:指针arg_ptr被置无效后,可以通过调用va_start()、va_copy()恢复arg_ptr。每次调用va_start() / va_copy()后,必须得有相应的va_end()与之匹配。参数指针可以在参数列表中随意地来回移动,但必须在va_start() … va_end()之内。

(以下内容出自戎亚新)

然而printf到底是怎样取第一个参数后面的参数值的呢,请看如下代码

2. printf 函数的实现

//ac env.h typedef char *va_lis t; #define _AUPBND (s izeof

(acp i_nativ e_int) - 1) #define _ADNBND (s izeof (acpi_n ative_int) - 1) #defin e _bnd(X, bnd) (((s izeof (X)) + (bnd)) & (~(bnd))) #def ine

va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd

(T,_ADNBND)))) #def ine v a_end(ap) (vo id) 0 #def ine v a_s tart(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) //s tart.c

s tatic char s print_buf[1024]; int printf(char *fmt, ...) { va_lis t args; int n; va_s tart(args, fmt); n = vs printf(s print_buf, fmt, args);

va_end(args); wr ite(s tdout, s print_buf, n); return n; } //unis td.h

s tatic inline long write(int fd, const char *buf, off_t count) { return s ys_write(fd, buf, count); }

3. 分析从上面的代码来看,printf似乎并不复杂,它通过一个宏v a_start 把所有的可变参数放到了由args指向的一块内存中,然后再调用v sprintf. 真正的参数个数以及格式的确定是在v sprintf搞定的了。由于v sprintf的代码比较复杂,也不是我们这里要讨论的重点,所以下面就不再列出了。我们这里要讨论的重点是v a_start(ap, A)宏的实现,它对定位从参数A后面的参数有重大的制导意义。现在把#def ine v a_start(ap, A) (v oid) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) 的含义解释一下如下:

va_s tart(ap, A) { char *ap = ((ch ar *)(&A)) + s izeof(A)并int类型大小地址对齐}

在printf的v a_start(args, fmt)中,fmt的类型为char *, 因此对于一个32为系统sizeof(char *) = 4, 如果int大小也是32,则v a_start(args, fmt);相当于char *args = (char *)(&fmt) + 4; 此时args的值正好为fmt后第一个参数的地址。对于如下的可变参数函数void fun(double d,...) { v a_lis t args; int n; va_s tart(args, d); }

则v a_start(args, d);相当于char *args = (char *)&d + s izeof(double);

此时args正好指向d后面的第一个参数。可变参数函数的实现与函数调用的栈结构有关,正常情况下c/c++的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈。

***************************************************************************************************** *printf函数大概就这么个东西吧,反正也是模糊概念的在这,关于使用串口中断发送的方法再做研究

在printf中有个v sprintf的函数,参数如下

int vsnprintf(

char *buffer, // 输出参数

size_t count, // 最大可写字符数

const char *format,// 格式字符串

va_list argptr // 参数列表指针

);

这是个复杂的问题,以后待研究,现在做保留

单片机按键加减报告

单片机按键加减报告

————————————————————————————————作者:————————————————————————————————日期: ?

单片机实验报告

一、实验目的 1、学习利用单片机设计简单加减计数,并学会定时/计数器T0/T1的使用。2、学习使用keil和proteus软件。 3、熟悉汇编语言并能利用汇编语言编写程序。 二、实验思路 用T0、T1设计10位以内的按键加减计数: 利用T0/T1计数功能实现每次按键的中断,且采用方式2,可以自动重载初值,较为方便。这里不考虑优先级的问题。再分别对T0、T1编写中断处理的程序。要注意的是,加法时,9加1显示0的情况;减法时,0减1显示9的情况。 三、实验原理 (以下不考虑T2的情况) 1、中断的概念 CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断。 2、定时/计数器 (1)中断控制寄存器(TCON) TCON的高4位用于控制定时/计数器的启动和中断申请。其格式如下: TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。 TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。

上位机与51单片机串口通信

上位机与51单片机串口通信 目录: 1、单片机串口通信的应用 2、PC控制单片机IO口输出 3、单片机控制实训指导及综合应用实例 4、单片机给计算机发送数据: [实验任务] 单片机串口通信的应用,通过串口,我们的个人电脑和单片机系统进行通信。 个人电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机系统接收后,用LED显示接收到的数据和向上位机发回原样数据。 [硬件电路图] [实验原理] RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串 行接口标准,用来实现计算机与计算机之间、计算机与外设之间的数据通讯。 RS-232串行接口总线适用于:设备之间的通讯距离不大于15m,传输速率最大为20kBps。RS-232协议以-5V-15V表示逻辑1;以+5V-15V 表示逻辑0。我们是用MAX232芯片将RS232电平转换为TTL电平的。一个完整的RS-232接口有22 根线,采用标准的25芯插头座。我们在这里使用的是简化的9芯插头座。 注意我们在这里使用的晶振是11.0592M的,而不是12M。因为波特率的设置 需要11.0592M的。 “串口调试助手V2.1.exe”软件的使用很简单,只要将串口选择‘CMO1’波 特率设置为‘9600’数据位为8 位。打开串口(如果关闭)。然后在发送区里 输入要发送的数据,单击手动发送就将数据发送出去了。注意,如果选中‘十六 进制发送’那么发送的数据是十六进制的,必须输入两位数据。如果没有选中, 则发送的是ASCLL码,那么单片机控制的数码管将显示ASCLL码值。

//参考源程序 #include "reg52.h" //包函8051 内部资源的定义 unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容sbit gewei=P2^4; //个位选通定义

按键控制单片机PWM输出设计

学号1322010110 天津城建大学 单片机原理及应用A课程 设计说明书 按键控制单片机PWM输出设计起止日期:2016年05月30日至2016年6月10日 学生姓名 班级 成绩 指导教师(签字) 控制与机械工程学院 2016年6月10日

目录 第一章系统方案设计 (1) 1.1 PWM (1) 1.2 STC12C5A60S2简介 (1) 1.3 仿真工具介绍 (2) 1.3.1 Protues简介 (2) 1.3.2 Keil uVision3简介 (4) 第二章硬件电路设计 (5) 2.1 复位电路 (5) 2.2 时钟电路 (5) 2.3 按键中断 (5) 2.4 显示电路 (6) 第三章程序设计流程图 (7) 第四章系统仿真 (8) 4.1 仿真图 (8) 4.2 程序 (8) 4.3 PCB.................................................................................................................. 错误!未定义书签。参考资料 ....................................................................................................................... 错误!未定义书签。

第一章系统方案设计 1.1 PWM PWM的全称是Pulse Width Modulation(脉冲宽度调制),它是通过改变输出方波的占空比来改变等效的输出电压。 1.2 STC12C5A60S2简介 STC12C5A60S2是STC生产的单时钟/机器周期(1T)的单片机,是高速、低功耗、超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换,针对电机控制,强干扰场合。 1)管脚说明: 1、P0.0~P0.7 P0:P0口既可以作为输入/输出口,也可以作为地址/数据复用总线使用。当P0口 作为输入/输出口时,P0是一个8位准双向口,内部有弱上拉电阻,无需外接上拉电阻。当P0作为地址/数据复用总线使用时,是低8位地址线A0~A7,数据线D0~D7 2、P1.0/ADC0/CLKOUT2 标准IO口、ADC输入通道0、独立波特率发生器的时钟输出 3、P1.1/ADC1 4、P1.2/ADC2/ECI/RxD2 标准IO口、ADC输入通道2、PCA计数器的外部脉冲输入脚,第二串口数据接收端 5、P1.3/ADC3/CCP0/TxD2 外部信号捕获,高速脉冲输出及脉宽调制输出、第二串口数据发送端 6、P1.4/ADC4/CCP1/SS非 SPI同步串行接口的从机选择信号 7、P1.5/ADC5/MOSI SPI同步串行接口的主出从入(主器件的输入和从器件的输出) 8、P1.6/ADC7/SCLK SPI同步串行接口的主入从出 9、P2.0~P2.7 10、P2口内部有上拉电阻,既可作为输入输出口(8位准双向口),也可作为高8位地址总线使用。 11、P3.0/RxD 标准IO口、串口1数据接收端 12、P3.1/INT0非 外部中断0,下降沿中断或低电平中断 13、P3.3/INT1 14、P3.4/T0/INT非/CLKOUT0 定时器计数器0外部输入、定时器0下降沿中断、定时计数器0的时钟输出 2)A/D转换器的结构: STC12C5A60AD/S2系列带A/D转换的单片机的A/D转换口在P1口,有8路10位高速A/D转换器,速度可达到250KHz(25万次/秒)。8路电压输入型A/D,可做温度检测、电池电压检测、按键扫描、频谱检测等。上电复位后P1口为弱上拉型IO口,用户可以通过软件设置将8路中的任何一路设置为A/D 转换,不须作为A/D使用的口可继续作为IO口使用。 单片机ADC由多路开关、比较器、逐次比较寄存器、10位DAC、转换结果寄存器以及ADC_CONTER

6步教你在STM32程序中添加 printf函数

6步教你在STM32程序中添加printf函数 6步教你在STM32程序中添加printf函数 前提是你有一个完整的可以运行的keil工程比如ADC的 调试的时候很多时候用到串口这里教你怎么样使用Printf 函数 在程序中添加Printf.txt 1, #include 2, /* Private functions ---------------------------------------------------------*/ 下添加 void USART_Configuration(void); #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ 3,添加如下2个函数usart配置和重定向C库的printf函数 void USART_Configuration() { /* USARTx configured as follow: - BaudRate = 9600 baud - Word Length = 8 Bits - One Stop Bit - No parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled */ USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Configure USART1 Tx (PA9) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Rx (PA10) as input floating */

单片机模拟串口

随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51系列只提供一个串口,那么另一个串口只能靠程序模拟。 本文所说的模拟串口,就是利用51的两个输入输出引脚如P1.0和P1.1,置1或0分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1或置0。至于串口通信的波特率,说到底只是每位电平持续的时间,波特率越高,持续的时间越短。如波特率为9600BPS,即每一位传送时间为1000ms/9600=0.104ms,即位与位之间的延时为为0.104毫秒。单片机的延时是通过执行若干条指令来达到目的的,因为每条指令为1-3个指令周期,可即是通过若干个指令周期来进行延时的,单片机常用11.0592M的的晶振,现在我要告诉你这个奇怪数字的来历。用此频率则每个指令周期的时间为(12/11.0592)us,那么波特率为9600BPS每位要间融多少个指令周期呢?指令周期s=(1000000/9600)/(12/11.0592)=96,刚好为一整数,如果为4800BPS则为96x2=192,如为19200BPS则为48,别的波特率就不算了,都刚好为整数个指令周期,妙吧。至于别的晶振频率大家自已去算吧。现在就以11.0592M的晶振为例,谈谈三种模拟串口的方法。 方法一:延时法 通过上述计算大家知道,串口的每位需延时0.104秒,中间可执行96个指令周期。 #define uchar unsigned char sbit P1_0 = 0x90; sbit P1_1 = 0x91; sbit P1_2 = 0x92; #define RXD P1_0 #define TXD P1_1 #define WRDYN 44 //写延时 #define RDDYN 43 //读延时 //往串口写一个字节 void WByte(uchar input) { uchar i=8; TXD=(bit)0; //发送启始 位 Delay2cp(39); //发送8位数据位 while(i--) { TXD=(bit)(input&0x01); //先传低位 Delay2cp(36); input=input>>1; } //发送校验位(无)

51单片机与PC机通信资料

《专业综合实习报告》 专业:电子信息工程 年级:2013级 指导教师: 学生:

目录 一:实验项目名称 二:前言 三:项目内容及要求 四:串口通信原理 五:设计思路 5.1虚拟串口的设置 5.2下位机电路和程序设计 5.3串口通信仿真 六:电路原理框图 七:相关硬件及配套软件 7.1 AT89C51器件简介 7.2 COMPIN简介 7.3 MAX232器件简介 7.4友善串口调试助手 7.5 虚拟串口软件Virtual Serial Port Driver 6.9八:程序设计 九:proteus仿真调试 十:总结 十一:参考文献 一:实验项目名称:

基于51单片机的单片机与PC机通信 二:前言 在国内外,以PC机作为上位机,单片机作为下位机的控制系统中,PC机通常以软件界面进行人机交互,以串行通信方式与单片机进行积极交互,而单片机系统根据被控对象配置相应的前向,后向信息通道,工作时作为主控机测对象,作为被控机接受PC机监督,指挥,定期或受命向上位机提供对象及本身的工作状态信息。 目前,随着集成电路集成度的增加,电子计算机向微型化和超微型化方向发展,微型计算机已成为导弹,智能机器人,人类宇宙和太空和太空奥妙复杂系统不可缺少的智能部件。在一些工业控制中,经常需要以多台单片机作为下位机执行对被控对象的直接控制,以一台PC机为上位机完成复杂的数据处理,组成一种以集中管理、分散控制为特点的集散控制系统。 为了提高系统管理的先进性和安全性,计算机工业自动控制和监测系统越来越多地采用集总分算系统。较为常见的形式是由一台做管理用的上位主计算机(主机)和一台直接参与控制检测的下位机(单片机)构成的主从式系统,主机和从机之间以通讯的方式来协调工作。主机的作用一是要向从机发送各种命令及参数:二是要及时收集、整理和分析从机发回的数据,供进一步的决策和报表。从机被动地接受、执行主机发来的命令,并且根据主机的要求向主机回传相应烦人实时数据,报告其运行状态。 用串行总线技术可以使系统的硬件设计大大简化、系统的体积减小、可靠性提高。同时,系统的更改和扩充极为容易。MCS-51系列单片机,由于内部带有一个可用于异步通讯的全双工的穿行通讯接口,阴齿可以很方便的构成一个主从式系统。 串口是计算机上一种非常通用的设备通讯协议,大多数计算机包容两个基于RS232的串口。串口同时也是仪器仪表设备通过用的通讯协议,很多GPIB兼容的设备也带有RS-232口。同时串口通讯协议也可以用于获取远程采集设备数据。所以,深入的理解学习和研究串口通信相关知识是非常必要的。此次毕业设计选题为“PC机与MCS-51单片机的串口通讯”,使用51单片机来实现一个主从式

单片机键盘显示实验报告

单片机得键盘与显示实验报告 ㈠实验目得 1.掌握单片机I/O得工作方式; 2.掌握单片机以串行口方式0工作得LED显示; 3.掌握键盘与LED显示得编程方法. ㈡实验器材 1.G6W仿真器?一台 2.MCS—51实验板?一台 3.PC机???一台 4.电源一台 ㈢实验内容及要求 实验硬件线路图见附图 从线路图可见,8051单片机得P1口作为8个按键得输入端,构成独立式键盘。四个LED显示器通过四个串/并移位寄存器74LS164接口至8051得串行口,该串行口应工作在方式0发送状态下,RXD端送出要显示得段码数据,TXD则作为发送时钟来对显示数据进行移位操作。 编写一个计算器程序,当某一键按下时可执行相应得加、减、乘、除运算方式,在四个显示器上显示数学算式与最终计算结果。 注:①通过按键来选择加、减、乘、除四种运算方式。 ②输入两个数字均为一位十进制数,可预先放在内存中。 ㈣实验框图(见下页) ㈤思考题 1.当键盘采用中断方式时,硬件电路应怎样连接? P1、4~P1、7就是键输出线,P1、0~P1、3就是扫描输入线。输入与门用于产生按键中断,其输入端与各列线相连,再通过上拉电阻接至+5 V电源,输出端接至8051得外部中断输入端。 2、74LS164移位寄存器得移位速率就是多少? 实验中要求计算得式子与结果之间相差一秒,移位寄存器得移位速率应该就是每秒一位吧。其实这个问题确实不知道怎么回答。.。。。

?LED

实验代码: ORG0000H AJMPMAIN ORG 0030H MAIN:MOV 41H,#0BBH;对几个存放地址进行初始化MOV 42H,#0BBH MOV43H,#0BBH MOV44H,#0BBH MOV SCON,#00H ;初始化串行口控制寄存器,设置其为方式0 LCALLDISPLAY ;初始化显示 KEY:MOV R3,#08H;用来存放两个数据 MOV R4,#02H MOVP1,#0FFH ;初始化P1口 MOVA,P1 ;读取按键状态 CPL A ;取正逻辑,高电平表示有键按下 JZ KEY ;A=0时无键按下,重新扫描键盘 LCALL DELAY1 ;消抖 MOVA,P1;再次读取按键状态 CPL A JZ KEY;再次判别就是否有键按下 PUSH A KEY1:MOVA,P1 CPL A ANL A,#0FH ;判别按键释放 JNZKEY1;按键未释放,等待 LCALLDELAY1;释放,延时去抖动 POPA JB ACC、0,ADD1 ;K1按下转去ADD1 JBACC、1,SUB1 ;K1按下转去SUB1 JB ACC、2,MUL1 ;K1按下转去MUL1 JBACC、3,DIV1;K1按下转去DIV1 LJMP KEY ADD1:LCALL BUFFER ;显示加数与被加数MOV43H,#049H LCALL DISPLAY;显示加号 MOV A,R3 ADDA,R4 DA A MOV R3,A;相加结果放入R6

C中Printf函数的格式控制

printf的格式控制的完整格式: % - 0 m.n l或h 格式字符 下面对组成格式说明的各项加以说明: ①%:表示格式说明的起始符号,不可缺少。 ②-:有-表示左对齐输出,如省略表示右对齐输出。 ③0:有0表示指定空位填0,如省略表示指定空位不填。 ④m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为n=6位。 ⑤l或h:l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型。 --------------------------------------- 格式字符 格式字符用以指定输出项的数据类型和输出格式。 ①d格式:用来输出十进制整数。有以下几种用法: %d:按整型数据的实际长度输出。 %md:m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出。 %ld:输出长整型数据。 ②o格式:以无符号八进制形式输出整数。对长整型可以用"%lo"格式输出。同样也可以指定字段宽度用“%mo”格式输出。 例: main() { int a = -1; printf("%d, %o", a, a); } 运行结果:-1,177777 程序解析:-1在内存单元中(以补码形式存放)为(1111111111111111)2,转换为八进制数为(177777)8。 ③x格式:以无符号十六进制形式输出整数。对长整型可以用"%lx"格式输出。同样也可以指定字段宽度用"%mx"格式输出。 ④u格式:以无符号十进制形式输出整数。对长整型可以用"%lu"格式输出。同样也可以指定字段宽度用“%mu”格式输出。 ⑤c格式:输出一个字符。 ⑥s格式:用来输出一个串。有几中用法 %s:例如:printf("%s", "CHINA")输出"CHINA"字符串(不包括双引号)。 %ms:输出的字符串占m列,如字符串本身长度大于m,则突破获m的限制,将字符串全部输出。若串长小于m,则左补空格。 %-ms:如果串长小于m,则在m列范围内,字符串向左靠,右补空格。 %m.ns:输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格。 %-m.ns:其中m、n含义同上,n个字符输出在m列范围的左侧,右补空格。如果n>m,则自动取n值,即保证n个字符正常输出。

基于单片机的串口通信模块设计

1 绪论 1.1 研究背景 通信是指不同的独立系统利用线路互相交换数据,它的主要目的是将数据从一端传送到另一端,实现数据的交换。在现代工业控制中,通常采用计算机作为上位机与下层的实时控制与监测设备进行通讯。现场数据必须通过一个数据收集器传给上位机,同样上位机向现场设备发命令也必须通过数据收集器。串行通信因其结构简单、执行速度快、抗干扰能力强等优点,已被广泛应用于数据采集和过程控制等领域。 计算机与外界的信息交换称为通信。基本的通信方式有并行通信和串行通信两种。串行通信是指一条信息额各位数据被逐位按顺序传送的通信方式。串行通信的特点是:数据位传送,按位顺序进行,最少只需要一根传输线即可完成,成本低但传送速度快,串行通信的距离可以从几米到几千米。 随着计算机技术尤其是单片微型机技术的发展,人们已越来越多地采用单片机来对一些工业控制系统中如温度、流量和压力等参数进行监测和控制。PC机具有强大的监控和管理能力,而单片机则具有快速及灵和的控制特点,通过PC 机的RS-232串行接口与外部设备进行通信,是许多测控系统中常用的一种通信解决方案。而随着USB接口技术的成熟和使用的普及,由于USB 接口有着 RS-232(DB-9)串口无法比拟的优点,RS-232(DB-9)串口正在逐步地为USB 接口所替代。而在现在的大多数笔记本电脑中,出于节省物理空间和用处不大等原因,RS-232(DB-9)串口已不再设置,这就约束了基于RS-232(DB-9)串口与PC 机联络的单片机设备的使用围。当前USB接口逐步取代RS-232(DB-9)串口已是大势所趋,单片机同计算机的USB通信在实际工作中的应用围也将越来越广。本文所介

51单片机串口通信异常的调试一例

51单片机串口通信异常的调试一例 单片机与DSP在硬件结构和程序编写方面存在很多共同之处,所以最近几周试着用了一下51单片机开发板,希望进一步熟悉中断的概念、串口通信、I2C协议、存储扩展等常用的知识。 在进行串口通信的实验时,预期功能不能实现。实验的设计方案是:通过上位机给单片机发送一个16bit的字符串,单片机对字符串进行接收并立刻回显给上位机,接收并回显完毕后依次将这些字符(只能是0-9,a-f这几个字符,可以重复)在数码管上进行显示。 程序编写完成后,通过上位机发送字符串9876543210abcdef,单片机串口接收并回显9876543210abcde,然后数码管依次显示f9876543210abcde,数码管显示完成后,单片机串口回显的字符串中的e后面又多了一个f。 对实验现象进行分析不难发现,串口的接收和回显功能正常,但是存在2个问题:1.串口接收并回显和数码管显示的时序有点混乱;2.数码管的显示出现异常,本应该依次显示9876543210abcdef,实际上显示的却是f9876543210abcde。 对源代码进行分析发现,时序混乱的原因是中断响应及中断返回的执行时序出现问题,修改代码后问题1被解决。 问题2的解决思路:源代码中,通过串口接收到的字符串被存储在一个一维数组array[16]中,该数组有16个元素,每个元素都是unsigned char型。在源代码中,先注释掉数码管显示的那一段代码,然后添加串口打印代码,串口打印实现的功能是依次显示array[0]到array[15]这16个元素的值。编译通过后,将程序烧写到单片机。使用串口调试助手,以十六进制的形式观察array[0]到array[15]的取值,结果如下:

51单片机键盘数码管显示_利用8255和51单片机实现数码管显示按键数值的程序(带程序)

期 中 大 作 业 学院:物理与电子信息工程学院

课题: 【利用8255和51单片机实现数码管显示按键数值的程序】要求: 【4*4矩阵键盘,按0到15,数码管上分别显示0~9,A~F】 芯片资料: 8255: 8255是Intel公司生产的可编程并行I/O接口芯片,有3个8位并行I/O口。具有3个通道3种工作方式的可编程并行接口芯片(40引脚)。其各口功能可由软件选择,使用灵活,通用性强。8255可作为单片机与多种外设连接时的中间接口电路。 8255作为主机与外设的连接芯片,必须提供与主机相连的3个总线接口,即数据线、地址线、控制线接口。同时必须具有与外设连接的接口A、B、C口。由于8255可编程,所以必须具有逻辑控制部分,因而8255内部结构分为3个部分:与CPU连接部分、与外设连接部分、控制部分。 8255特性: 1.一个并行输入/输出的LSI芯片,多功能的I/O器件,可作为CPU总线与外围的接口。 2.具有24个可编程设置的I/O口,即3组8位的I/O口,分别为PA口、PB口和PC 口。它们又可分为两组12位的I/O口:A组包括A口及C口(高4位,PC4~PC7),B组包括B口及C口(低4位,PC0~PC3)。A组可设置为基本的I/O口,闪控(STROBE)的I/O闪控式,双向I/O三种模式;B组只能设置为基本I/O或闪控式I/O两种模式,而这些操作模式完全由控制寄存器的控制字决定.

引脚说明 RESET:复位输入线,当该输入端处于高电平时,所有内部寄存器(包括控制寄存器)均被清除,所有I/O口均被置成输入方式。 CS:芯片选择信号线,当这个输入引脚为低电平时,即CS=0时,表示芯片被选中,允许8255与CPU进行通讯;CS=1时,8255无法与CPU做数据传输。RD:读信号线,当这个输入引脚为低电平时,即CS=0且RD=0时,允许8255通过数据总线向CPU发送数据或状态信息,即CPU从8255读取信息或数据。WR:写入信号,当这个输入引脚为低电平时,即CS=0且WR=0时,允许CPU将数据或控制字写入8255。 D0~D7:三态双向数据总线,8255与CPU数据传送的通道,当CPU 执行输入输出指令时,通过它实现8位数据的读/写操作,控制字和状态信息也通过数据总线传送。 PA0~PA7:端口A输入输出线,一个8位的数据输出锁存器/缓冲器,一个8位的数据输入锁存器。 PB0~PB7:端口B输入输出线,一个8位的I/O锁存器,一个8位的输入输出缓冲器。 PC0~PC7:端口C输入输出线,一个8位的数据输出锁存器/缓冲器,一个8位的数据输入缓冲器。端口C可以通过工作方式设定而分成2个4位的端口,每个4位的端口包含一个4位的锁存器,分别与端口A和端口B配合使用,可作为控制信号输出或状态信号输入端口。 A1,A0:地址选择线,用来选择8255的PA口,PB口,PC口和控制寄存器。 当A1=0, A0=0时,PA口被选择; 当A1=0, A0=1时,PB口被选择; 当A1=1, A0=0时,PC口被选择; 当A1=1. A0=1时,控制寄存器被选择。 74ls373芯片资料: 74ls373是常用的地址锁存器芯片,它实质是一个是带三态缓冲输出的8D 触发器,在单片机系统中为了扩展外部存储器,通常需要一块74ls373芯片.本文将介绍74ls373的工作原理,引脚图(管脚图),内结构图、主要参数及在单片机系统中的典型应用电路.

C语言Printf之使用及在单片机中的用法

一、printf常用说明 printf的格式控制的完整格式: % - 0 m.n l或h 格式字符 下面对组成格式说明的各项加以说明: ①%:表示格式说明的起始符号,不可缺少。 ②-:有-表示左对齐输出,如省略表示右对齐输出。 ③0:有0表示指定空位填0,如省略表示指定空位不填。 ④m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为n=6位。 ⑤l或h:l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型。 ---------------------------------- 格式字符 格式字符用以指定输出项的数据类型和输出格式。 ①d格式:用来输出十进制整数。有以下几种用法: %d:按整型数据的实际长度输出。 %md:m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出。 %ld:输出长整型数据。 ②o格式:以无符号八进制形式输出整数。对长整型可以用"%lo"格式输出。同样也可以指定字段宽度用“%mo”格式输出。例: main() { int a = -1; printf("%d, %o", a, a); } 运行结果:-1,177777 程序解析:-1在内存单元中(以补码形式存放)为(1111111111111111)2,转换为八进制数为(177777)8。 ③x格式:以无符号十六进制形式输出整数。对长整型可以用"%lx"格式输出。同样也可以指定字段宽度用"%mx"格式输出。 ④u格式:以无符号十进制形式输出整数。对长整型可以用"%lu"格式输出。同样也可以指定字段宽度用“%mu”格式输出。 ⑤c格式:输出一个字符。

单片机串口通信的发送与接收(可编辑修改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、如果在电脑上发送以$开始的字符串,则将整个字符串原样返回(字符串长度不是固定的)。

C语言printf函数详解

功能: 产生格式化输出的函数。 用法: printf(格式控制字符串,参数1,参数2,…,参数n); 格式控制字符串定义为: %[flags][width][.perc][F|N|h|l]type type d有符号10进制整数 i有符号10进制整数 o无符号8进制整数 u无符号10进制整数 x无符号的16进制数字,并以小写abcdef表示 X无符号的16进制数字,并以大写ABCDEF表示 f浮点数 E/e用科学记数法表示浮点数 g用%f和%e表示中,总的位数最短的来表示浮点数。G同g格式,但表示为指数c单个字符 s字符串 S wchar_t字符(宽字符)类型字符串 %显示百分号本身 p显示一个指针,near指针表示为:XXXX,far指针表示为:XXXX:YYYY n相连参量应是一个指针,其中存放已写字符的个数 flags:规定输出格式 无右对齐,左边填充0和空格 -左对齐,右边填充空格 +在数字前增加符号+或- 0 将输出的前面补上0,直到占满指定列宽为止(不可以搭配使用-) 空格输出值为正时冠以空格,为负时冠以负号 #当type=c,s,d,i,u时没有影响;当type=o,x,X时,分别在数值前增加'0',"0x","0X"; 当type=e,E,f时,总是使用小数点;当type=g,G时,除了数值为0外总是显示小数点。 width:用于控制显示数值的宽度 n(n=1,2,3...)宽度至少为n位,不够以空格填充 0n(n=1,2,3...)宽度至少为n位,不够左边以0填充 *格式列表中,下一个参数还是width prec:用于控制小数点后面的位数 无按缺省精度显示 0当type=d,i,o,u,x时,没有影响;当type=e,E,f时,不显示小数点 n(n=1,2,3...)当type=e,E,f时,表示的最大小数位数

基于51系列单片机串行多通道数据采集系统设计

基于51系列单片机串行多通道数据采集系统设计(南京铁道职业技术学院,江苏苏州,黄克亚215137) 【摘要】:摘要:本文详细介绍了11通道12位串行AD转换芯片器TLC2543的结构、主要特点、工作原理与编程要点。给出了TLC2543与51系列单片机的硬件接口电路和软件控制程序,并在Proteus软件中进行系统仿真。 【关键词】:单片机、TLC2543 、C语言、仿真 引言:51系列单片机因其优越的性能,较低的价格,灵活方便的控制方法获得广泛应用,但是作为数字系统的单片机要想处理现实中广泛存在模拟量就必须进行AD转换。目前AD转换芯片有很多,但大多数是精度不高,占用单片机太多的I/O口,使其应用受到很大的限制。本论文所讨论的是基于11通道、12位串行AD转换芯片TLC2543数据采集系统的实现。 1 TLC2543的特点及引脚 TLC2543是12 bit串行A/D转换器,使用开关电容逐次逼近技术完成A/D转换过程.由于是串行输入结构,能够节省51系列单片机的I/O资源.其特点有: 1)12 bit分辨率A/D转换器; 2)在工作温度范围内10us转换时间; 3)11个模拟输入通道; 4)3路内置自测试方式; 5)采样率为66啊kb/s 6)线性误差±1LSB(max); 7)有转换结束(EOC)输出; 8)具有单、双极性输出; 9)可编程的MSB或LSB前导; 10)可编程的输出数据长度. TLC2543的引脚排列如图1所示. 图l中AIN0~AINl0为模拟输入端;CS为片选端;DIN为串行数据输入端;DOUT为A/D转换结果的三态串行输出端;EOC为转换结束端;CLK为I/O时钟;REF+为正基准电压端;REF-为负基准电压端;VCC为电源;GND为地. 2 TLC2543的使用方法 2.1控制字的格式 控制字为从DATA INPUT端串行输人的8位数据,它规定了TLC2543要转换的模拟量通道、转换后的输出数据长度、输出数据的格式。其中高4位(D7~04)决定通道号,对于0通道至10通道,该4位分别为

单片机串口通信C程序及应用实例

一、程序代码 #include//该头文件可到https://www.wendangku.net/doc/96427177.html,网站下载#define uint unsigned int #define uchar unsigned char uchar indata[4]; uchar outdata[4]; uchar flag; static uchar temp1,temp2,temp3,temp; static uchar R_counter,T_counter; void system_initial(void); void initial_comm(void); void delay(uchar x); void uart_send(void); void read_Instatus(void); serial_contral(void); void main() { system_initial(); initial_comm(); while(1) { if(flag==1) { ES = 0; serial_contral(); ES = 1; flag = 0; } else read_Instatus(); } } void uart_send(void) { for(T_counter=0;T_counter<4;T_counter++) { SBUF = outdata[T_counter]; while(TI == 0);

TI = 0; } T_counter = 0; } uart_receive(void) interrupt 4 { if(RI) { RI = 0; indata[R_counter] = SBUF; R_counter++; if(R_counter>=4) { R_counter = 0; flag = 1; } } } void system_initial(void) { P1M1 = 0x00; P1M0 = 0xff; P1 = 0xff; //初始化为全部关闭 temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致 temp = 0xf0; R_counter = 0; T_counter = 0; } void initial_comm(void) { SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit Reload PCON = 0x80; //波特率不加倍SMOD = 1 TH1 = 0xfa; //baud: 9600;fosc = 11.0596 IE = 0x90; // enable serial interrupt TR1 = 1; // timer 1 RI = 0; TI = 0; ES = 1; EA = 1; }

用51单片机、8255、138、373等实现数码管显示按键数值的程序.(DOC)

姓名 专业 学号 2013年10月28日

随着单片机技术的飞速发展,在其推动下,现代的电子产品几乎渗透到了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高。 单片机具有体积小、功能强、应用面广等优点,目前正以前所未见的速度取代着传统电子线路构成的经典系统,蚕食着传统数字电路与模拟电路固有的领地。它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。同时,学习使用单片机了解计算机原理与结构的最佳选择。现在,这种单片机的使用领域已十分广泛。彩电、冰箱、空调、录像机、VCD、遥控器、游戏机、电饭煲等无处不见单片机的影子,单片机早已深深地融入我们每个人的生活之中。 单片机能大大地提高这些产品的智能性,易用性及节能性等主要性能指标,给我们的生活带来舒适和方便的同时,在工农业生产上也极大地提高了生产效率和产品质量。单片机按用途大体上可分为两类,一种是通用型单片机,另一种是专用型单片机。 课题要求: 用51单片机、8255、138、373等实现数码管显示按键数值的程序

各芯片资料: 1.8255芯片资料如下 用8255A可编程器件扩展并行接口 8255: 有三个八位的并行口:PA、PB、PC。 有三种工作方式:方式0,方式1,方式2。 逻辑结构图: 包含四个部分:●三个并行数据输入输出端口 ●两个工作方式控制电路 ●一个读写逻辑控制电路 ●八位总线缓冲器 ⑴.三个并行数据输入输出端口:A口;B口;C口

一般,A口,B口作为数据输入输出端口, C口作为控制/状态信息口,可以分为两个部分,分别与A口和B口配合使用,作为控制信息输出或状态信息输入。⑵.工作方式控制电路 工作方式控制电路有两个:A组控制和B组控制电路, A组控制用来控制A口和C口的上半部分PC7——PC4; B组控制用来控制B口和C口的下半部分PC3——PC0; 两组控制电路具有一个控制命令寄存器,用来接收来自 CPU的数据(控制字),以决定芯片的工作方式,或对 C口按位进行清“0”或者置“1”。 ⑶.总线缓冲器 三态双向八位缓冲器,作为微处理器数据总线与8255之间的接口,用来传送命令、数据及状态信息。 ⑷.读写逻辑控制电路 读写逻辑控制电路接受CPU来的控制信号:读、写、地址及复位信息,根据控制信号的要求,将数据读出,送往CPU,或者将CPU来的信息写入端口。 引脚说明: CS:片选信号,低电平有效,表示芯片被选中; RD:读操作,低电平有效,控制数据读出; WE:写操作,低电平有效,控制数据写入; A1,A0:地址线, 端口选择信号,用来选择8255内部端口:

puts()函数和printf函数的区别

puts()函数和printf函数的区别 puts()函数只用来输出字符串,没有格式控制,里面的参数可以直接是字符串或者是存放字符串的字符数组名。 printf()函数的输出格式很多,可以根据不同格式加转义字符,达到格式化输出。 puts()函数的作用与语句printf("%s\n",s);的作用形同。 例子: ①: #include int main( void ) { puts( "Hello world from puts!" ); //字符串,最后隐含带有'\0'字符 } Output Hello world from puts! ②: main() { static char a[] = {'H','I','!','!'}; puts(a); } 则输出Hi!!烫烫烫烫烫烫烫烫烫烫烫烫dhaklhdwuhdaghdagdak... (后面都是乱码)

原因: a在结尾处缺少一个空字符('\0'), 所以它不是一个串,这样, puts() 就不知道什么时候停止输出, 它将会把 a 后面内存单元中的内容都打印出, 直到它在什么地方碰到了一个空字符为止。 ③: //============== cat hello.c #include int main(void) { printf("hello world!\n"); } //======================== gcc -S hello.c -o hello.s 生成汇编代码 //======================== cat hello.s //========================= .file "hello.c" .section .rodata .LC0: .string "hello world!" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx)

相关文档
相关文档 最新文档