单片机C语言部分资料

发布时间 : 星期六 文章单片机C语言部分资料更新完毕开始阅读

方式1波特率 = 2?(定时器溢出率)/32

其中SMOD是PCON的第7位,定时器的溢出率为定时器定时时间的倒数,定时器工作模式0、1和2都可以使用。

3.方式2和方式3

这两种方式都是11位异步接收/发送方式,操作方式完全一样,只是波特率有所区别,方式3波特率同方式1,方式1波特率为:

SMOD

方式2波特率 = 2?(定时器溢出率)/64

方式2和方式3的发送起始于数据写入SBUF指令,当第9位数据TB8输出之后,TI置位。

方式2和方式3接收数据的前提也是REN = 1,在第9位数据接收到之后,如果下列提条件满足,即RI = 0且SM2 = 0或接收到的第9位数据为1,则将已经接受的数据装入SBUF和RB8,并置位RI,如果条件不满足,则接收无效。

三、串行口通信初始化

1.串行口的波特率与定时器设置

单片机的晶体振荡频率比较固定,常用的有6MHz、12 MHz、11.0592 MHz,单片机串行口用于和计算机通信,选用的波特率也相对固定,可以通过查表获得相应设置,表3-6-2给出了单片机常用的波特率与定时器设置。

表3-6-2单片机常用的波特率与定时设置 串行口工作方式 波特率(bps) fOSC=6MHz SMOD TMOD 0 2 1M 375K 187.5 K 1 或 3 62.5K 19.2K 9.6 K 4.8 2.4 1.2 600 ― ― 1 ― ― ― ― 1 1 1 ― ― × ― ― ― ― 20 20 20 TH1 ― ― × ― ― ― ― 0xf3 0xe6 0xcc fOSC=12MHz SMOD TMOD × 1 0 1 ― ― 1 0 0 0 × × × TH1 × × × fOSC=11.0592MHz SMOD TMOD ― ― ― ― 1 0 0 0 0 0 ― ― ― ― TH1 ― ― ― ― SMOD

0x20 0xff ― ― ― ― 0x20 0xfd 0x20 0xfd 0x20 0xfa 0x20 0xf4 0x20 0xe8 0x20 0xd0 0x20 0xf3 0x20 0xf3 0x20 0xe6 0x20 0xcc 2.初始化步骤

下面以波特率为9600bps,串口工作方式3,允许发送/接收数据的初始化步骤程序举例:

/*********************************/

TMOD = 0x20; //第一步,编程TMOD

TL1 = 0xfd; //第二步,装载定时器1的初值 TH1 = 0xfd;

TR1 = 1; //第三步,启动定时器1, TR1 = 1

SCON = 0xd8; //第四步编程SCON,确定串行口工作方式3

//SM2、TB8 = 1,TI、RI = 0

PCON = 0x00; //第四步,编程PCON,SMOD = 0

SBUF = date1; //发送1字节数据date1,进入串行中断 while(TI == 0); //等待发送,发送完毕后TI自动置位 TI = 0; // TI软件清零

date2 = SBUF; //接收1字节数据并保存在date2,进入串行中断 while(RI == 0); //等待接收,接收完毕后RI自动置位 RI = 0; // RI软件清零

/*********************************/

3.6.2单片机与计算机之间通信

本案例实现计算机键盘输入的字符通过计算机的COM1向单片机发送,单片机接收后随即把这个字符再向计算机发送,并在计算机的屏幕上显示出来。电路原理见图3-6-1,计算机和单片机之间通过串行电缆连接。

一、 程序设计

由于计算机作为上位机控制,因此本案例程序包括计算机的发送/接收程序和单片机的数据接收/发送程序。上位机程序采用BASIC编写,编写的文件后保存为RS232.BAS。单片机串口通信采用同样的参数设置。

1.上位机程序

/*****************************************************************************/ 10 OPEN”COM1:9600,N,8,1,CS,DS,CD”AS#1 20 IF LOC(1)>0 THEN GOSUB 1000

30 A$ = INKEY$:IF A$<>””THEN GOSUB 2000 40 GOTO 20

1000 A$ = INPUT$(LOC(1)),#1) 1010 PRINT A$; 1020 RETURN 2000 PRINT #1,A$ 2010 RETURN

/*****************************************************************************/

2.单片机通信程序

/*****************************************************************************/

#include void main(void)

