Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1964573
  • 博文数量: 356
  • 博客积分: 8284
  • 博客等级: 中将
  • 技术积分: 4580
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-15 20:25
个人简介

天行健,君子以自强不息

文章分类

全部博文(356)

文章存档

2018年(1)

2016年(4)

2015年(13)

2014年(14)

2013年(2)

2012年(25)

2011年(43)

2010年(65)

2009年(189)

分类: BSD

2009-07-27 16:55:29

 单片机的串口通信看起来是很复杂的,主要是因为他用到了更多的寄存器,与前面的知识相比他更具综合能力,写起来考虑的问题自然也变多了.而前面学习过的定时器与中断将是单片机通信的基础.
     单片机的中断系统中第4个中断就是串口中断,要进行串口通信首先就要打开CPU总中断EA,还要打开串口通信中断ES,这是串口通信的前堤,而串口通信也跟计时器一样有很多的模式,因此我们还要设置SCON寄存器来指定采用哪一种方式进行通信,而在通信的过程中,我们还要设定通信的波特率,不然的话,单片机是没办法进行采样的,这样也不会得到正确的结果了.我在实验过程中用到的是1号定时器来设定的波特率,用到了计时器方式2,也就是8位自动重装,这样可以简化编程,她的实现思想就是将常数放入TH,而TL中则是初始化参数,当溢出时,单片机会自动将TH中的常数装入TL中.



    再来说说波特率,我们为什么要设定波特率,因为单片机会以16倍波特率的速度进行采样,而在实验中我们用的是10位异步收发方式,因此要将SM0置0,SM1置1.而其中的10位有8位数据位,第一位和最后一位是发送数据的起始与结束.采用高的皮特率就不会出错啦.而波特率是有一个公式的:
方式0的波特率 =  fosc/12
方式2的波特率 =(2SMOD/64)· fosc
方式1的波特率 =(2SMOD/32)·(T1溢出率)
方式3的波特率 =(2SMOD/32)·(T1溢出率)
T1 溢出率 = fosc /{12×[256 -(TH1)]}
根据公式我们很容易就算出当晶振为110592HZ时,要达到9600的波特率,我们只需要将TL1置FDH即可,如下图:

  除此之外,你还要将SCON中的REN位置1,不然的话,单片机是不会接收数据的.
  还有不要忘了选择定时器的工作方式,设置TMOD为0x20既是工作方式2,8位自动重装定时器.
  这样一来,初始批工作算是差不多了.而串口通信分为中断方式,和查询方式,如果你想用查询方式你也不用设置IE寄存器了.
   在串口通信中,还有一个很重要的寄存器SBUF,其实也不是一个,是两个,只是它们共用同一个地址,再热气表达式的不同,单片机会自动选择使用哪一个SBUF.
   下面是我写的一个例子程序,产生的效果是:向单片机发送任一个0~255之间的数,将会被显示到数码管上.并且单片机还会自动把刚才传过去的数又发送回来 ,实验过程中用到了几个工具如下:
    串口调试助手V2.1.exe,51串口波特率计算器.exe(我已打包在附件中)还有一些必用的就不说了.
C代码 复制代码
  1. #include   
  2. #define uchar unsigned char   
  3. #define uint unsigned int   
  4.   
  5. sbit sda = P1^0;   
  6. sbit clk = P1^1;   
  7. sbit dig1 = P1^2;   
  8. sbit dig2 = P1^3;   
  9. sbit dig3 = P1^4;   
  10. sbit dig4 = P1^5;   
  11. uchar r,flag;   
  12. uchar code table[]={0x7e,0x0c,0xb6,0x9e,   
  13.                     0xcc,0xda,0xfa,0x0e,   
  14.                     0xfe,0xde,0xef,0xf9,   
  15.                     0x72,0xb8,0xf2,0xe2};   
  16. void init();   
  17. void write(uchar);   
  18. void display(uchar);   
  19. void delay(uchar);   
  20.   
  21. void main()   
  22. {   
  23.     init();   
  24.     while(1)   
  25.     {   
  26.         //查询方式通信   
  27.         //if(RI==1)  //RI为1表示收到一字节数据   
  28.         //{   
  29.         //  RI = 0;//此步必不可少,因为硬件不能将其置0   
  30.         //  r = SBUF;   
  31.         //}   
  32.         display(r);   //中断方式通信   
  33.         delay(10);   
  34.         if(flag==1)   
  35.         {   
  36.                 flag = 0;   
  37.                 ES = 0;   
  38.                 SBUF = r;   //放送数据   
  39.                 while(!TI);   
  40.                 TI = 0;   
  41.                 ES = 1;   
  42.         }   
  43.   
  44.     }   
  45. }   
  46. /** 串口中断 **/  
  47. void ser() interrupt 4   
  48. {   
  49.     RI = 0;   
  50.     r = SBUF;   
  51.     flag = 1;      
  52. }   
  53. /** 延迟函数 **/  
  54. void delay(uchar t)   
  55. {   
  56.     uchar x,y;   
  57.     for(x=t;x>0;x--)   
  58.         for(y=101;y>0;y--);   
  59. }   
  60. /** 初始化 **/  
  61. void init()   
  62. {   
  63.     dig1 = 1;   
  64.     dig2 = 1;   
  65.     dig3 = 1;   
  66.     dig4 = 1;   
  67.   
  68.     r = 0xff;   
  69.   
  70.     TMOD = 0x20;   
  71.     TH1 = 0xfd;   
  72.     TL1 = 0xfd;   
  73.     TR1 = 1;    //启动定时器1,从而设定了串口通信的波特率   
  74.     SM0 = 0;   
  75.     SM1 = 1;  //设定串口通信方式为十位异步收发器   
  76.     REN = 1;  //打开串口通信   
  77.     EA = 1;   
  78.     ES = 1;   
  79. }   
  80. /** 向数据码管写入一个字节数据 **/  
  81. void write(uchar u)   
  82. {   
  83.     uchar i;   
  84.     for(i=0;i<8;i++)   
  85.     {   
  86.         clk = 1;   
  87.         sda = u&0x80;   
  88.         clk = 0;   
  89.         u = u<<1;    
  90.     }   
  91. }   
  92. /** 显示一个3位的整数 **/  
  93. void display(uchar num)   
  94. {   
  95.     uchar bai,shi,ge;   
  96.     bai = num/100;   
  97.     shi = num%100/10;   
  98.     ge = num%10;   
  99.     /* 显示个位 */  
  100.     dig4 = 0;   
  101.     write(table[ge]);   
  102.     delay(10);   
  103.     dig4 = 1;   
  104.     /* 显示百位 */  
  105.     if(bai!=0)   
  106.     {   
  107.         dig2 = 0;   
  108.         write(table[bai]);   
  109.         delay(10);   
  110.         dig2 = 1;   
  111.   
  112.         /* 显示十位 */  
  113.         dig3 = 0;   
  114.         write(table[shi]);   
  115.         delay(10);   
  116.         dig3 = 1;   
  117.     }   
  118.     else  
  119.     {   
  120.         if(shi==0)   
  121.         {   
  122.             dig3 = 1;   
  123.             //delay(10);   
  124.         }   
  125.         else  
  126.         {   
  127.             /* 显示十位 */  
  128.             dig3 = 0;   
  129.             write(table[shi]);   
  130.             delay(10);   
  131.             dig3 = 1;   
  132.         }   
  133.     }   
  134. }  
阅读(1465) | 评论(0) | 转发(0) |
0

上一篇:s3c2440寄存器

下一篇:ubuntu下安全删除u盘

给主人留下些什么吧!~~