AVR串口通信初始化设置及例程0 本文关键词:串口,初始化,例程,设置,通信
AVR串口通信初始化设置及例程0 本文简介:Atmega128串口详解0000Atmega128有两个串口:USART0与USART1以USART0为例串口的初始化包括:传输模式的选择:同步还是异步,默认为异步模式,可通过选择USART控制和状态寄存器UCSR0C中的UMSEL位来选择,UMSEL为0,是异步模式.波特率的设置:通信的双方都必
AVR串口通信初始化设置及例程0 本文内容:
Atmega128
串口详解
0000
Atmega128有两个串口:USART0与USART1
以USART0为例
串口的初始化包括:
传输模式的选择:同步还是异步,默认为异步模式,可通过选择USART控制和状态寄存器UCSR0C中的UMSEL位来选择,UMSEL为0,是异步模式.
波特率的设置:通信的双方都必须有相同的波特率,波特率可以通过设置波特率发生寄存器UBRR0来确定,UBRR0为两字节16位的寄存器,可分为
UBRR0H和UBRR0L.同时起作用的还有UCSR0A中的波特率加倍位UX2,当UX2为1时设置的波特率加倍.
传输帧格式的设置:默认是8位数据位,一位停止位
发送接受的使能与中断:通过设置UCSR0B来根据需要选择接收或发送的使能和是否使用中断,对使用中断的USART操作,初始化前要关闭中断
USART0的控制和状态寄存器有:UCSR0A,UCSR0B,UCSR0C,波特率寄存器有UBRR0,即UBRR0H和UBRR0L,数据寄存器为UDR0
1、初始化:
设置波特率前,要关闭USART0的所有使用,包括使能和中断:
UCSR0B=0B00000000;
//关闭USART0
2、设置UCSR0A:
UCSR0A能写的有Bit0,Bit1,Bit6,其他5位为状态位.我们一般使用的有Bit1-U2X0,当这一位为1时,波特率的分频因子从16降到8,能够有效的将异步通信模式的传输速率加倍,但是这一位仅对异步操作有影响,使用同步操作时应将此位清零.
UCSR0A=0B00000000;
//不使用倍速发送
3、设置UCSR0C:
Bit6-UMSEL0:USART0的模式选择,0为异步模式,1为同步模式
Bit5:4-UPM01:0:奇偶校验模式,00禁止,01,保留,10偶校验,11,奇校验
Bit3-USBS0:停止位的选择,0停止位为1bit,1停止位为2-bits
Bit2:1-UCSZ01:0:字符长度,当UCSZ02为0时,00表示5位,01表示6位,10表示7位,11表示8位.当UCSZ02为1时,11表示9位.(UCSZ02为UCSR0B里的一位寄存器)
eg:
UCSR0C=0B00000110
//异步模式,禁止奇偶校验,停止位为1位,数据位为8位
4、设置UBRR:
UBRR的设置和这些参数有关:U2X0,CPU频率,波特率
当U2X0为0时,即异步正常模式下,UBRR的计算公式:
1、U2X=0时的公式计算
UBRR0L=
(F_CPU/BAUDRATE/16-1)%256;
UBRR0H=
(F_CPU/BAUDRATE/16-1)/256;
2、U2X=1时的公式计算
UBRRL=
(F_CPU/BAUDRATE/8-1)%256;
UBRRH=
(F_CPU/BAUDRATE/8-1)/256;
//也可根据数据手册的[波特率设置的例子]查得
//UBRRL
=
0x2F;
//set
baud
rate
lo
//UBRRH
=
0x00;
//set
baud
rate
hi
设置一般会有误差,误差计算方法为:Error[%]=(BaudRate_ture/BaudRate-1)*100%;
5、然后就是设置UCSR0B:
Bit7-RXCIE0为接收结束中断使能,Bit6-TXCIE0为发送结束中断使能,Bit4-RXEN0为接收使能,Bit3-TXEN0为发送使能.一般情况下,接收使用中断方式,所以使用接收结束中断使能.
UCSR0B=0B10011000
//发送接收使能,接收结束使能
还一种写法是UCSR0B|=(1<<
RXEN0)|(1<<
TXEN0)|(RXCIE0);
如果更熟练,可以直接以10进制活16进制来设置这些寄存器:
UCSR0B=0x98;或者UCSR0B=152;
串口的初始化函数:
void
uart_init(void)
//串口0初始化
{
UCSR0B=0x00;
//disable
while
setting
baud
rate
UCSR0A=0B00000000;
//Bit1为1则倍速发送
U2X=0
UCSR0C=0x06;
//B00000110
//奇偶模式无,八位数据位,一位停止位
UBRR0L=103;
//B00011001波特率:9600
Bps
UBRR0H=0x00;
//误差率:0.156%
UCSR0B=0x98;
}
初始化之后就是对USART0进行读写了.
UCSR0A的Bit5-UDRE0标志指出发送缓冲器UDR0是否准备好接收新数据,UDRE0为1说明缓冲器为空,可以接收新数据,UDRE0标志也可用来产生寄存器空中断.复位后的UDRE0置位,表明发送器已经就绪:
当UDRE0为1时!(UCSR0A
//while(!(UCSR0A
表明发送器已经就绪。
UDR0=c;
}
串口0发送字符串:
void
putstr(uchars)
//串口0发送字符串
{
while(*s)
{
putchar(*s);
s++;
}
}
RXC0为UCSR0A里的Bit7位,为USART0接收结束的状态位,接收缓冲器中有未读出的数据时RXC0置位,否则清零.
串口0接收字符:
uchar
getchar(void)
//串口0接收字符
{
while(!(UCSR0A
return
UDR0;
}
在使用串口的程序中一般包含这些文件:
#include
#include
#include
#include
avr/io.h里有各种寄存器的定义,avr/signal.h,avr/interrupt.h里有中断的定义,avr/delay.h包含延时函数.
转自
http://blog.csdn.net/gnuhpc/archive/2009/07/24/4378251.aspx
例程如下:
/***************************************************************************/
/*串口0测试程序/
/*目标器件:ATmega128/
/*晶振:RC
8MHZ/
/*编译环境:ICCAVR
6.31A/
/*E-Mail:[email protected]/
/***************************************************************************/
/*********************************包含头文件********************************/
#include
#include
/***********************************宏定义**********************************/
#define
fosc
8000000
//晶振8MHZ
#define
baud
2400
//波特率
/****************************************************************************
函数功能:uart0初始化程序
入口参数:
出口参数:***************************************************************************/
void
uart0_init(void)
{
UCSR0B
=
0x00;
//关闭UART00
UCSR0A
=
0x00;
//不使用倍速发送(异步)
UCSR0C
=(1< //数据位为8位 UBRR0L=(fosc/16/(baud+1))%256; //异步正常情况下的计算公式 UBRR0H=(fosc/16/(baud+1))/256; UCSR0B =(1< //接收使能和发送使能 } /**************************************************************************** 函数功能:uart0发送单字节数据 入口参数:c 出口参数:***************************************************************************/ void putchar0(unsigned char c) { while (!(UCSR0A//表明发送器已经准备就绪 UDR0=c; //将要发送的数据装入UDR0寄存器 } /**************************************************************************** 函数功能:uart0接收单字节数据 入口参数: 出口参数:***************************************************************************/ unsigned char getchar0(void) { while(!(UCSR0A//表明已经接收完毕 return UDR0; } /**************************************************************************** 函数功能:uart0发送字符串数据 入口参数:*s 出口参数:***************************************************************************/ void puts0(chars) { while (*s) { putchar0(*s); s++; } putchar0(0x0a);//回车换行 putchar0(0x0d); } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数:***************************************************************************/ void main(void) { unsigned char i; uart0_init();//UART0初始化 puts0(“HELLO!“); while(1) { puts0(“test ok!“); } }
篇2:VerilogRS232串口模块实验报告
VerilogRS232串口模块实验报告 本文关键词:串口,模块,实验,报告,VerilogRS232
VerilogRS232串口模块实验报告 本文简介:1设计概述实验功能:实现RS232的双工通信。实验环境:1)硬件环境:PC机一台、ml507PFGA开发套件;2)软件环境:开发软件ISE14.5、代码编写软件Notepad++、仿真软件Modelsim、调试软件chipscope、串口调试工具。2设计原理2.1串行接口RS232工作原理串口用来连
VerilogRS232串口模块实验报告 本文内容:
1
设计概述
实验功能:实现RS232的双工通信。
实验环境:1)硬件环境:PC机一台、ml507PFGA开发套件;2)软件环境:开发软件ISE14.5、代码编写软件Notepad++、仿真软件Modelsim、调试软件chipscope、串口调试工具。
2
设计原理
2.1
串行接口RS232工作原理
串口用来连接FPGA和PC机,RS-232允许全双工通信,即计算机在接收数据的同时可以发送数据。串口按位(bit)发送和接收字节。通常以8位数据为1组,先发送最低有效位,最后发送最高有效位。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。
通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。数据的传输没有时钟信号,接收端必须采取某种方式,使之与接收数据同步。
1)串行线缆的两端先约定好串行传输的参数(传输速度、传输格式等);
2)当没有数据传输的时候,发送端向数据线上发送“1“;
3)每传输一个字节之前,发送端先发送一个“0“来表示传输已经开始,这样接收端便可以知道有数据到来了;
图1
数据帧结构
4)开始传输后,数据以约定的速度和格式传输,所以接收端可以与之同步;
5)在串口总线上‘高电平’是默认的状态,当一帧数据开始传输必须先拉低电平,这就是起始位,起始位之后是8位数据位,最后是校验位和停止位(可不加校验位)。传输完成一个字节之后,都在其后发送一个停止位(“1“)。(图1)
2.2
波特率发生器
波特率是串口传输的传输速度;在微观上就是一个位的周期。常用的波特率有9600bps和115200bps。“9600bps”表示每秒可以传输9600位。本次实验我所选用的传输速率为9600bps。由于我们的FPGA通常运行在远高于9600Hz的频率上(100MHz),因此需要分频产生接近9600Hz的时钟信号。若FPGA时钟为100MHz,则需要100M/9600=10416个时钟周期置位一次就可以得到9600Hz的时钟。
3
模块组成
3.1接收模块
接收模块示意图(图2)
图2
接收模块示意图
串口接收包括三个模块:电平检测模块,用来检测数据开始,当检测到输入信号RX_Pin_In有下降沿时,可以判断信号到来,H2L_Sig信号输出为高电平通知接收控制模块准备接收数据;波特率定时模块,用来产生波特率(9600bps);接收控制模块,用来控制接收开始和结束。RX_En_Sig为高电平时,若电平检测模块检测到有数据输入,则发出H2L_Sig高电平信号,接收控制模块输出Count_Sig信号,波特率定时模块开始计数。
为了确保采集到的数据的准确性,数据采集都是在每位数据的中间进行着(图3)。为使采集信号出现在数据位中间,决定每次计数到5208产生一个采集信号BPS_CLK,持续一个时钟周期,计数到10416时计数器清零并重新计数,这样采集信号周期不变,准确度提高。
图3
数据定时采集示意图
接收控制模块将8位数据位并行输出,输出RX_Done_Sig信号表示一帧数据结束,发送模块可以接收来自RX_Data的数据。
3.1.1
detect_module.v
detect_module.v这个功能模块是为了检查电平由高变低。当检测到电平又高变低,在第40行就会输出高脉冲。
3.1.2
rx_bps_module.v
波特率定时模块,用来产生波特率,其原理同计数器。当rx_control_module.v拉高Count_Sig,bps_module.v经BPS_CLK对
rx_control_module.v
产生定时。
3.1.3
rx_control_module.v
rx_control_module.v是核心控制模块,用来控制接收开始和结束。对串口的配置主要是1帧11位的数据,重视八位数据位,无视起始位,校验位和结束位。当RX_En_Sig拉高,这个模块就开始工作,它将采集来自RX_Pin_In的数据,当完成一帧数据接收的时候,就会产生一个高脉冲给
RX_Done_Sig。
44~62行是rx_control_module.v的核心控制功能。当rx_control_module.v模块被使能,该模块就会处于就绪状态,一旦detect_module.v检查到又高变低的电平变化(47行),会使步骤i进入第0位采集,然而isCount
标志寄存器同时也会被设置为逻辑1,rx_bps_module.v
便会开始产生波特率的定时。
3.1.4
rx_module.v
rx_module.v是一个组合模块,主要是包含detect_module.v,bps_module.v和
rx_control_module.v,2个功能模块,和1个组合模块。完成对三个模块的例化及信号传递。
3.2
发送模块
发送模块示意图(图4)
图4
发送模块示意图
发送模块包括波特率定时模块,当TX_En_Sig低电平时不工作,高电平时开始计数,然后产生一个高脉冲经BPS_CLK输出给发送控制模块;发送控制模块在TX_En_Sig高电平时,每收到一个BPS_CLK,将TX_Data的数据,由TX_Pin_Out输出。当一帧数据发送完毕后,产生一个TX_Done_Sig的高脉冲(图5)。
图5
数据定时发送示意图
3.2.1
tx_bps_module.v
tx_bps_module.v同样是作为“定时”的功能。当TX_En_Sig拉低电平的时候,它是处于随眠的状态。一旦TX_En_Sig拉高电平,那么tx_bps_module.v就开始计数。然后定时产生一个高脉冲经BPS_CLK给tx_control_module.v。程序与rx_bps_module.v基本相同。
3.2.2
tx_control_module.v
tx_control_module.v控制模块是最为中心的一部分,当TX_En_Sig拉高电平,同时间tx_bps_module.v也会开始计数。tx_control_module.v将TX_Data的值,按tx_bps_module.v产生的定时,有节奏的往TX_Pin_Out发送。当一帧数据发送完毕后,就产生一个TX_Done_Sig的高脉冲。
3.2.3
tx_module.v
4
功能仿真
4.1
接收模块仿真
4.1.1
接收模块验证程序
增加一个control_module.v模块,一开始control_module.v会拉高
RX_En_Sig使能rx_module.v。当有一阵数据经RX_Pin_In传入,rx_module.v就会接收然后将输出输出致RX_Data,再产生一个高脉冲给RX_Done_Sig。当control_module.v
接收到RX_Done_Sig的高脉冲,就会将RX_Data的“前四位”输出致4位LED资源。rx_module_demo.v为一组合模块,完成对control_module.v和rx_module.v的例化。tb_RX_DATA.v为测试文件。
1)control_module.v
一开始的时候(36行)就将isEn设置为逻辑1,这个标志寄存器在38行驱动着
RX_En_Sig,即此时的rx_module.v已经进入就绪状态,control_module.v等待着
RX_Done_Sig的通知(34行)。一旦一帧数据接收完毕,RX_Done_Sig就会产生高脉冲,然后rData被赋予RX_Data的值,同时isEn被设置为逻辑0(35行)。在下一瞬间,control_module.v再一次设置isEn为逻辑1,做好接收下一组数据的准备。
2)rx_module_demo.v(略)
3)tb_RX_DATA.v
测试文件输出的数据为“1111_1111”。
4.1.2
Modelsim的仿真
仿真结果(图6)
图6
接收模块验证仿真结果
可以看出,该程序能够正确判断数据帧的起始位和终止位,正确接收了数据帧“1111_1111”,并将高四位赋给了Number_Data,来控制四个LED灯。
4.2
发送模块仿真
4.2.1
发送模块验证程序
增加一个control_module.v模块,主要是每秒往tx_module.v发送0x31的数据。一开始control_module.v往TX_Data输出数据,然后拉高TX_Done_Sig使
tx_module.v开始工作。当
tx_module.v
发往一帧数据以后,就会对
TX_Done_Sig
产生一个高脉冲,以示发送完毕。tx_module_demo.v为一组合模块,完成对control_module.v和tx_module.v的例化。tb_TX_DATA.v为测试文件。
1)control_module.v
第28行是1秒的定义常量,在30~36行是1秒的定时器。control_module.v主要是每秒发送0x31的数据,也就是每秒设置一次
isEn标志寄存器。当isEn被设置后,tx_module.v就会开始工作,发完一帧数据位TX_Done_Sig会产生高脉冲。这使得control_module.v会重新赋值rData寄存器,然后复位isEn标志寄存器。直到下一秒的到来,isEn标志寄存器会再一次被设置。
2)tx_module.v(略)
3)tb_TX_DATA.v
4.2.2实验仿真
为了便于仿真,将常量T1S=25’d19_999。仿真结果(图7)
图7
发送模块验证仿真结果
可以看出,TX_Pin_Out正确发送起始位“0”,数据位“1000_1100”,终止位“1”。
5
总结
篇3:基于串口通信的LCD显示
基于串口通信的LCD显示 本文关键词:串口,通信,显示,LCD
基于串口通信的LCD显示 本文简介:目录引言11设计任务与目的21.1设计任务:21.2设计目的:22串口通信原理22.1串行口工作原理22.3方案论证43硬件设计63.1AT89S52最小系统63.3LCD显示电路73.4max232电平转换电路84软件设计94.1主程序流程图94.2LCD显示函数104.3键盘函数105系统调试1
基于串口通信的LCD显示 本文内容:
目
录
引言1
1
设计任务与目的2
1.1
设计任务:2
1.2
设计目的:2
2
串口通信原理2
2.1
串行口工作原理2
2.3
方案论证4
3硬件设计6
3.1
AT89S52最小系统6
3.3
LCD显示电路7
3.4
max232电平转换电路8
4
软件设计9
4.1主程序流程图9
4.2
LCD显示函数10
4.3
键盘函数10
5系统调试11
5.1
硬件调试11
5.2
软件调试11
6
结论11
参考文献12
引言
51单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。在国内外,以PC机作为上位机,单片机作为下位机的控制系统中,PC机通常以软件界面进行人机交互,以串行通信方式与单片机进行积极交互的技术得到越来越大的重视和越来越广泛的应用。LCD显示技术是一门新兴的显示技术,相对于LED显示,LCD显示有节能,能显示的更多以及更高端等优点。本次课程设计选用串行通信和LCD显示来进一步加深我们对于单片机的理解。
1
设计任务与目的
1.1
设计任务:
(1)下位机选用89S51或89S52单片机;
(2)下位机接收上位机的数据并显示在LED或LCD上
(3)下位机显示数据可以显示固定数据、以为数据、循环移位;
(4)硬件要求:制作串口线和下位机及外围电路;
(5)软件要求:keil
c或汇编编程设计,串口调试助手或labview串口通信编程。
1.2设计目的:
(1)通过串口实现下位机与上位机之间的相互通信。
(2)通过设计将串口通信的各种方式进行进一步的了解。
(3)将接收的数字与发送的数字在LCD上进行显示,从而熟悉液晶显示屏LCD1602
的具体操作。
(4)熟练掌握C语言在单片机上的编程应用。
(5)将各学科之间的的知识进行综合运用,并能够实现所需的功能设计。
2
串口通信原理
串行通信是CPU与外界交换信息的一种基本通信方式。通信时仅需一到两根传输线,且每次只能传送一位,适用于长距离传输,但速度较慢。MCS—51串行口是一个可编程的全双工串行通信接口,其对应的引脚为P3.0(10脚)和P3.1(11脚),分别为RXD和TXD,通过软件编程它可以作通用异步收发器用,也可以做同步移位寄存器使用,其帧格式有8位、10位和11位3种,并能设置各种波特率。MCS—51串行口有两个独立的缓冲器,即发送缓冲器和接收缓冲器,且共用一个地址99H(SBUF)。同时,MSC—51串行口可以用软件设置成4种不同的工作方式。
2.1
串行口工作原理
通过对特殊功能寄存器—串行口控制寄存器中SM0、SM1两位的操作,MCS—51单片机串口通信工作方式有4种,与串行口有关的特殊功能寄存器有串行口控制寄存器SCON、电源控制寄存器PCON和定时器T1,主要确定了串口通信的工作方式和波特率的计算方法。
(1)串行口数据缓冲器SBUF
SBUF是两个在物理上相互独立的接收,发送缓冲器,可同时发送,接收数据,两个缓冲器共用一个字节地址,为99H,可字节寻址,不可位寻址,复位值为00H。可通过编程对SBUF的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。CPU写SBUF,就是修改发送缓冲器;
CPU读SBUF,就是读接收缓冲器,在硬件结构上,串行口对外有两条独立的收发信号线RXD和TXD,因此可以同时发送,接收数据,实现全双工传送。
(2)串行口控制寄存器SCON
SCON寄存器用于确定串行通信的工作方式、接收和发送控制、串行口的中断状态标志,它既可以是字节寻址,也可以是位寻址,字地址为98H,其复位值为00H。
SM0,SM1—工作方式控制位,可构成4种通信工作方式,分别为:方式0-同步移位寄存器;方式1-10位异步收发;方式2-11位异步收发;方式3-11位异步收发。
SM2—多机通信控制位,用于主一从式多机通信控制,因多机通信是在方式2和方式3下进行,因此SM2位主要用于方式2和方式3。若SM2=1,则允许多机通信。若SM2=0,则不属于多机通信情况,接收到一帧数据后,无论第9位(D8)是0还是1,都置中断标志RI=1,接收到的数据装入接收/发送缓冲器(SBUF)中。
在工作方式1时,若SM2=1,则只有接收到有效停止位时中断标志RI才置1,以便接收下一帧数据;在工作方式0时,SM2必须为0。
REN—允许接收控制位,用软件置1或清零,REN=1,允许接收;REN=0,禁止接收。
TB8—发送数据位8,在方式2和方式3时,TB8是要发送的第9位数据。在多机通信中,以TB8位的状态表示主机发送的是地址还是数据:TB8=0为数据,TB8=1为地址,该位由软件置位或清零,此外,该位还可以作为数据的奇偶检验位。
RB8—接收数据位8,在工作方式2和工作方式3种,它是接收到的第9位数据位,既可以作为约定好的奇偶检验位,也可以作为多机通信时的地址帧或数据帧标志。在工作方式1中若SM2=0,则RB8是接收到的停止位,在工作方式0种不使用RB8。
TI—发送中断标志位,在工作方式0中,发送完8位数据后,由硬件置1,向CPU申请接收中断,CPU响应中断后,必须用软件清零;在其他方式下,在发送停止位前,由硬件置位。
RI—接收中断标志位。在工作方式0种,接收完8位数据后,由硬件置1,向CPU申请发送中断,CPU响应中断后,必须用软件清零;在其他方式下,在接收到停止位的中间时刻由硬件置1,中断响应后也必须用软件清零。
串行发送中断标志位TI和接受中断标志位RI是同一个中断源,在全双工通信中,必须用软件来判别是发送中断请求还是接收中断请求。
(3)电源控制寄存器PCON
PCON主要是为CHMOS型单片机上实现电源控制而设置的专用寄存器,单元地址为87H其中只有一位SMOD与串行口工作有关。SMOD称为波特率选择位。在工作方式1,2,3中若SMOD=1,则波特率提高一倍;若SMOD=0,则波特率不加倍。
除了以上3种特殊功能寄存器以外,串口的工作还与定时器T1和中断允许寄存器IE有关,定时器T1主要在工作方式1,工作方式2中用于计算波特率,而IE主要用于接收/发送中断的允许控制,ES=0,禁止串行中断,ES=1,允许串行中断。
2.2串行通信的波特率
在使用串口做通讯时,一个很重要的参数就是波特率,只有上下位机的波特率一样时才可以进行正常通讯。波特率是指串行端口每秒内可以传输的波特位数。51芯片的串口工作模式0的波特率是固定的,为fosc/12,以一个12M的晶振来计算,那么它的波特率可以达到1M。模式2的波特率是固定在fosc/64或fosc/32,具体用那一种就取决于PCON寄存器中的SMOD位,如SMOD为0,波特率为focs/64,SMOD为1,波特率为focs/32。模式1和模式3的波特率是可变的,取决于定时器1或2(52芯片)的溢出速率。计算这两个模式的波特率可以用以下的公式去计算。
波特率=(2SMOD÷32)×定时器1溢出速率
(1)
上式中如设置了PCON寄存器中的SMOD位为1时就可以把波特率提升2倍。通常会使用定时器1工作在定时器工作模式2下,这时定时值中的TL1做为计数,TH1做为自动重装值,这个定时模式下,定时器溢出后,TH1的值会自动装载到TL1,再次开始计数,这样可以不用软件去干预,使得定时更准确。在这个定时模式2下定时器1溢出速率的计算公式如下:
溢出速率=(计数速率)/(256-TH1)
(2)
上式中的“计数速率”与所使用的晶体振荡器频率有关,在51芯片中定时器启动后会在每一个机器周期使定时寄存器TH的值增加一,一个机器周期等于十二个振荡周期,所以可以得知51芯片的计数速率为晶体振荡器频率的1/12,一个12M的晶振用在51芯片上,那么51的计数速率就为1M。通常用11.0592M晶体是为了得到标准的无误差的波特率。如我们要得到9600的波特率,晶振为11.0592M和12M,定时器1为模式2,SMOD设为1,分别看看那所要求的TH1为何值。代入公式:
当晶振为11.0592MHZ时:
9600=(2÷32)×((11.0592M/12)/(256-TH1))
TH1=250
当晶振为12MHZ时:
9600=(2÷32)×((12M/12)/(256-TH1))
TH1≈249.49
上面的计算可以看出使用12M晶体的时候计算出来的TH1不为整数,而TH1的值只能取整数,这样它就会有一定的误差存在不能产生精确的9600波特率。
本次设计中为了得到精确地波特率,采用的晶振频率为11.0592MHz,此外定时器工作在方式2,即八位自动重装载,串口工作在方式1.
2.3
方案论证
方案一:USB转串口通信实现传输数据,使用LED显示。LED显示原理简单,容易实现,但功能不强大,技术落后。
上位机
USB转串口通信信
AT89S52
LED显示
图2.1方案一系统框图
方案二:使用max232芯片来进行RS485和TTL电平之间的转换,能够更好的理解串口通信。使用LCD来进行显示,功能更加强大。使用按键来控制LCD所显示的数字进行移位显示或循环移位显示。综合考虑,方案二更能体现本次课设的内容,更能加深我们队串口通信的理解,但是考虑到现在计算机都没有串口,使用USB转串口。
按键控制
LCD1602
显示
AT89S52
单片机
系统组成框图
Max232
电平转换
上位机
串行通信
图2.2
方案二系统框图
3硬件设计
3.1
使用AT89S52作为本系统的主控机
图3.1单片机工作电路
AT89S52是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,而且它与MCS-51兼容,且具有4K字节可编程序存储器和1000次擦写循环,数据保留时间为10年,是最好的选择。
3.2
采用按键复位电路
图1.2
按键复位电路
3.3
采用LCD显示电路
图1.3
LCD显示电路
分别使用P2.0,P2.1,P2.2作为LCD的控制端,P0口作为数据的输入端,使用一个10K的滑动变阻器来调节LCD的对比度。
3.4
max232电平转换电路
图1.4
串行通信电路
插座的2脚接电脑的数据发送端,插座的三脚接电脑的接收端。
3.5
按键电路
图1.5
按键电路
通过读取P2口的电平来判断是否有键按下。
4
软件设计
4.1主程序流程图
开始
初始化液晶
初始化串口
接收到数据
接收数据
否
是
是
否
接收完
调用键盘扫描函数
键值为0x40,数据右移一位
键值为0x80,数据循环右移
键值为0,调显示函数
返回
图4.1主程序流程图
本程序采用模块化设计,使用函数来实现要实现的功能。主要的几个函数有LCD显示函数,按键扫描函数和串口中断函数。通过串口中断函数来改变字符串的内容,调用按键函数确定键值,根据键值来确定固定显示,循环显示和移位显示。最后调用LCD显示函数吧字符串显示出来。
4.2
LCD显示字符串函数和显示字符函数。
要显示的字符,地址作为实参
要显示的字符串作为实参
是否在第一行
调用显示一个字符函数
否
否
是
地址加c0
地址加80
是否显示完
写入数据
是
结束
图4.2显示函数流程图
显示字符串是通过调用显示函数来实现的,有三个参数,分别为要显示的字符,横坐标,纵坐标。显示字符是先确定地址,再把数据写入。
4.3
键盘函数判定有键按下
调用键盘处理函数
去抖动
返回键值
图4.3键盘函数
键值处理函数是把P2口的值取反,然后屏蔽低四位得到键值。
5系统调试
普遍情况下一个系统只有经过调试才会正常工作,在调试过程中我们能加深对系统的理解,发现自己的错误。
5.1
硬件调试
硬件要实现的有LCD能正常显示,按键正常工作,串口能正常通信。
5.1.0
LCD
调试
使用KEIL3写一个简单的LCD显示函数生成HEX文件,首先我在proteus
ISIS7中对实验进行了仿真,确定程序是可行的。但将程序拷进单片机中后LCD不能正常显示,经过询问同学我得知可能是我的电位器没调好,经过调试电位器LCD能正常显示。
5.1.1
按键调试
使用万用表分别检测按键没按下和按下时的电位,发现能达到预期的目标。但编程时发现我的P2.0,P2.1,P2.2口已经在LCD上用了。只能把先断开,再跳线到P2.5,P2.6,P2.7,能够正常实现按键功能。
5.1.2
串行通信调试
一开始总是不能正常通信,经过耐心的检查发现时串行线连接错误。
5.2
软件调试
软件调试采用仿真和现场调试相结合的方法,先一个个函数实现,再把所有的程序整合起来实现预期的功能。
6
结论
经过调试,本次设计住实现了上位机与下位机之间简单的通信,上位机通过LABVIEW程序发送一个十六进制的数经过串口,可以被下位机接收,并在LCD进行显示,而且实现根据按键来控制固定显示、移位显示和循环移位显示。,通过本次设计,对单片机串口通信这部分的内容进行了更深层次的学习,知道了很多书本上学不到的东西。并且在本次设计中采用LCD显示,开始觉得LCD很高端,但通过查阅资料和询问同学老师很轻松的就掌握了它的使用。本次设计所要求的移位显示,一开始使用移位指令。结果发现显示的时候会有残影,使用没显示一次清屏一次的办法解决了这个问题。
总之,通过本次设计锻炼了我查找错误时的耐力,锻炼了我调试软硬件的能力,也是我对与C语言在单片机上的编程变得更加熟练,为以后进一步学习打下了坚实的基础。
参考文献
[1]谭浩强,C程序设计[M]北京:清华大学出版社,2010.6:25~30
[2]白驹珩、雷晓平,单片计算机及其应用[M]北京:高等教育出版社,2005.9:30~50
[3]王选民,智能仪器原理及设计[M]北京:清华大学出版社,2008.7:123~140
[4]黄冰,微机原理及应用[M]重庆:重庆大学出版社,2003.1:229~231
[5]史志举,PC机与AT89C51单片机的串行通信系统设计[D]江苏:河海大学
附
录
附图一:原理图
附图二:PCB图
附图三:仿真电路图
16