{ unsigned char date;

TMOD = 0x20;

TL0 = 0xfd;TL1 = 0xfd; SCON = 0xd8;PCON = 0x00; TR1 = 1; While(1)

{ while(RI == 0); //等待接收

RI = 0;

date = SBUF; //接收数据保存在date中

SBUF = date; //再保存在date的数据向外发送 while(TI == 0); //等待发送 TI = 0; } }

/*****************************************************************************/

3.程序说明

(1)计算机串行口发送/接收数据的波特率为9600,1位停止位,无奇偶校验。其设置

参考有关书籍。

(2)也可以采用VB编写,也可以直接使用51单片机的串行通信调试助手ComAssistant等小软件。

3.6.3 单片机串口中断应用

使用8051串行口实现中断驱动串行I/O。中断程序使用8字节的环形缓冲器处理发送中断和接收中断。

/*****************************************************************************/ #include #include

#define XTAL 11059200 //CPU振荡器频率 #define baudrate 9600 //9600通信波特率

#define OLEN 8 //串行发送缓冲区的大小 unsigned char ostart; //发送缓冲区起始索引 unsigned char oend; //发送缓冲区结束索引

char idata outbuf[OLEN]; //发送缓冲区的存储

#define ILEN 8 //串行接收缓冲区的大小 unsigned char istart; //接收缓冲区起始索引 unsigned char iend; //接收缓冲区结束索引 char idata inbuf[ILEN]; //接收缓冲区的存储

bit sendfull; //标志:标识发送缓冲区满 bit sendactive; //标志:标识发送器激活 /* 串行中断服务程序 */

static void com_isr(void)interrupt 4 {

char c;

/ *--------------------接收数据中断------------------------* / if(RI){

c=SBUF; //读字符

RI=0; //清零中断请求标志 if(istart+ILEN!=iend {

inbuf[iend++&(ILEN-1]=c; 字符送入缓冲区 } }

/ *-------------------------发送数据中断-------------------------* / if(TI!=0) {

TI=0; //清零中断请求标志 if(ostart!=oend) { //若字符在缓冲区 SBUF=outbuf[ostart++ &(OLEN-1]; //则发送字符

sendfull=0; //清零sendfull标志 }

else{ //若所有字符发送 sendactive=0; //则清零sendactive } } }

/ *初始化串行口和UART波特率函数 */ void com_initiaize(void){

istart=0; //清空接收缓冲区 iend = 0;

ostart=0; //清空发送缓冲区 iend=0;

sendactive=0; //发送器未激活

sendfull=0; //清零sendfull标志

//配置定时器1作为波特率发生 POCN |= 0x80; //0x80=SMOD:设置波特率加倍 TMOD |= 0x20; //置定时器1为方式2 TH1=(unsigned char)(16L*12L*baudrate)));

TR1=1; //启动定时器1

SCON=0x50; //串行口方式1,允许串行接收 ES=1; //允许串行中断 }

/* putbuf:写字符到SBUF或发送缓冲区 */ void putbuf(char c){

if(!sendactive){ //若发生器未激活

sendactive=1; //则直接传送第一字符到 SBUF = 0; //SBUF启动发生器 } else{

ES=0; //在缓冲区更新期间禁止串行中断 outbuf[oend++&(OLEN-1)=c; //放字符到发送缓冲区 if(((oend ^ostart)&(OLEN-1))==0) { sendfull=1;

} //若缓冲区满置标志

ES=1; //则再次允许串行口中断 } } }

/*替换标准库函数putchar程序*/

/*printf函数使用putchar输出一个字符*/ char putchar(char c){

if(c=='/n'){ //扩展新一行字符 while(sendfull); //等待直到缓冲区有空间

putbuf(0x0D); //在LF前发送CR用于<新行> }

while(sendfull); //等待直到缓冲区有空间 putbuf(c); //把字符放入缓冲区 return(c); }

/*替换标准库函数_getkey程序*/

/*getchar和gets 函数使用_getkey来读字符*/ char_getkey(void){ char c;

while(iend==istart){

; //等待直到有字符 }

ES=1; //再次允许串行口中断 return(c); }

/* C主函数启动中断驱动的串行I/O */ void main(void){

EA=1; //* 允许全部中断*/ com_initialize(); //* 初始化中断驱动串行I/O */ while(1){ char c;

printf(\; } }

/*****************************************************************************/

若提供发送(putbuf和putchar)、接收字符(_getkey)和初始化串行口(com_initialize)子程序,则源代码可以用于置换库程序putchar和_getkey。printf,scanf和其他库函数也可以与此例的中断驱动I/O程序一起工作。

联系合同范文客服:xxxxx#qq.com(#替换为@)